From fb61f8622369aad275a4e3487b8aeec7a571fdde Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Oct 2013 14:11:18 +0200 Subject: [PATCH 01/10] ARM: integrator: get the CM control register by proxy The CM_CTRL register was accessed directly from the LED driver, which does not work now that we get the base for the register from the device tree. Add an accessor function to do this and make the LED driver compile again. Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/core.c | 8 ++++++++ arch/arm/mach-integrator/include/mach/cm.h | 3 ++- arch/arm/mach-integrator/leds.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 4cdfd7365925..c07c821fb6b3 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -93,6 +93,14 @@ int __init integrator_init(bool is_cp) static DEFINE_RAW_SPINLOCK(cm_lock); +/** + * cm_get - get the value from the CM_CTRL register + */ +u32 cm_get(void) +{ + return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET); +} + /** * cm_control - update the CM_CTRL register. * @mask: bits to change diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/include/mach/cm.h index 202e6a57f100..ae6085f1db19 100644 --- a/arch/arm/mach-integrator/include/mach/cm.h +++ b/arch/arm/mach-integrator/include/mach/cm.h @@ -1,6 +1,7 @@ /* - * update the core module control register. + * access the core module control register. */ +u32 cm_get(void); void cm_control(u32, u32); #define CM_CTRL __io_address(INTEGRATOR_HDR_CTRL) diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 7a7f6d3273bf..ed82535845f7 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c @@ -78,7 +78,7 @@ static void cm_led_set(struct led_classdev *cdev, static enum led_brightness cm_led_get(struct led_classdev *cdev) { - u32 reg = readl(CM_CTRL); + u32 reg = cm_get(); return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF; } From c791f4d3390527300644a436787f8a95c4bc48c4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Oct 2013 14:00:33 +0200 Subject: [PATCH 02/10] ARM: integrator: update defconfig This updates the integrator defconfig, apart from the usual re-shuffling of symbols due to restructuring of the kernel Kconfig this will also: - Enable IM-PD1 so all hardware is enabled out-of-the-box - Enable the LEDs class and heartbeat trigger, so that the LED driver in plat-versatile/ is compiled. - Enale some debug code like the CLK debug. Signed-off-by: Linus Walleij --- arch/arm/configs/integrator_defconfig | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index a8314c3ee84d..5bae19557591 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -1,15 +1,17 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y -CONFIG_TINY_RCU=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_INTEGRATOR=y CONFIG_ARCH_INTEGRATOR_AP=y CONFIG_ARCH_INTEGRATOR_CP=y +CONFIG_INTEGRATOR_IMPD1=y CONFIG_CPU_ARM720T=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM922T=y @@ -18,12 +20,9 @@ CONFIG_CPU_ARM1020=y CONFIG_CPU_ARM1022=y CONFIG_CPU_ARM1026=y CONFIG_PCI=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_AEABI=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y +# CONFIG_ATAGS is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp" @@ -44,24 +43,20 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_AFS_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y +CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_NET_PCI=y CONFIG_E100=y CONFIG_SMC91X=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_SERIO_SERPORT is not set -CONFIG_SERIAL_AMBA_PL010=y -CONFIG_SERIAL_AMBA_PL010_CONSOLE=y CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_ARMCLCD=y @@ -71,19 +66,23 @@ CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_VGA_CONSOLE is not set CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PL030=y +CONFIG_COMMON_CLK_DEBUG=y CONFIG_EXT2_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y From a67202583f44c90d1155f4de8c8028884a2a1451 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 15 Jun 2013 23:56:32 +0200 Subject: [PATCH 03/10] ARM: integrator: get the LM interrupts from DT The OF/DT boot path needs to get the LM (Logical Module) IRQs from the device tree for coherency. This augments the DT syscon node to contain these IRQs and alter the DT LM code to get them from there. Signed-off-by: Linus Walleij --- .../devicetree/bindings/arm/arm-boards | 21 +++++++++++++++++++ arch/arm/boot/dts/integratorap.dts | 3 +++ arch/arm/mach-integrator/integrator_ap.c | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index db5858e32d3f..5fdd7b9eeb52 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -9,9 +9,30 @@ Required properties (in root node): FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. +Required nodes: + 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. +The AP syscon node must include the logic module interrupts, stated +in order of module instance +example: + +/dts-v1/; +/include/ "integrator.dtsi" + +/ { + model = "ARM Integrator/AP"; + compatible = "arm,integrator-ap"; + + syscon { + /* AP system controller registers */ + reg = <0x11000000 0x100>; + interrupt-parent = <&pic>; + /* These are the logic module IRQs */ + interrupts = <9>, <10>, <11>, <12>; + }; +}; ARM Versatile Application and Platform Baseboards diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index b6b82eca8d1e..453ab0ea4d2b 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -21,6 +21,9 @@ chosen { syscon { /* AP system controller registers */ reg = <0x11000000 0x100>; + interrupt-parent = <&pic>; + /* These are the logical module IRQs */ + interrupts = <9>, <10>, <11>, <12>; }; timer0: timer@13000000 { diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index d9e95e612fcb..f5fbd8adef0c 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -541,7 +541,7 @@ static void __init ap_init_of(void) lmdev->resource.start = 0xc0000000 + 0x10000000 * i; lmdev->resource.end = lmdev->resource.start + 0x0fffffff; lmdev->resource.flags = IORESOURCE_MEM; - lmdev->irq = IRQ_AP_EXPINT0 + i; + lmdev->irq = irq_of_parse_and_map(syscon, i); lmdev->id = i; lm_device_register(lmdev); From 50564a794d64ace92c189d7cb5b591a60d3de9c2 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 16 Jun 2013 00:05:07 +0200 Subject: [PATCH 04/10] ARM: integrator: print the Linux IRQ in LL_DEBUG code The static HW irqs have no meaning in the interrupt handler and does not correlate to the /proc/interrupts IRQ numbers anymore, print the Linux IRQ number instead. Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/pci_v3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index bef100527c42..2d10793fa2a0 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -605,7 +605,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) return 1; } -static irqreturn_t v3_irq(int dummy, void *devid) +static irqreturn_t v3_irq(int irq, void *devid) { #ifdef CONFIG_DEBUG_LL struct pt_regs *regs = get_irq_regs(); @@ -615,7 +615,7 @@ static irqreturn_t v3_irq(int dummy, void *devid) extern void printascii(const char *); sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " - "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, + "ISTAT=%02x\n", irq, 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)); From d7057e1de8d6c180eb2ecd90b0cab9d1a8a4d8ab Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 15 Jun 2013 22:01:13 +0200 Subject: [PATCH 05/10] ARM: integrator: delete non-devicetree boot path The Device Tree boot path now supports everything the ATAG boot can provide, and the two are equivalent. This deletes the ATAG boot path from the Integrator/AP and Integrator/CP platforms to move them on to the future. Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/core.c | 57 -------- arch/arm/mach-integrator/integrator_ap.c | 135 ------------------ arch/arm/mach-integrator/integrator_cp.c | 173 ----------------------- arch/arm/mach-integrator/pci_v3.c | 122 ++++------------ 5 files changed, 25 insertions(+), 463 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1ad6fb6c094d..d9ce86857791 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -317,6 +317,7 @@ config ARCH_INTEGRATOR select NEED_MACH_MEMORY_H select PLAT_VERSATILE select SPARSE_IRQ + select USE_OF select VERSATILE_FPGA_IRQ help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index c07c821fb6b3..4698942f3ed3 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -34,63 +34,6 @@ #include "common.h" -#ifdef CONFIG_ATAGS - -#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT } -#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 } -#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 } -#define KMI0_IRQ { IRQ_KMIINT0 } -#define KMI1_IRQ { IRQ_KMIINT1 } - -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, NULL); - -static AMBA_APB_DEVICE(uart1, "uart1", 0, - 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); - -static struct amba_device *amba_devs[] __initdata = { - &rtc_device, - &uart0_device, - &uart1_device, - &kmi0_device, - &kmi1_device, -}; - -int __init integrator_init(bool is_cp) -{ - int i; - - /* - * The Integrator/AP lacks necessary AMBA PrimeCell IDs, so we need to - * hard-code them. The Integator/CP and forward have proper cell IDs. - * Else we leave them undefined to the bus driver can autoprobe them. - */ - if (!is_cp && IS_ENABLED(CONFIG_ARCH_INTEGRATOR_AP)) { - rtc_device.periphid = 0x00041030; - uart0_device.periphid = 0x00041010; - 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++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - - return 0; -} - -#endif - static DEFINE_RAW_SPINLOCK(cm_lock); /** diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index f5fbd8adef0c..563f1c63c25c 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -402,8 +402,6 @@ void __init ap_init_early(void) { } -#ifdef CONFIG_OF - static void __init ap_of_timer_init(void) { struct device_node *node; @@ -564,136 +562,3 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") .restart = integrator_restart, .dt_compat = ap_dt_board_compat, MACHINE_END - -#endif - -#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_map_io(); -} - -/* - * This is where non-devicetree initialization code is collected and stashed - * for eventual deletion. - */ - -static struct platform_device pci_v3_device = { - .name = "pci-v3", - .id = 0, -}; - -static struct resource cfi_flash_resource = { - .start = INTEGRATOR_FLASH_BASE, - .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device cfi_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &ap_flash_data, - }, - .num_resources = 1, - .resource = &cfi_flash_resource, -}; - -static void __init ap_timer_init(void) -{ - struct clk *clk; - unsigned long rate; - - clk = clk_get_sys("ap_timer", NULL); - BUG_ON(IS_ERR(clk)); - clk_prepare_enable(clk); - rate = clk_get_rate(clk); - - writel(0, TIMER0_VA_BASE + TIMER_CTRL); - writel(0, TIMER1_VA_BASE + TIMER_CTRL); - writel(0, TIMER2_VA_BASE + TIMER_CTRL); - - integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE); - integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE, - IRQ_TIMERINT1); -} - -#define INTEGRATOR_SC_VALID_INT 0x003fffff - -static void __init ap_init_irq(void) -{ - /* Disable all interrupts initially. */ - /* Do the core module ones */ - writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); - - /* do the header card stuff next */ - writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); - writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); - - fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, - -1, INTEGRATOR_SC_VALID_INT, NULL); - integrator_clk_init(false); -} - -static void __init ap_init(void) -{ - unsigned long sc_dec; - int i; - - platform_device_register(&pci_v3_device); - platform_device_register(&cfi_flash_device); - - ap_syscon_base = __io_address(INTEGRATOR_SC_BASE); - sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); - for (i = 0; i < 4; i++) { - struct lm_device *lmdev; - - if ((sc_dec & (16 << i)) == 0) - continue; - - lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); - if (!lmdev) - continue; - - lmdev->resource.start = 0xc0000000 + 0x10000000 * i; - lmdev->resource.end = lmdev->resource.start + 0x0fffffff; - lmdev->resource.flags = IORESOURCE_MEM; - lmdev->irq = IRQ_AP_EXPINT0 + i; - lmdev->id = i; - - lm_device_register(lmdev); - } - - integrator_init(false); -} - -MACHINE_START(INTEGRATOR, "ARM-Integrator") - /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .atag_offset = 0x100, - .reserve = integrator_reserve, - .map_io = ap_map_io_atag, - .init_early = ap_init_early, - .init_irq = ap_init_irq, - .handle_irq = fpga_handle_irq, - .init_time = ap_timer_init, - .init_machine = ap_init, - .restart = integrator_restart, -MACHINE_END - -#endif diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 8c60fcb08a98..871c25dee7fe 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -249,7 +249,6 @@ static void __init intcp_init_early(void) #endif } -#ifdef CONFIG_OF static const struct of_device_id fpga_irq_of_match[] __initconst = { { .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, { /* Sentinel */ } @@ -354,175 +353,3 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") .restart = integrator_restart, .dt_compat = intcp_dt_board_compat, MACHINE_END - -#endif - -#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. - */ - -#define INTCP_FLASH_SIZE SZ_32M - -static struct resource intcp_flash_resource = { - .start = INTCP_PA_FLASH_BASE, - .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device intcp_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &intcp_flash_data, - }, - .num_resources = 1, - .resource = &intcp_flash_resource, -}; - -#define INTCP_ETH_SIZE 0x10 - -static struct resource smc91x_resources[] = { - [0] = { - .start = INTEGRATOR_CP_ETH_BASE, - .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_CP_ETHINT, - .end = IRQ_CP_ETHINT, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct platform_device *intcp_devs[] __initdata = { - &intcp_flash_device, - &smc91x_device, -}; - -#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) -#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) -#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) - -static void __init intcp_init_irq(void) -{ - u32 pic_mask, cic_mask, sic_mask; - - /* These masks are for the HW IRQ registers */ - pic_mask = ~((~0u) << (11 - 0)); - pic_mask |= (~((~0u) << (29 - 22))) << 22; - cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); - sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); - - /* - * Disable all interrupt sources - */ - writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); - writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); - writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); - writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); - - fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, - -1, pic_mask, NULL); - - fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, - -1, cic_mask, NULL); - - fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, - IRQ_CP_CPPLDINT, sic_mask, NULL); - - integrator_clk_init(true); -} - -#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) -#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE) -#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE) - -static void __init cp_timer_init(void) -{ - writel(0, TIMER0_VA_BASE + TIMER_CTRL); - writel(0, TIMER1_VA_BASE + TIMER_CTRL); - writel(0, TIMER2_VA_BASE + TIMER_CTRL); - - sp804_clocksource_init(TIMER2_VA_BASE, "timer2"); - sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1"); -} - -#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } -#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT } - -static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, - INTEGRATOR_CP_MMC_IRQS, &mmc_data); - -static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, - INTEGRATOR_CP_AACI_IRQS, NULL); - -static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, - { IRQ_CP_CLCDCINT }, &clcd_data); - -static struct amba_device *amba_devs[] __initdata = { - &mmc_device, - &aaci_device, - &clcd_device, -}; - -static void __init intcp_init(void) -{ - int i; - - platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); - - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - integrator_init(true); -} - -MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .atag_offset = 0x100, - .reserve = integrator_reserve, - .map_io = intcp_map_io_atag, - .init_early = intcp_init_early, - .init_irq = intcp_init_irq, - .handle_irq = fpga_handle_irq, - .init_time = cp_timer_init, - .init_machine = intcp_init, - .restart = integrator_restart, -MACHINE_END - -#endif diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 2d10793fa2a0..67406fc46004 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -809,32 +809,6 @@ static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp) return pci_common_swizzle(dev, pinp); } -static int irq_tab[4] __initdata = { - IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3 -}; - -/* - * map the specified device/slot/pin to an IRQ. This works out such - * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. - */ -static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - int intnr = ((slot - 9) + (pin - 1)) & 3; - - return irq_tab[intnr]; -} - -static struct hw_pci pci_v3 __initdata = { - .swizzle = pci_v3_swizzle, - .setup = pci_v3_setup, - .nr_controllers = 1, - .ops = &pci_v3_ops, - .preinit = pci_v3_preinit, - .postinit = pci_v3_postinit, -}; - -#ifdef CONFIG_OF - static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_irq oirq; @@ -851,14 +825,36 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin) oirq.size); } -static int __init pci_v3_dtprobe(struct platform_device *pdev, - struct device_node *np) +static struct hw_pci pci_v3 __initdata = { + .swizzle = pci_v3_swizzle, + .setup = pci_v3_setup, + .nr_controllers = 1, + .ops = &pci_v3_ops, + .preinit = pci_v3_preinit, + .postinit = pci_v3_postinit, +}; + +static int __init pci_v3_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct of_pci_range_parser parser; struct of_pci_range range; struct resource *res; int irq, ret; + /* Remap the Integrator system controller */ + ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); + if (!ap_syscon_base) { + dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); + return -ENODEV; + } + + /* Device tree probe path */ + if (!np) { + dev_err(&pdev->dev, "no device tree node for PCIv3\n"); + return -ENODEV; + } + if (of_pci_range_parser_init(&parser, np)) return -EINVAL; @@ -925,76 +921,6 @@ static int __init pci_v3_dtprobe(struct platform_device *pdev, return 0; } -#else - -static inline int pci_v3_dtprobe(struct platform_device *pdev, - struct device_node *np) -{ - return -EINVAL; -} - -#endif - -static int __init pci_v3_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - /* Remap the Integrator system controller */ - ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); - if (!ap_syscon_base) { - dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); - return -ENODEV; - } - - /* Device tree probe path */ - if (np) - return pci_v3_dtprobe(pdev, np); - - pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K); - if (!pci_v3_base) { - dev_err(&pdev->dev, "unable to remap PCIv3 base\n"); - return -ENODEV; - } - - ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL); - if (ret) { - dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n", - ret); - return -ENODEV; - } - - conf_mem.name = "PCIv3 config"; - conf_mem.start = PHYS_PCI_CONFIG_BASE; - conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1; - conf_mem.flags = IORESOURCE_MEM; - - io_mem.name = "PCIv3 I/O"; - io_mem.start = PHYS_PCI_IO_BASE; - io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1; - io_mem.flags = IORESOURCE_MEM; - - non_mem_pci = 0x00000000; - non_mem_pci_sz = SZ_256M; - non_mem.name = "PCIv3 non-prefetched mem"; - non_mem.start = PHYS_PCI_MEM_BASE; - non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1; - non_mem.flags = IORESOURCE_MEM; - - pre_mem_pci = 0x10000000; - pre_mem_pci_sz = SZ_256M; - pre_mem.name = "PCIv3 prefetched mem"; - pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M; - pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1; - pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; - - pci_v3.map_irq = pci_v3_map_irq; - - pci_common_init_dev(&pdev->dev, &pci_v3); - - return 0; -} - static const struct of_device_id pci_ids[] = { { .compatible = "v3,v360epc-pci", }, {}, From 578fdfdf32a84ca17ed2090dba4ff2c8e688cc89 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 15 Jun 2013 23:58:15 +0200 Subject: [PATCH 06/10] ARM: integrator: decommission the header This header is no longer needed when we boot from the device tree. Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/core.c | 1 - arch/arm/mach-integrator/include/mach/irqs.h | 81 -------------------- arch/arm/mach-integrator/integrator_ap.c | 1 - arch/arm/mach-integrator/integrator_cp.c | 1 - arch/arm/mach-integrator/pci_v3.c | 1 - 5 files changed, 85 deletions(-) delete mode 100644 arch/arm/mach-integrator/include/mach/irqs.h diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 4698942f3ed3..dd85cc9d234c 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h deleted file mode 100644 index eff0adad9ae3..000000000000 --- a/arch/arm/mach-integrator/include/mach/irqs.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * arch/arm/mach-integrator/include/mach/irqs.h - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Interrupt numbers, all of the above are just static reservations - * used so they can be encoded into device resources. They will finally - * be done away with when switching to device tree. - */ -#define IRQ_PIC_START 64 -#define IRQ_SOFTINT (IRQ_PIC_START+0) -#define IRQ_UARTINT0 (IRQ_PIC_START+1) -#define IRQ_UARTINT1 (IRQ_PIC_START+2) -#define IRQ_KMIINT0 (IRQ_PIC_START+3) -#define IRQ_KMIINT1 (IRQ_PIC_START+4) -#define IRQ_TIMERINT0 (IRQ_PIC_START+5) -#define IRQ_TIMERINT1 (IRQ_PIC_START+6) -#define IRQ_TIMERINT2 (IRQ_PIC_START+7) -#define IRQ_RTCINT (IRQ_PIC_START+8) -#define IRQ_AP_EXPINT0 (IRQ_PIC_START+9) -#define IRQ_AP_EXPINT1 (IRQ_PIC_START+10) -#define IRQ_AP_EXPINT2 (IRQ_PIC_START+11) -#define IRQ_AP_EXPINT3 (IRQ_PIC_START+12) -#define IRQ_AP_PCIINT0 (IRQ_PIC_START+13) -#define IRQ_AP_PCIINT1 (IRQ_PIC_START+14) -#define IRQ_AP_PCIINT2 (IRQ_PIC_START+15) -#define IRQ_AP_PCIINT3 (IRQ_PIC_START+16) -#define IRQ_AP_V3INT (IRQ_PIC_START+17) -#define IRQ_AP_CPINT0 (IRQ_PIC_START+18) -#define IRQ_AP_CPINT1 (IRQ_PIC_START+19) -#define IRQ_AP_LBUSTIMEOUT (IRQ_PIC_START+20) -#define IRQ_AP_APCINT (IRQ_PIC_START+21) -#define IRQ_CP_CLCDCINT (IRQ_PIC_START+22) -#define IRQ_CP_MMCIINT0 (IRQ_PIC_START+23) -#define IRQ_CP_MMCIINT1 (IRQ_PIC_START+24) -#define IRQ_CP_AACIINT (IRQ_PIC_START+25) -#define IRQ_CP_CPPLDINT (IRQ_PIC_START+26) -#define IRQ_CP_ETHINT (IRQ_PIC_START+27) -#define IRQ_CP_TSPENINT (IRQ_PIC_START+28) -#define IRQ_PIC_END (IRQ_PIC_START+28) - -#define IRQ_CIC_START (IRQ_PIC_END+1) -#define IRQ_CM_SOFTINT (IRQ_CIC_START+0) -#define IRQ_CM_COMMRX (IRQ_CIC_START+1) -#define IRQ_CM_COMMTX (IRQ_CIC_START+2) -#define IRQ_CIC_END (IRQ_CIC_START+2) - -/* - * IntegratorCP only - */ -#define IRQ_SIC_START (IRQ_CIC_END+1) -#define IRQ_SIC_CP_SOFTINT (IRQ_SIC_START+0) -#define IRQ_SIC_CP_RI0 (IRQ_SIC_START+1) -#define IRQ_SIC_CP_RI1 (IRQ_SIC_START+2) -#define IRQ_SIC_CP_CARDIN (IRQ_SIC_START+3) -#define IRQ_SIC_CP_LMINT0 (IRQ_SIC_START+4) -#define IRQ_SIC_CP_LMINT1 (IRQ_SIC_START+5) -#define IRQ_SIC_CP_LMINT2 (IRQ_SIC_START+6) -#define IRQ_SIC_CP_LMINT3 (IRQ_SIC_START+7) -#define IRQ_SIC_CP_LMINT4 (IRQ_SIC_START+8) -#define IRQ_SIC_CP_LMINT5 (IRQ_SIC_START+9) -#define IRQ_SIC_CP_LMINT6 (IRQ_SIC_START+10) -#define IRQ_SIC_CP_LMINT7 (IRQ_SIC_START+11) -#define IRQ_SIC_END (IRQ_SIC_START+11) diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 563f1c63c25c..88a62a5febc2 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -51,7 +51,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 871c25dee7fe..26b344197560 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -38,7 +38,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 67406fc46004..ce8d0cafb7cf 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -36,7 +36,6 @@ #include #include -#include #include #include From bb4dbefe4c6ae3685152d03e318e093d5f6f795a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 16 Jun 2013 02:44:27 +0200 Subject: [PATCH 07/10] ARM: integrator: move CM base into device tree This moves the core module (CM) control base into the device tree. It is a simple memory range of 0x200 bytes. Move the cm header down into the machine directory and unexport the cm_control() symbol as no modules are using it. Signed-off-by: Linus Walleij --- .../devicetree/bindings/arm/arm-boards | 19 +++ arch/arm/boot/dts/integrator.dtsi | 5 + .../mach-integrator/{include/mach => }/cm.h | 4 +- arch/arm/mach-integrator/core.c | 120 +++++++++++------- arch/arm/mach-integrator/integrator_ap.c | 6 +- arch/arm/mach-integrator/integrator_cp.c | 3 +- arch/arm/mach-integrator/leds.c | 3 +- 7 files changed, 111 insertions(+), 49 deletions(-) rename arch/arm/mach-integrator/{include/mach => }/cm.h (94%) diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 5fdd7b9eeb52..0ebf3d94e8bf 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -11,6 +11,20 @@ FPGA type interrupt controllers, see the versatile-fpga-irq binding doc. Required nodes: +- core-module: the root node to the Integrator platforms must have + a core-module with regs and the compatible string + "arm,core-module-integrator" + + Required properties for the core module: + - regs: the location and size of the core module registers, one + range of 0x200 bytes. + +- cpcon/syscon: 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. The AP syscon node must include the logical module + interrupts. + 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. @@ -25,6 +39,11 @@ example: model = "ARM Integrator/AP"; compatible = "arm,integrator-ap"; + core-module@10000000 { + compatible = "arm,core-module-integrator"; + reg = <0x10000000 0x200>; + }; + syscon { /* AP system controller registers */ reg = <0x11000000 0x100>; diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 813b91d7bea2..0f06f8687b0b 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi @@ -5,6 +5,11 @@ /include/ "skeleton.dtsi" / { + core-module@10000000 { + compatible = "arm,core-module-integrator"; + reg = <0x10000000 0x200>; + }; + timer@13000000 { reg = <0x13000000 0x100>; interrupt-parent = <&pic>; diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/cm.h similarity index 94% rename from arch/arm/mach-integrator/include/mach/cm.h rename to arch/arm/mach-integrator/cm.h index ae6085f1db19..4ecff7bff482 100644 --- a/arch/arm/mach-integrator/include/mach/cm.h +++ b/arch/arm/mach-integrator/cm.h @@ -4,7 +4,9 @@ u32 cm_get(void); void cm_control(u32, u32); -#define CM_CTRL __io_address(INTEGRATOR_HDR_CTRL) +struct device_node; +void cm_init(void); +void cm_clear_irqs(void); #define CM_CTRL_LED (1 << 0) #define CM_CTRL_nMBDET (1 << 1) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index dd85cc9d234c..00ddf20ed91b 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -22,18 +22,21 @@ #include #include #include +#include +#include #include #include -#include #include #include #include +#include "cm.h" #include "common.h" static DEFINE_RAW_SPINLOCK(cm_lock); +static void __iomem *cm_base; /** * cm_get - get the value from the CM_CTRL register @@ -54,12 +57,80 @@ void cm_control(u32 mask, u32 set) u32 val; raw_spin_lock_irqsave(&cm_lock, flags); - val = readl(CM_CTRL) & ~mask; - writel(val | set, CM_CTRL); + val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask; + writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET); raw_spin_unlock_irqrestore(&cm_lock, flags); } -EXPORT_SYMBOL(cm_control); +static const char *integrator_arch_str(u32 id) +{ + switch ((id >> 16) & 0xff) { + case 0x00: + return "ASB little-endian"; + case 0x01: + return "AHB little-endian"; + case 0x03: + return "AHB-Lite system bus, bi-endian"; + case 0x04: + return "AHB"; + case 0x08: + return "AHB system bus, ASB processor bus"; + default: + return "Unknown"; + } +} + +static const char *integrator_fpga_str(u32 id) +{ + switch ((id >> 12) & 0xf) { + case 0x01: + return "XC4062"; + case 0x02: + return "XC4085"; + case 0x03: + return "XVC600"; + case 0x04: + return "EPM7256AE (Altera PLD)"; + default: + return "Unknown"; + } +} + +void cm_clear_irqs(void) +{ + /* disable core module IRQs */ + writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET + + IRQ_ENABLE_CLEAR); +} + +static const struct of_device_id cm_match[] = { + { .compatible = "arm,core-module-integrator"}, + { }, +}; + +void cm_init(void) +{ + struct device_node *cm = of_find_matching_node(NULL, cm_match); + u32 val; + + if (!cm) { + pr_crit("no core module node found in device tree\n"); + return; + } + cm_base = of_iomap(cm, 0); + if (!cm_base) { + pr_crit("could not remap core module\n"); + return; + } + cm_clear_irqs(); + val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET); + pr_info("Detected ARM core module:\n"); + pr_info(" Manufacturer: %02x\n", (val >> 24)); + pr_info(" Architecture: %s\n", integrator_arch_str(val)); + pr_info(" FPGA: %s\n", integrator_fpga_str(val)); + pr_info(" Build: %02x\n", (val >> 4) & 0xFF); + pr_info(" Rev: %c\n", ('A' + (val & 0x03))); +} /* * We need to stop things allocating the low memory; ideally we need a @@ -95,27 +166,7 @@ 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); + return sprintf(buf, "%s\n", integrator_arch_str(integrator_id)); } static struct device_attribute intcp_arch_attr = @@ -125,24 +176,7 @@ 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); + return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id)); } static struct device_attribute intcp_fpga_attr = diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 88a62a5febc2..ece47556afe6 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -57,6 +57,7 @@ #include #include +#include "cm.h" #include "common.h" #include "pci_v3.h" @@ -145,7 +146,7 @@ static int irq_suspend(void) static void irq_resume(void) { /* disable all irq sources */ - writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + cm_clear_irqs(); writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); @@ -447,8 +448,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = { static void __init ap_init_irq_of(void) { - /* disable core module IRQs */ - writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + cm_init(); of_irq_init(fpga_irq_of_match); integrator_clk_init(false); } diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 26b344197560..422c3f9b4163 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -49,6 +48,7 @@ #include #include +#include "cm.h" #include "common.h" /* Base address to the CP controller */ @@ -255,6 +255,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = { static void __init intcp_init_irq_of(void) { + cm_init(); of_irq_init(fpga_irq_of_match); integrator_clk_init(true); } diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index ed82535845f7..cb6ac58f5e07 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c @@ -11,10 +11,11 @@ #include #include -#include #include #include +#include "cm.h" + #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE) From bdac7eacc43d2e4f2e2b9d5e70050138f5d07d62 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 17 Jun 2013 22:52:32 +0200 Subject: [PATCH 08/10] cpufreq: probe the Integrator cpufreq driver from DT This makes the Integrator cpufreq driver probe from the core module device tree node through it's registered platforms device, getting the memory base from the device tree, remapping it and removing dependencies to and by moving the two affected CM register offsets into the driver. Acked-by: Viresh Kumar Acked-by: Rafael J. Wysocki Signed-off-by: Linus Walleij --- drivers/cpufreq/integrator-cpufreq.c | 61 ++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index f7c99df0880b..3d79bca47433 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c @@ -15,18 +15,19 @@ #include #include #include +#include +#include +#include -#include -#include #include #include -static struct cpufreq_driver integrator_driver; +static void __iomem *cm_base; +/* The cpufreq driver only use the OSC register */ +#define INTEGRATOR_HDR_OSC_OFFSET 0x08 +#define INTEGRATOR_HDR_LOCK_OFFSET 0x14 -#define CM_ID __io_address(INTEGRATOR_HDR_ID) -#define CM_OSC __io_address(INTEGRATOR_HDR_OSC) -#define CM_STAT __io_address(INTEGRATOR_HDR_STAT) -#define CM_LOCK __io_address(INTEGRATOR_HDR_LOCK) +static struct cpufreq_driver integrator_driver; static const struct icst_params lclk_params = { .ref = 24000000, @@ -100,7 +101,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, BUG_ON(cpu != smp_processor_id()); /* get current setting */ - cm_osc = __raw_readl(CM_OSC); + cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); if (machine_is_integrator()) { vco.s = (cm_osc >> 8) & 7; @@ -128,7 +129,7 @@ static int integrator_set_target(struct cpufreq_policy *policy, cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - cm_osc = __raw_readl(CM_OSC); + cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); if (machine_is_integrator()) { cm_osc &= 0xfffff800; @@ -138,9 +139,9 @@ static int integrator_set_target(struct cpufreq_policy *policy, } cm_osc |= vco.v; - __raw_writel(0xa05f, CM_LOCK); - __raw_writel(cm_osc, CM_OSC); - __raw_writel(0, CM_LOCK); + __raw_writel(0xa05f, cm_base + INTEGRATOR_HDR_LOCK_OFFSET); + __raw_writel(cm_osc, cm_base + INTEGRATOR_HDR_OSC_OFFSET); + __raw_writel(0, cm_base + INTEGRATOR_HDR_LOCK_OFFSET); /* * Restore the CPUs allowed mask. @@ -165,7 +166,7 @@ static unsigned int integrator_get(unsigned int cpu) BUG_ON(cpu != smp_processor_id()); /* detect memory etc. */ - cm_osc = __raw_readl(CM_OSC); + cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); if (machine_is_integrator()) { vco.s = (cm_osc >> 8) & 7; @@ -202,19 +203,43 @@ static struct cpufreq_driver integrator_driver = { .name = "integrator", }; -static int __init integrator_cpu_init(void) +static int __init integrator_cpufreq_probe(struct platform_device *pdev) { + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!cm_base) + return -ENODEV; + return cpufreq_register_driver(&integrator_driver); } -static void __exit integrator_cpu_exit(void) +static void __exit integrator_cpufreq_remove(struct platform_device *pdev) { cpufreq_unregister_driver(&integrator_driver); } +static const struct of_device_id integrator_cpufreq_match[] = { + { .compatible = "arm,core-module-integrator"}, + { }, +}; + +static struct platform_driver integrator_cpufreq_driver = { + .driver = { + .name = "integrator-cpufreq", + .owner = THIS_MODULE, + .of_match_table = integrator_cpufreq_match, + }, + .remove = __exit_p(integrator_cpufreq_remove), +}; + +module_platform_driver_probe(integrator_cpufreq_driver, + integrator_cpufreq_probe); + MODULE_AUTHOR ("Russell M. King"); MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs"); MODULE_LICENSE ("GPL"); - -module_init(integrator_cpu_init); -module_exit(integrator_cpu_exit); From 99d14a1d9b876c9847608983606fa1928f5bf8f3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Oct 2013 16:51:28 +0200 Subject: [PATCH 09/10] ARM: integrator: use devm_ioremap() to remap CM In the PCIv3 driver, use devm_ioremap() instead of just ioremap() when remapping the system controller in the PCIv3 driver, so the mapping will be automatically released on probe failure. Reported-by: Mark Rutland Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/pci_v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index ce8d0cafb7cf..c9c5a33bc802 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -842,7 +842,7 @@ static int __init pci_v3_probe(struct platform_device *pdev) int irq, ret; /* Remap the Integrator system controller */ - ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); + ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100); if (!ap_syscon_base) { dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); return -ENODEV; From df36680f1a71eef97685c30eb9eaf55a6813b6cd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Oct 2013 18:24:58 +0200 Subject: [PATCH 10/10] ARM: integrator: core module registers from compatible strings This augments the core machine code for the Integrator platforms to get their references to the core module device nodes by using compatible strings instead of predefined node names and rename the CP syscon node to be simply "syscon". Reported-by: Mark Rutland Signed-off-by: Linus Walleij --- .../devicetree/bindings/arm/arm-boards | 28 +++++++++++-------- arch/arm/boot/dts/integratorap.dts | 2 +- arch/arm/boot/dts/integratorcp.dts | 4 +-- arch/arm/mach-integrator/integrator_ap.c | 8 +++++- arch/arm/mach-integrator/integrator_cp.c | 8 +++++- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 0ebf3d94e8bf..5fac246a9530 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -19,18 +19,22 @@ Required nodes: - regs: the location and size of the core module registers, one range of 0x200 bytes. -- cpcon/syscon: 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. The AP syscon node must include the logical module - interrupts. +- syscon: the root node of the Integrator platforms must have a + system controller node pointong to the control registers, + with the compatible string + "arm,integrator-ap-syscon" + "arm,integrator-cp-syscon" + respectively. -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. -The AP syscon node must include the logic module interrupts, stated -in order of module instance -example: + Required properties for the system controller: + - regs: the location and size of the system controller registers, + one range of 0x100 bytes. + + Required properties for the AP system controller: + - interrupts: the AP syscon node must include the logical module + interrupts, stated in order of module instance , + , ... for the CP system controller this + is not required not of any use. /dts-v1/; /include/ "integrator.dtsi" @@ -45,7 +49,7 @@ example: }; syscon { - /* AP system controller registers */ + compatible = "arm,integrator-ap-syscon"; reg = <0x11000000 0x100>; interrupt-parent = <&pic>; /* These are the logic module IRQs */ diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index 453ab0ea4d2b..e6be9315ff0a 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -19,7 +19,7 @@ chosen { }; syscon { - /* AP system controller registers */ + compatible = "arm,integrator-ap-syscon"; reg = <0x11000000 0x100>; interrupt-parent = <&pic>; /* These are the logical module IRQs */ diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index ff1aea0ee043..a3a06b893237 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts @@ -18,8 +18,8 @@ chosen { bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; }; - cpcon { - /* CP controller registers */ + syscon { + compatible = "arm,integrator-cp-syscon"; reg = <0xcb000000 0x100>; }; diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index ece47556afe6..d50dc2dbfd89 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -470,6 +470,11 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = { { /* sentinel */ }, }; +static const struct of_device_id ap_syscon_match[] = { + { .compatible = "arm,integrator-ap-syscon"}, + { }, +}; + static void __init ap_init_of(void) { unsigned long sc_dec; @@ -486,7 +491,8 @@ static void __init ap_init_of(void) root = of_find_node_by_path("/"); if (!root) return; - syscon = of_find_node_by_path("/syscon"); + + syscon = of_find_matching_node(root, ap_syscon_match); if (!syscon) return; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 422c3f9b4163..1df6e7602cad 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -286,6 +286,11 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { { /* sentinel */ }, }; +static const struct of_device_id intcp_syscon_match[] = { + { .compatible = "arm,integrator-cp-syscon"}, + { }, +}; + static void __init intcp_init_of(void) { struct device_node *root; @@ -300,7 +305,8 @@ static void __init intcp_init_of(void) root = of_find_node_by_path("/"); if (!root) return; - cpcon = of_find_node_by_path("/cpcon"); + + cpcon = of_find_matching_node(root, intcp_syscon_match); if (!cpcon) return;