diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2012-11-26 22:38:38 +0100 | 
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2012-11-26 22:38:38 +0100 | 
| commit | 4c929c8a8837f4e5acdec5883a1b64a240751e2f (patch) | |
| tree | 19ca9af00b75642547ebb9863873acb1d77f5513 | |
| parent | d98eb5cfb0ac050ed8c8fafd029b94d451189864 (diff) | |
| parent | f7a9b36517d38cfa2213a346b154d2d7046ff223 (diff) | |
| download | olio-linux-3.10-4c929c8a8837f4e5acdec5883a1b64a240751e2f.tar.xz olio-linux-3.10-4c929c8a8837f4e5acdec5883a1b64a240751e2f.zip  | |
Merge tag 'integrator-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/cleanup
From Linus Walleij <linus.walleij@linaro.org>:
This series will do the following:
- Switch the Integrator/AP and /CP to use the SoC bus
  when booting from device tree.
- Group all devices on the SoC below this bus so as to
  set a good example of how to do this. The bus was
  invented by Lee Jones, let's show how it's to be used
  on a DT:ed SoC.
- Fetch the special system controller offsets from two
  special device tree nodes for each case and replace
  the static mappings with these at boot.
- Move some static remaps to the ATAG-only code path
  and delete some static maps that aren't used.
- Push dependencies on system controller remaps down
  to the Integrator/AP board file and the PCIv3 driver
  respectively and use only dynamic remappings.
- Fix up conditional BUG() usage in the PCIv3 driver
  to be simpler and more to the point.
