aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-integrator
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-11-01 20:31:10 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-11-16 16:25:50 -0500
commite67ae6be734de909954e20317c38472af983b92c (patch)
tree646010180c98b8918e72d7d3ed388a1cfb37e02f /arch/arm/mach-integrator
parent6f0c0580b70c89094b3422ba81118c7b959c7556 (diff)
ARM: integrator: hook the AP into the SoC bus
This hooks the Integrator/AP into the SoC bus when booting from device tree, by mapping the AP controller registers first, then registering the SoC device, and then populating the device tree with the SoC device as parent. Introduce some helpers in the core to provide sysfs files detailing the use of the SoC ID which will later be reused by the Integrator/CP patch for the same bus grouping. Cc: Lee Jones <lee.jones@linaro.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/common.h1
-rw-r--r--arch/arm/mach-integrator/core.c91
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c57
4 files changed, 148 insertions, 2 deletions
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 350e26636a06..3961942c9e11 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -8,6 +8,7 @@ config ARCH_INTEGRATOR_AP
8 select MIGHT_HAVE_PCI 8 select MIGHT_HAVE_PCI
9 select SERIAL_AMBA_PL010 9 select SERIAL_AMBA_PL010
10 select SERIAL_AMBA_PL010_CONSOLE 10 select SERIAL_AMBA_PL010_CONSOLE
11 select SOC_BUS
11 help 12 help
12 Include support for the ARM(R) Integrator/AP and 13 Include support for the ARM(R) Integrator/AP and
13 Integrator/PP2 platforms. 14 Integrator/PP2 platforms.
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index c3ff21b5ea24..fc9f47d289f4 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -4,3 +4,4 @@ void integrator_init_early(void);
4int integrator_init(bool is_cp); 4int integrator_init(bool is_cp);
5void integrator_reserve(void); 5void integrator_reserve(void);
6void integrator_restart(char, const char *); 6void integrator_restart(char, const char *);
7void integrator_init_sysfs(struct device *parent, u32 id);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index ea22a17246d7..161fbf8596bd 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -22,6 +22,7 @@
22#include <linux/amba/bus.h> 22#include <linux/amba/bus.h>
23#include <linux/amba/serial.h> 23#include <linux/amba/serial.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/stat.h>
25 26
26#include <mach/hardware.h> 27#include <mach/hardware.h>
27#include <mach/platform.h> 28#include <mach/platform.h>
@@ -169,3 +170,93 @@ void integrator_restart(char mode, const char *cmd)
169{ 170{
170 cm_control(CM_CTRL_RESET, CM_CTRL_RESET); 171 cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
171} 172}
173
174static u32 integrator_id;
175
176static ssize_t intcp_get_manf(struct device *dev,
177 struct device_attribute *attr,
178 char *buf)
179{
180 return sprintf(buf, "%02x\n", integrator_id >> 24);
181}
182
183static struct device_attribute intcp_manf_attr =
184 __ATTR(manufacturer, S_IRUGO, intcp_get_manf, NULL);
185
186static ssize_t intcp_get_arch(struct device *dev,
187 struct device_attribute *attr,
188 char *buf)
189{
190 const char *arch;
191
192 switch ((integrator_id >> 16) & 0xff) {
193 case 0x00:
194 arch = "ASB little-endian";
195 break;
196 case 0x01:
197 arch = "AHB little-endian";
198 break;
199 case 0x03:
200 arch = "AHB-Lite system bus, bi-endian";
201 break;
202 case 0x04:
203 arch = "AHB";
204 break;
205 default:
206 arch = "Unknown";
207 break;
208 }
209
210 return sprintf(buf, "%s\n", arch);
211}
212
213static struct device_attribute intcp_arch_attr =
214 __ATTR(architecture, S_IRUGO, intcp_get_arch, NULL);
215
216static ssize_t intcp_get_fpga(struct device *dev,
217 struct device_attribute *attr,
218 char *buf)
219{
220 const char *fpga;
221
222 switch ((integrator_id >> 12) & 0xf) {
223 case 0x01:
224 fpga = "XC4062";
225 break;
226 case 0x02:
227 fpga = "XC4085";
228 break;
229 case 0x04:
230 fpga = "EPM7256AE (Altera PLD)";
231 break;
232 default:
233 fpga = "Unknown";
234 break;
235 }
236
237 return sprintf(buf, "%s\n", fpga);
238}
239
240static struct device_attribute intcp_fpga_attr =
241 __ATTR(fpga, S_IRUGO, intcp_get_fpga, NULL);
242
243static ssize_t intcp_get_build(struct device *dev,
244 struct device_attribute *attr,
245 char *buf)
246{
247 return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF);
248}
249
250static struct device_attribute intcp_build_attr =
251 __ATTR(build, S_IRUGO, intcp_get_build, NULL);
252
253
254
255void integrator_init_sysfs(struct device *parent, u32 id)
256{
257 integrator_id = id;
258 device_create_file(parent, &intcp_manf_attr);
259 device_create_file(parent, &intcp_arch_attr);
260 device_create_file(parent, &intcp_fpga_attr);
261 device_create_file(parent, &intcp_build_attr);
262}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index e6617c134faf..7d84080f9aa3 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -37,6 +37,8 @@
37#include <linux/of_irq.h> 37#include <linux/of_irq.h>
38#include <linux/of_address.h> 38#include <linux/of_address.h>
39#include <linux/of_platform.h> 39#include <linux/of_platform.h>
40#include <linux/stat.h>
41#include <linux/sys_soc.h>
40#include <video/vga.h> 42#include <video/vga.h>
41 43
42#include <mach/hardware.h> 44#include <mach/hardware.h>
@@ -462,13 +464,64 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
462 { /* sentinel */ }, 464 { /* sentinel */ },
463}; 465};
464 466
467/* Base address to the AP system controller */
468static void __iomem *ap_syscon_base;
469
465static void __init ap_init_of(void) 470static void __init ap_init_of(void)
466{ 471{
467 unsigned long sc_dec; 472 unsigned long sc_dec;
473 struct device_node *root;
474 struct device_node *syscon;
475 struct device *parent;
476 struct soc_device *soc_dev;
477 struct soc_device_attribute *soc_dev_attr;
478 u32 ap_sc_id;
479 int err;
468 int i; 480 int i;
469 481
470 of_platform_populate(NULL, of_default_bus_match_table, 482 /* Here we create an SoC device for the root node */
471 ap_auxdata_lookup, NULL); 483 root = of_find_node_by_path("/");
484 if (!root)
485 return;
486 syscon = of_find_node_by_path("/syscon");
487 if (!syscon)
488 return;
489
490 ap_syscon_base = of_iomap(syscon, 0);
491 if (!ap_syscon_base)
492 return;
493
494 ap_sc_id = readl(ap_syscon_base);
495
496 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
497 if (!soc_dev_attr)
498 return;
499
500 err = of_property_read_string(root, "compatible",
501 &soc_dev_attr->soc_id);
502 if (err)
503 return;
504 err = of_property_read_string(root, "model", &soc_dev_attr->machine);
505 if (err)
506 return;
507 soc_dev_attr->family = "Integrator";
508 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
509 'A' + (ap_sc_id & 0x0f));
510
511 soc_dev = soc_device_register(soc_dev_attr);
512 if (IS_ERR_OR_NULL(soc_dev)) {
513 kfree(soc_dev_attr->revision);
514 kfree(soc_dev_attr);
515 return;
516 }
517
518 parent = soc_device_to_device(soc_dev);
519
520 if (!IS_ERR_OR_NULL(parent))
521 integrator_init_sysfs(parent, ap_sc_id);
522
523 of_platform_populate(root, of_default_bus_match_table,
524 ap_auxdata_lookup, parent);
472 525
473 sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); 526 sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
474 for (i = 0; i < 4; i++) { 527 for (i = 0; i < 4; i++) {