2 * CLPS711X common devices definitions
4 * Author: Alexander Shiyan <shc_work@mail.ru>, 2013-2014
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
13 #include <linux/of_fdt.h>
14 #include <linux/platform_device.h>
15 #include <linux/random.h>
16 #include <linux/sizes.h>
17 #include <linux/slab.h>
18 #include <linux/sys_soc.h>
20 #include <asm/system_info.h>
22 #include <mach/hardware.h>
24 static const struct resource clps711x_cpuidle_res __initconst
=
25 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ HALT
, SZ_128
);
27 static void __init
clps711x_add_cpuidle(void)
29 platform_device_register_simple("clps711x-cpuidle", PLATFORM_DEVID_NONE
,
30 &clps711x_cpuidle_res
, 1);
33 static const phys_addr_t clps711x_gpios
[][2] __initconst
= {
41 static void __init
clps711x_add_gpio(void)
44 struct resource gpio_res
[2];
46 memset(gpio_res
, 0, sizeof(gpio_res
));
48 gpio_res
[0].flags
= IORESOURCE_MEM
;
49 gpio_res
[1].flags
= IORESOURCE_MEM
;
51 for (i
= 0; i
< ARRAY_SIZE(clps711x_gpios
); i
++) {
52 gpio_res
[0].start
= CLPS711X_PHYS_BASE
+ clps711x_gpios
[i
][0];
53 gpio_res
[0].end
= gpio_res
[0].start
;
54 gpio_res
[1].start
= CLPS711X_PHYS_BASE
+ clps711x_gpios
[i
][1];
55 gpio_res
[1].end
= gpio_res
[1].start
;
57 platform_device_register_simple("clps711x-gpio", i
,
58 gpio_res
, ARRAY_SIZE(gpio_res
));
62 const struct resource clps711x_syscon_res
[] __initconst
= {
63 /* SYSCON1, SYSFLG1 */
64 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ SYSCON1
, SZ_128
),
65 /* SYSCON2, SYSFLG2 */
66 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ SYSCON2
, SZ_128
),
68 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ SYSCON3
, SZ_64
),
71 static void __init
clps711x_add_syscon(void)
75 for (i
= 0; i
< ARRAY_SIZE(clps711x_syscon_res
); i
++)
76 platform_device_register_simple("syscon", i
+ 1,
77 &clps711x_syscon_res
[i
], 1);
80 static const struct resource clps711x_uart1_res
[] __initconst
= {
81 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ UARTDR1
, SZ_128
),
82 DEFINE_RES_IRQ(IRQ_UTXINT1
),
83 DEFINE_RES_IRQ(IRQ_URXINT1
),
86 static const struct resource clps711x_uart2_res
[] __initconst
= {
87 DEFINE_RES_MEM(CLPS711X_PHYS_BASE
+ UARTDR2
, SZ_128
),
88 DEFINE_RES_IRQ(IRQ_UTXINT2
),
89 DEFINE_RES_IRQ(IRQ_URXINT2
),
92 static void __init
clps711x_add_uart(void)
94 platform_device_register_simple("clps711x-uart", 0, clps711x_uart1_res
,
95 ARRAY_SIZE(clps711x_uart1_res
));
96 platform_device_register_simple("clps711x-uart", 1, clps711x_uart2_res
,
97 ARRAY_SIZE(clps711x_uart2_res
));
100 static void __init
clps711x_soc_init(void)
102 struct soc_device_attribute
*soc_dev_attr
;
103 struct soc_device
*soc_dev
;
107 base
= ioremap(CLPS711X_PHYS_BASE
, SZ_32K
);
111 id
[0] = readl(base
+ UNIQID
);
112 id
[1] = readl(base
+ RANDID0
);
113 id
[2] = readl(base
+ RANDID1
);
114 id
[3] = readl(base
+ RANDID2
);
115 id
[4] = readl(base
+ RANDID3
);
116 system_rev
= SYSFLG1_VERID(readl(base
+ SYSFLG1
));
118 add_device_randomness(id
, sizeof(id
));
120 system_serial_low
= id
[0];
122 soc_dev_attr
= kzalloc(sizeof(*soc_dev_attr
), GFP_KERNEL
);
126 soc_dev_attr
->machine
= of_flat_dt_get_machine_name();
127 soc_dev_attr
->family
= "Cirrus Logic CLPS711X";
128 soc_dev_attr
->revision
= kasprintf(GFP_KERNEL
, "%u", system_rev
);
129 soc_dev_attr
->soc_id
= kasprintf(GFP_KERNEL
, "%08x", id
[0]);
131 soc_dev
= soc_device_register(soc_dev_attr
);
132 if (IS_ERR(soc_dev
)) {
133 kfree(soc_dev_attr
->revision
);
134 kfree(soc_dev_attr
->soc_id
);
142 void __init
clps711x_devices_init(void)
144 clps711x_add_cpuidle();
146 clps711x_add_syscon();