* tag 'integrator-for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator:
  ARM: integrator: use BUG_ON where possible
  ARM: integrator: push down SC dependencies
  ARM: integrator: delete static UART1 mapping
  ARM: integrator: delete SC mapping on the CP
  ARM: integrator: remove static CP syscon mapping
  ARM: integrator: remove static AP syscon mapping
  ARM: integrator: hook the CP into the SoC bus
  ARM: integrator: hook the AP into the SoC bus
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
| -rw-r--r-- | Documentation/devicetree/bindings/arm/arm-boards | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/integratorap.dts | 5 | ||||
| -rw-r--r-- | arch/arm/boot/dts/integratorcp.dts | 5 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/common.h | 8 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/core.c | 141 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/include/mach/platform.h | 1 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 158 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 115 | ||||
| -rw-r--r-- | arch/arm/mach-integrator/pci_v3.c | 32 | 
10 files changed, 354 insertions, 117 deletions
diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index fc81a7d6b0f..db5858e32d3 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -9,6 +9,10 @@ Required properties (in root node):  FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. +In the root node the Integrator/CP must have a /cpcon node pointing +to the CP control registers, and the Integrator/AP must have a +/syscon node pointing to the Integrator/AP system controller. +  ARM Versatile Application and Platform Baseboards  ------------------------------------------------- diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index 61767757b50..c9c3fa34464 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -18,6 +18,11 @@  		bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk";  	}; +	syscon { +		/* AP system controller registers */ +		reg = <0x11000000 0x100>; +	}; +  	timer0: timer@13000000 {  		compatible = "arm,integrator-timer";  	}; diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index 2dd5e4e4848..8b119399025 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts @@ -18,6 +18,11 @@  		bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";  	}; +	cpcon { +		/* CP controller registers */ +		reg = <0xcb000000 0x100>; +	}; +  	timer0: timer@13000000 {  		compatible = "arm,sp804", "arm,primecell";  	}; diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index 350e26636a0..abeff25532a 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -8,6 +8,7 @@ config ARCH_INTEGRATOR_AP  	select MIGHT_HAVE_PCI  	select SERIAL_AMBA_PL010  	select SERIAL_AMBA_PL010_CONSOLE +	select SOC_BUS  	help  	  Include support for the ARM(R) Integrator/AP and  	  Integrator/PP2 platforms. @@ -19,6 +20,7 @@ config ARCH_INTEGRATOR_CP  	select PLAT_VERSATILE_CLCD  	select SERIAL_AMBA_PL011  	select SERIAL_AMBA_PL011_CONSOLE +	select SOC_BUS  	help  	  Include support for the ARM(R) Integrator CP platform. diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index c3ff21b5ea2..79197d8b34a 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,6 +1,12 @@  #include <linux/amba/serial.h> -extern struct amba_pl010_data integrator_uart_data; +#ifdef CONFIG_ARCH_INTEGRATOR_AP +extern struct amba_pl010_data ap_uart_data; +#else +/* Not used without Integrator/AP support anyway */ +struct amba_pl010_data ap_uart_data {}; +#endif  void integrator_init_early(void);  int integrator_init(bool is_cp);  void integrator_reserve(void);  void integrator_restart(char, const char *); +void 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 ea22a17246d..39c060f75e4 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -18,10 +18,10 @@  #include <linux/memblock.h>  #include <linux/sched.h>  #include <linux/smp.h> -#include <linux/termios.h>  #include <linux/amba/bus.h>  #include <linux/amba/serial.h>  #include <linux/io.h> +#include <linux/stat.h>  #include <mach/hardware.h>  #include <mach/platform.h> @@ -46,10 +46,10 @@ static AMBA_APB_DEVICE(rtc, "rtc", 0,  	INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);  static AMBA_APB_DEVICE(uart0, "uart0", 0, -	INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data); +	INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);  static AMBA_APB_DEVICE(uart1, "uart1", 0, -	INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data); +	INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);  static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);  static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL); @@ -77,6 +77,8 @@ int __init integrator_init(bool is_cp)  		uart1_device.periphid	= 0x00041010;  		kmi0_device.periphid	= 0x00041050;  		kmi1_device.periphid	= 0x00041050; +		uart0_device.dev.platform_data = &ap_uart_data; +		uart1_device.dev.platform_data = &ap_uart_data;  	}  	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { @@ -89,49 +91,6 @@ int __init integrator_init(bool is_cp)  #endif -/* - * On the Integrator platform, the port RTS and DTR are provided by - * bits in the following SC_CTRLS register bits: - *        RTS  DTR - *  UART0  7    6 - *  UART1  5    4 - */ -#define SC_CTRLC	__io_address(INTEGRATOR_SC_CTRLC) -#define SC_CTRLS	__io_address(INTEGRATOR_SC_CTRLS) - -static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl) -{ -	unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; -	u32 phybase = dev->res.start; - -	if (phybase == INTEGRATOR_UART0_BASE) { -		/* UART0 */ -		rts_mask = 1 << 4; -		dtr_mask = 1 << 5; -	} else { -		/* UART1 */ -		rts_mask = 1 << 6; -		dtr_mask = 1 << 7; -	} - -	if (mctrl & TIOCM_RTS) -		ctrlc |= rts_mask; -	else -		ctrls |= rts_mask; - -	if (mctrl & TIOCM_DTR) -		ctrlc |= dtr_mask; -	else -		ctrls |= dtr_mask; - -	__raw_writel(ctrls, SC_CTRLS); -	__raw_writel(ctrlc, SC_CTRLC); -} - -struct amba_pl010_data integrator_uart_data = { -	.set_mctrl = integrator_uart_set_mctrl, -}; -  static DEFINE_RAW_SPINLOCK(cm_lock);  /** @@ -169,3 +128,93 @@ void integrator_restart(char mode, const char *cmd)  {  	cm_control(CM_CTRL_RESET, CM_CTRL_RESET);  } + +static u32 integrator_id; + +static ssize_t intcp_get_manf(struct device *dev, +			      struct device_attribute *attr, +			      char *buf) +{ +	return sprintf(buf, "%02x\n", integrator_id >> 24); +} + +static struct device_attribute intcp_manf_attr = +	__ATTR(manufacturer,  S_IRUGO, intcp_get_manf,  NULL); + +static ssize_t intcp_get_arch(struct device *dev, +			      struct device_attribute *attr, +			      char *buf) +{ +	const char *arch; + +	switch ((integrator_id >> 16) & 0xff) { +	case 0x00: +		arch = "ASB little-endian"; +		break; +	case 0x01: +		arch = "AHB little-endian"; +		break; +	case 0x03: +		arch = "AHB-Lite system bus, bi-endian"; +		break; +	case 0x04: +		arch = "AHB"; +		break; +	default: +		arch = "Unknown"; +		break; +	} + +	return sprintf(buf, "%s\n", arch); +} + +static struct device_attribute intcp_arch_attr = +	__ATTR(architecture,  S_IRUGO, intcp_get_arch,  NULL); + +static ssize_t intcp_get_fpga(struct device *dev, +			      struct device_attribute *attr, +			      char *buf) +{ +	const char *fpga; + +	switch ((integrator_id >> 12) & 0xf) { +	case 0x01: +		fpga = "XC4062"; +		break; +	case 0x02: +		fpga = "XC4085"; +		break; +	case 0x04: +		fpga = "EPM7256AE (Altera PLD)"; +		break; +	default: +		fpga = "Unknown"; +		break; +	} + +	return sprintf(buf, "%s\n", fpga); +} + +static struct device_attribute intcp_fpga_attr = +	__ATTR(fpga,  S_IRUGO, intcp_get_fpga,  NULL); + +static ssize_t intcp_get_build(struct device *dev, +			       struct device_attribute *attr, +			       char *buf) +{ +	return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF); +} + +static struct device_attribute intcp_build_attr = +	__ATTR(build,  S_IRUGO, intcp_get_build,  NULL); + + + +void integrator_init_sysfs(struct device *parent, u32 id) +{ +	integrator_id = id; +	device_create_file(parent, &intcp_manf_attr); +	device_create_file(parent, &intcp_arch_attr); +	device_create_file(parent, &intcp_fpga_attr); +	device_create_file(parent, &intcp_build_attr); +} diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h index efeac5d0bc9..be5859efe10 100644 --- a/arch/arm/mach-integrator/include/mach/platform.h +++ b/arch/arm/mach-integrator/include/mach/platform.h @@ -190,7 +190,6 @@  #define INTEGRATOR_SC_CTRLC_OFFSET      0x0C  #define INTEGRATOR_SC_DEC_OFFSET        0x10  #define INTEGRATOR_SC_ARB_OFFSET        0x14 -#define INTEGRATOR_SC_PCIENABLE_OFFSET  0x18  #define INTEGRATOR_SC_LOCK_OFFSET       0x1C  #define INTEGRATOR_SC_BASE              0x11000000 diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index e6617c134fa..a0a7cbbb7a7 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -37,6 +37,9 @@  #include <linux/of_irq.h>  #include <linux/of_address.h>  #include <linux/of_platform.h> +#include <linux/stat.h> +#include <linux/sys_soc.h> +#include <linux/termios.h>  #include <video/vga.h>  #include <mach/hardware.h> @@ -60,7 +63,10 @@  #include "common.h" -/*  +/* Base address to the AP system controller */ +void __iomem *ap_syscon_base; + +/*   * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx   * is the (PA >> 12).   * @@ -68,7 +74,6 @@   * just for now).   */  #define VA_IC_BASE	__io_address(INTEGRATOR_IC_BASE) -#define VA_SC_BASE	__io_address(INTEGRATOR_SC_BASE)  #define VA_EBI_BASE	__io_address(INTEGRATOR_EBI_BASE)  #define VA_CMIC_BASE	__io_address(INTEGRATOR_HDR_IC) @@ -97,11 +102,6 @@ static struct map_desc ap_io_desc[] __initdata = {  		.length		= SZ_4K,  		.type		= MT_DEVICE  	}, { -		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE), -		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE -	}, {  		.virtual	= IO_ADDRESS(INTEGRATOR_EBI_BASE),  		.pfn		= __phys_to_pfn(INTEGRATOR_EBI_BASE),  		.length		= SZ_4K, @@ -122,11 +122,6 @@ static struct map_desc ap_io_desc[] __initdata = {  		.length		= SZ_4K,  		.type		= MT_DEVICE  	}, { -		.virtual	= IO_ADDRESS(INTEGRATOR_UART1_BASE), -		.pfn		= __phys_to_pfn(INTEGRATOR_UART1_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE -	}, {  		.virtual	= IO_ADDRESS(INTEGRATOR_DBG_BASE),  		.pfn		= __phys_to_pfn(INTEGRATOR_DBG_BASE),  		.length		= SZ_4K, @@ -201,8 +196,6 @@ device_initcall(irq_syscore_init);  /*   * Flash handling.   */ -#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET) -#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)  #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)  #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) @@ -210,7 +203,8 @@ static int ap_flash_init(struct platform_device *dev)  {  	u32 tmp; -	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); +	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, +	       ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);  	tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;  	writel(tmp, EBI_CSR1); @@ -227,7 +221,8 @@ static void ap_flash_exit(struct platform_device *dev)  {  	u32 tmp; -	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); +	writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, +	       ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);  	tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;  	writel(tmp, EBI_CSR1); @@ -241,9 +236,12 @@ static void ap_flash_exit(struct platform_device *dev)  static void ap_flash_set_vpp(struct platform_device *pdev, int on)  { -	void __iomem *reg = on ? SC_CTRLS : SC_CTRLC; - -	writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); +	if (on) +		writel(INTEGRATOR_SC_CTRL_nFLVPPEN, +		       ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET); +	else +		writel(INTEGRATOR_SC_CTRL_nFLVPPEN, +		       ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);  }  static struct physmap_flash_data ap_flash_data = { @@ -254,6 +252,45 @@ static struct physmap_flash_data ap_flash_data = {  };  /* + * For the PL010 found in the Integrator/AP some of the UART control is + * implemented in the system controller and accessed using a callback + * from the driver. + */ +static void integrator_uart_set_mctrl(struct amba_device *dev, +				void __iomem *base, unsigned int mctrl) +{ +	unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; +	u32 phybase = dev->res.start; + +	if (phybase == INTEGRATOR_UART0_BASE) { +		/* UART0 */ +		rts_mask = 1 << 4; +		dtr_mask = 1 << 5; +	} else { +		/* UART1 */ +		rts_mask = 1 << 6; +		dtr_mask = 1 << 7; +	} + +	if (mctrl & TIOCM_RTS) +		ctrlc |= rts_mask; +	else +		ctrls |= rts_mask; + +	if (mctrl & TIOCM_DTR) +		ctrlc |= dtr_mask; +	else +		ctrls |= dtr_mask; + +	__raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET); +	__raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET); +} + +struct amba_pl010_data ap_uart_data = { +	.set_mctrl = integrator_uart_set_mctrl, +}; + +/*   * Where is the timer (VA)?   */  #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) @@ -450,9 +487,9 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,  		"rtc", NULL),  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, -		"uart0", &integrator_uart_data), +		"uart0", &ap_uart_data),  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, -		"uart1", &integrator_uart_data), +		"uart1", &ap_uart_data),  	OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,  		"kmi0", NULL),  	OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, @@ -465,12 +502,60 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {  static void __init ap_init_of(void)  {  	unsigned long sc_dec; +	struct device_node *root; +	struct device_node *syscon; +	struct device *parent; +	struct soc_device *soc_dev; +	struct soc_device_attribute *soc_dev_attr; +	u32 ap_sc_id; +	int err;  	int i; -	of_platform_populate(NULL, of_default_bus_match_table, -			ap_auxdata_lookup, NULL); +	/* Here we create an SoC device for the root node */ +	root = of_find_node_by_path("/"); +	if (!root) +		return; +	syscon = of_find_node_by_path("/syscon"); +	if (!syscon) +		return; + +	ap_syscon_base = of_iomap(syscon, 0); +	if (!ap_syscon_base) +		return; -	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); +	ap_sc_id = readl(ap_syscon_base); + +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); +	if (!soc_dev_attr) +		return; + +	err = of_property_read_string(root, "compatible", +				      &soc_dev_attr->soc_id); +	if (err) +		return; +	err = of_property_read_string(root, "model", &soc_dev_attr->machine); +	if (err) +		return; +	soc_dev_attr->family = "Integrator"; +	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", +					   'A' + (ap_sc_id & 0x0f)); + +	soc_dev = soc_device_register(soc_dev_attr); +	if (IS_ERR_OR_NULL(soc_dev)) { +		kfree(soc_dev_attr->revision); +		kfree(soc_dev_attr); +		return; +	} + +	parent = soc_device_to_device(soc_dev); + +	if (!IS_ERR_OR_NULL(parent)) +		integrator_init_sysfs(parent, ap_sc_id); + +	of_platform_populate(root, of_default_bus_match_table, +			ap_auxdata_lookup, parent); + +	sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);  	for (i = 0; i < 4; i++) {  		struct lm_device *lmdev; @@ -514,6 +599,27 @@ MACHINE_END  #ifdef CONFIG_ATAGS  /* + * For the ATAG boot some static mappings are needed. This will + * go away with the ATAG support down the road. + */ + +static struct map_desc ap_io_desc_atag[] __initdata = { +	{ +		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE), +		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE), +		.length		= SZ_4K, +		.type		= MT_DEVICE +	}, +}; + +static void __init ap_map_io_atag(void) +{ +	iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag)); +	ap_syscon_base = __io_address(INTEGRATOR_SC_BASE); +	ap_map_io(); +} + +/*   * This is where non-devicetree initialization code is collected and stashed   * for eventual deletion.   */ @@ -581,7 +687,7 @@ static void __init ap_init(void)  	platform_device_register(&cfi_flash_device); -	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); +	sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);  	for (i = 0; i < 4; i++) {  		struct lm_device *lmdev; @@ -608,7 +714,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100,  	.reserve	= integrator_reserve, -	.map_io		= ap_map_io, +	.map_io		= ap_map_io_atag,  	.nr_irqs	= NR_IRQS_INTEGRATOR_AP,  	.init_early	= ap_init_early,  	.init_irq	= ap_init_irq, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 5b08e8e4cc8..29df06b35d0 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -26,6 +26,7 @@  #include <linux/of_irq.h>  #include <linux/of_address.h>  #include <linux/of_platform.h> +#include <linux/sys_soc.h>  #include <mach/hardware.h>  #include <mach/platform.h> @@ -51,11 +52,13 @@  #include "common.h" +/* Base address to the CP controller */ +static void __iomem *intcp_con_base; +  #define INTCP_PA_FLASH_BASE		0x24000000  #define INTCP_PA_CLCD_BASE		0xc0000000 -#define INTCP_VA_CTRL_BASE		__io_address(INTEGRATOR_CP_CTL_BASE)  #define INTCP_FLASHPROG			0x04  #define CINTEGRATOR_FLASHPROG_FLVPPEN	(1 << 0)  #define CINTEGRATOR_FLASHPROG_FLWREN	(1 << 1) @@ -82,11 +85,6 @@ static struct map_desc intcp_io_desc[] __initdata = {  		.length		= SZ_4K,  		.type		= MT_DEVICE  	}, { -		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE), -		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE -	}, {  		.virtual	= IO_ADDRESS(INTEGRATOR_EBI_BASE),  		.pfn		= __phys_to_pfn(INTEGRATOR_EBI_BASE),  		.length		= SZ_4K, @@ -107,11 +105,6 @@ static struct map_desc intcp_io_desc[] __initdata = {  		.length		= SZ_4K,  		.type		= MT_DEVICE  	}, { -		.virtual	= IO_ADDRESS(INTEGRATOR_UART1_BASE), -		.pfn		= __phys_to_pfn(INTEGRATOR_UART1_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE -	}, {  		.virtual	= IO_ADDRESS(INTEGRATOR_DBG_BASE),  		.pfn		= __phys_to_pfn(INTEGRATOR_DBG_BASE),  		.length		= SZ_4K, @@ -126,11 +119,6 @@ static struct map_desc intcp_io_desc[] __initdata = {  		.pfn		= __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),  		.length		= SZ_4K,  		.type		= MT_DEVICE -	}, { -		.virtual	= IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), -		.pfn		= __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), -		.length		= SZ_4K, -		.type		= MT_DEVICE  	}  }; @@ -146,9 +134,9 @@ static int intcp_flash_init(struct platform_device *dev)  {  	u32 val; -	val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	val = readl(intcp_con_base + INTCP_FLASHPROG);  	val |= CINTEGRATOR_FLASHPROG_FLWREN; -	writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	writel(val, intcp_con_base + INTCP_FLASHPROG);  	return 0;  } @@ -157,21 +145,21 @@ static void intcp_flash_exit(struct platform_device *dev)  {  	u32 val; -	val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	val = readl(intcp_con_base + INTCP_FLASHPROG);  	val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN); -	writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	writel(val, intcp_con_base + INTCP_FLASHPROG);  }  static void intcp_flash_set_vpp(struct platform_device *pdev, int on)  {  	u32 val; -	val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	val = readl(intcp_con_base + INTCP_FLASHPROG);  	if (on)  		val |= CINTEGRATOR_FLASHPROG_FLVPPEN;  	else  		val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN; -	writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG); +	writel(val, intcp_con_base + INTCP_FLASHPROG);  }  static struct physmap_flash_data intcp_flash_data = { @@ -190,7 +178,7 @@ static struct physmap_flash_data intcp_flash_data = {  static unsigned int mmc_status(struct device *dev)  {  	unsigned int status = readl(__io_address(0xca000000 + 4)); -	writel(8, __io_address(INTEGRATOR_CP_CTL_BASE + 8)); +	writel(8, intcp_con_base + 8);  	return status & 8;  } @@ -318,9 +306,9 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,  		"rtc", NULL),  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, -		"uart0", &integrator_uart_data), +		"uart0", NULL),  	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, -		"uart1", &integrator_uart_data), +		"uart1", NULL),  	OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,  		"kmi0", NULL),  	OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, @@ -338,8 +326,57 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {  static void __init intcp_init_of(void)  { -	of_platform_populate(NULL, of_default_bus_match_table, -			intcp_auxdata_lookup, NULL); +	struct device_node *root; +	struct device_node *cpcon; +	struct device *parent; +	struct soc_device *soc_dev; +	struct soc_device_attribute *soc_dev_attr; +	u32 intcp_sc_id; +	int err; + +	/* Here we create an SoC device for the root node */ +	root = of_find_node_by_path("/"); +	if (!root) +		return; +	cpcon = of_find_node_by_path("/cpcon"); +	if (!cpcon) +		return; + +	intcp_con_base = of_iomap(cpcon, 0); +	if (!intcp_con_base) +		return; + +	intcp_sc_id = readl(intcp_con_base); + +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); +	if (!soc_dev_attr) +		return; + +	err = of_property_read_string(root, "compatible", +				      &soc_dev_attr->soc_id); +	if (err) +		return; +	err = of_property_read_string(root, "model", &soc_dev_attr->machine); +	if (err) +		return; +	soc_dev_attr->family = "Integrator"; +	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", +					   'A' + (intcp_sc_id & 0x0f)); + +	soc_dev = soc_device_register(soc_dev_attr); +	if (IS_ERR_OR_NULL(soc_dev)) { +		kfree(soc_dev_attr->revision); +		kfree(soc_dev_attr); +		return; +	} + +	parent = soc_device_to_device(soc_dev); + +	if (!IS_ERR_OR_NULL(parent)) +		integrator_init_sysfs(parent, intcp_sc_id); + +	of_platform_populate(root, of_default_bus_match_table, +			intcp_auxdata_lookup, parent);  }  static const char * intcp_dt_board_compat[] = { @@ -365,6 +402,28 @@ MACHINE_END  #ifdef CONFIG_ATAGS  /* + * For the ATAG boot some static mappings are needed. This will + * go away with the ATAG support down the road. + */ + +static struct map_desc intcp_io_desc_atag[] __initdata = { +	{ +		.virtual	= IO_ADDRESS(INTEGRATOR_CP_CTL_BASE), +		.pfn		= __phys_to_pfn(INTEGRATOR_CP_CTL_BASE), +		.length		= SZ_4K, +		.type		= MT_DEVICE +	}, +}; + +static void __init intcp_map_io_atag(void) +{ +	iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag)); +	intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE); +	intcp_map_io(); +} + + +/*   * This is where non-devicetree initialization code is collected and stashed   * for eventual deletion.   */ @@ -503,7 +562,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100,  	.reserve	= integrator_reserve, -	.map_io		= intcp_map_io, +	.map_io		= intcp_map_io_atag,  	.nr_irqs	= NR_IRQS_INTEGRATOR_CP,  	.init_early	= intcp_init_early,  	.init_irq	= intcp_init_irq, diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index bbeca59df66..be50e795536 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -191,12 +191,9 @@ static void __iomem *v3_open_config_window(struct pci_bus *bus,  	/*  	 * Trap out illegal values  	 */ -	if (offset > 255) -		BUG(); -	if (busnr > 255) -		BUG(); -	if (devfn > 255) -		BUG(); +	BUG_ON(offset > 255); +	BUG_ON(busnr > 255); +	BUG_ON(devfn > 255);  	if (busnr == 0) {  		int slot = PCI_SLOT(devfn); @@ -388,9 +385,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)   * means I can't get additional information on the reason for the pm2fb   * problems.  I suppose I'll just have to mind-meld with the machine. ;)   */ -#define SC_PCI     __io_address(INTEGRATOR_SC_PCIENABLE) -#define SC_LBFADDR __io_address(INTEGRATOR_SC_BASE + 0x20) -#define SC_LBFCODE __io_address(INTEGRATOR_SC_BASE + 0x24) +static void __iomem *ap_syscon_base; +#define INTEGRATOR_SC_PCIENABLE_OFFSET	0x18 +#define INTEGRATOR_SC_LBFADDR_OFFSET	0x20 +#define INTEGRATOR_SC_LBFCODE_OFFSET	0x24  static int  v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) @@ -401,13 +399,13 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)  	char buf[128];  	sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", -		addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255, +		addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,  		v3_readb(V3_LB_ISTAT));  	printk(KERN_DEBUG "%s", buf);  #endif  	v3_writeb(V3_LB_ISTAT, 0); -	__raw_writel(3, SC_PCI); +	__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);  	/*  	 * If the instruction being executed was a read, @@ -449,15 +447,15 @@ static irqreturn_t v3_irq(int dummy, void *devid)  	sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "  		"ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, -		__raw_readl(SC_LBFADDR), -		__raw_readl(SC_LBFCODE) & 255, +		__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), +		__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,  		v3_readb(V3_LB_ISTAT));  	printascii(buf);  #endif  	v3_writew(V3_PCI_STAT, 0xf000);  	v3_writeb(V3_LB_ISTAT, 0); -	__raw_writel(3, SC_PCI); +	__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);  #ifdef CONFIG_DEBUG_LL  	/* @@ -480,6 +478,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)  	if (nr == 0) {  		sys->mem_offset = PHYS_PCI_MEM_BASE;  		ret = pci_v3_setup_resources(sys); +		/* Remap the Integrator system controller */ +		ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); +		if (!ap_syscon_base) +			return -EINVAL;  	}  	return ret; @@ -568,7 +570,7 @@ void __init pci_v3_preinit(void)  	v3_writeb(V3_LB_ISTAT, 0);  	v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));  	v3_writeb(V3_LB_IMASK, 0x28); -	__raw_writel(3, SC_PCI); +	__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);  	/*  	 * Grab the PCI error interrupt.  |