diff options
Diffstat (limited to 'arch')
42 files changed, 407 insertions, 1119 deletions
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index bb23c2d33cf..840958ba556 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -345,10 +345,14 @@ }; }; - ramc: ramc@ffffe200 { + ramc0: ramc@ffffe200 { compatible = "atmel,at91sam9260-sdramc"; - reg = <0xffffe200 0x200 - 0xffffe800 0x200>; + reg = <0xffffe200 0x200>; + }; + + ramc1: ramc@ffffe800 { + compatible = "atmel,at91sam9260-sdramc"; + reg = <0xffffe800 0x200>; }; pit: timer@fffffd30 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 932a669156a..857fd3e0b8a 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -96,8 +96,14 @@ ramc0: ramc@ffffe400 { compatible = "atmel,at91sam9g45-ddramc"; - reg = <0xffffe400 0x200 - 0xffffe600 0x200>; + reg = <0xffffe400 0x200>; + clocks = <&ddrck>; + clock-names = "ddrck"; + }; + + ramc1: ramc@ffffe600 { + compatible = "atmel,at91sam9g45-ddramc"; + reg = <0xffffe600 0x200>; clocks = <&ddrck>; clock-names = "ddrck"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 2bfac310dbe..68eb9aded16 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -87,6 +87,8 @@ ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; + clocks = <&ddrck>; + clock-names = "ddrck"; }; pmc: pmc@fffffc00 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index e1a5c70b885..765a1e39858 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -95,6 +95,8 @@ ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; + clocks = <&ddrck>; + clock-names = "ddrck"; }; pmc: pmc@fffffc00 { diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 45013b867c8..7702a0d120c 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -402,8 +402,10 @@ }; ramc0: ramc@ffffea00 { - compatible = "atmel,at91sam9g45-ddramc"; + compatible = "atmel,sama5d3-ddramc"; reg = <0xffffea00 0x200>; + clocks = <&ddrck>, <&mpddr_clk>; + clock-names = "ddrck", "mpddr"; }; dbgu: serial@ffffee00 { @@ -1170,6 +1172,11 @@ #clock-cells = <0>; reg = <48>; }; + + mpddr_clk: mpddr_clk { + #clock-cells = <0>; + reg = <49>; + }; }; }; @@ -1178,6 +1185,11 @@ reg = <0xfffffe00 0x10>; }; + shutdown-controller@fffffe10 { + compatible = "atmel,at91sam9x5-shdwc"; + reg = <0xfffffe10 0x10>; + }; + pit: timer@fffffe30 { compatible = "atmel,at91sam9260-pit"; reg = <0xfffffe30 0xf>; diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 6cc6f7aebda..474c855fa83 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -28,36 +28,30 @@ config OLD_CLK_AT91 bool default AT91_PMC_UNIT && AT91_USE_OLD_CLK -config AT91_SAM9_ALT_RESET - bool - default !ARCH_AT91X40 - -config AT91_SAM9G45_RESET - bool - default !ARCH_AT91X40 - -config AT91_SAM9_TIME +config OLD_IRQ_AT91 bool + select MULTI_IRQ_HANDLER + select SPARSE_IRQ config HAVE_AT91_SMD bool config SOC_AT91SAM9 bool - select AT91_SAM9_TIME + select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 select CPU_ARM926T select GENERIC_CLOCKEVENTS - select MULTI_IRQ_HANDLER - select SPARSE_IRQ + select MEMORY if USE_OF + select ATMEL_SDRAMC if USE_OF config SOC_SAMA5 bool - select AT91_SAM9_TIME + select ATMEL_AIC5_IRQ select CPU_V7 select GENERIC_CLOCKEVENTS - select MULTI_IRQ_HANDLER - select SPARSE_IRQ select USE_OF + select MEMORY + select ATMEL_SDRAMC menu "Atmel AT91 System-on-Chip" @@ -70,8 +64,7 @@ config ARCH_AT91X40 depends on !MMU select CPU_ARM7TDMI select ARCH_USES_GETTIMEOFFSET - select MULTI_IRQ_HANDLER - select SPARSE_IRQ + select OLD_IRQ_AT91 help Select this if you are using one of Atmel's AT91X40 SoC. @@ -108,11 +101,10 @@ endif if SOC_SAM_V4_V5 config SOC_AT91RM9200 bool "AT91RM9200" + select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 select CPU_ARM920T select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 - select MULTI_IRQ_HANDLER - select SPARSE_IRQ select HAVE_AT91_USB_CLK config SOC_AT91SAM9260 diff --git a/arch/arm/mach-at91/Kconfig.non_dt b/arch/arm/mach-at91/Kconfig.non_dt index 44ace320d2e..b774c3d3c63 100644 --- a/arch/arm/mach-at91/Kconfig.non_dt +++ b/arch/arm/mach-at91/Kconfig.non_dt @@ -14,31 +14,37 @@ config ARCH_AT91RM9200 bool "AT91RM9200" select SOC_AT91RM9200 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" select SOC_AT91SAM9260 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9261 bool "AT91SAM9261 or AT91SAM9G10" select SOC_AT91SAM9261 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9263 bool "AT91SAM9263" select SOC_AT91SAM9263 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9RL bool "AT91SAM9RL" select SOC_AT91SAM9RL select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9G45 bool "AT91SAM9G45" select SOC_AT91SAM9G45 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 endchoice diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 78e9cec282f..61d04f9314e 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -2,15 +2,13 @@ # Makefile for the linux kernel. # -obj-y := irq.o gpio.o setup.o sysirq_mask.o +obj-y := gpio.o setup.o sysirq_mask.o obj-m := obj-n := obj- := +obj-$(CONFIG_OLD_IRQ_AT91) += irq.o obj-$(CONFIG_OLD_CLK_AT91) += clock.o -obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o -obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o -obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o # CPU-specific support diff --git a/arch/arm/mach-at91/at91_rstc.h b/arch/arm/mach-at91/at91_rstc.h deleted file mode 100644 index a600e699292..00000000000 --- a/arch/arm/mach-at91/at91_rstc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91_rstc.h - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Reset Controller (RSTC) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * 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. - */ - -#ifndef AT91_RSTC_H -#define AT91_RSTC_H - -#ifndef __ASSEMBLY__ -extern void __iomem *at91_rstc_base; - -#define at91_rstc_read(field) \ - __raw_readl(at91_rstc_base + field) - -#define at91_rstc_write(field, value) \ - __raw_writel(value, at91_rstc_base + field) -#else -.extern at91_rstc_base -#endif - -#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */ -#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ -#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */ -#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */ -#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */ - -#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */ -#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */ -#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ -#define AT91_RSTC_RSTTYP_GENERAL (0 << 8) -#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8) -#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8) -#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8) -#define AT91_RSTC_RSTTYP_USER (4 << 8) -#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */ -#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */ - -#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */ -#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */ -#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */ -#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */ - -#endif diff --git a/arch/arm/mach-at91/at91_shdwc.h b/arch/arm/mach-at91/at91_shdwc.h deleted file mode 100644 index 9e29f31ec9a..00000000000 --- a/arch/arm/mach-at91/at91_shdwc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/at91_shdwc.h - * - * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. - * - * Shutdown Controller (SHDWC) - System peripherals regsters. - * Based on AT91SAM9261 datasheet revision D. - * - * 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. - */ - -#ifndef AT91_SHDWC_H -#define AT91_SHDWC_H - -#ifndef __ASSEMBLY__ -extern void __iomem *at91_shdwc_base; - -#define at91_shdwc_read(field) \ - __raw_readl(at91_shdwc_base + field) - -#define at91_shdwc_write(field, value) \ - __raw_writel(value, at91_shdwc_base + field) -#endif - -#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ -#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ -#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ - -#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */ -#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ -#define AT91_SHDW_WKMODE0_NONE 0 -#define AT91_SHDW_WKMODE0_HIGH 1 -#define AT91_SHDW_WKMODE0_LOW 2 -#define AT91_SHDW_WKMODE0_ANYLEVEL 3 -#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */ -#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */ -#define AT91_SHDW_CPTWK0_(x) ((x) << 4) -#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ -#define AT91_SHDW_RTCWKEN (1 << 17) /* Real Time Clock Wake-up Enable */ - -#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ -#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ -#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */ -#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */ - -#endif diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 3477ba94c4c..aab1f969a7c 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -11,6 +11,7 @@ */ #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/clk/at91_pmc.h> #include <asm/proc-fns.h> @@ -24,7 +25,6 @@ #include <mach/hardware.h> #include "at91_aic.h" -#include "at91_rstc.h" #include "soc.h" #include "generic.h" #include "sam9_smc.h" @@ -342,8 +342,6 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { - at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9260_BASE_RSTC); at91_ioremap_ramc(0, AT91SAM9260_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); @@ -354,7 +352,6 @@ static void __init at91sam9260_ioremap_registers(void) static void __init at91sam9260_initialize(void) { arm_pm_idle = at91sam9_idle; - arm_pm_restart = at91sam9_alt_restart; at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT); @@ -362,6 +359,45 @@ static void __init at91sam9260_initialize(void) at91_gpio_init(at91sam9260_gpio, 3); } +static struct resource rstc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_RSTC, + .end = AT91SAM9260_BASE_RSTC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_BASE_SDRAMC, + .end = AT91SAM9260_BASE_SDRAMC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rstc_device = { + .name = "at91-sam9260-reset", + .resource = rstc_resources, + .num_resources = ARRAY_SIZE(rstc_resources), +}; + +static struct resource shdwc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SHDWC, + .end = AT91SAM9260_BASE_SHDWC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device shdwc_device = { + .name = "at91-poweroff", + .resource = shdwc_resources, + .num_resources = ARRAY_SIZE(shdwc_resources), +}; + +static void __init at91sam9260_register_devices(void) +{ + platform_device_register(&rstc_device); + platform_device_register(&shdwc_device); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -404,6 +440,11 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; +static void __init at91sam9260_init_time(void) +{ + at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); +} + AT91_SOC_START(at91sam9260) .map_io = at91sam9260_map_io, .default_irq_priority = at91sam9260_default_irq_priority, @@ -411,5 +452,7 @@ AT91_SOC_START(at91sam9260) | (1 << AT91SAM9260_ID_IRQ2), .ioremap_registers = at91sam9260_ioremap_registers, .register_clocks = at91sam9260_register_clocks, + .register_devices = at91sam9260_register_devices, .init = at91sam9260_initialize, + .init_time = at91sam9260_init_time, AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index fb164a5d04a..a8bd3596333 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -11,6 +11,7 @@ */ #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/clk/at91_pmc.h> #include <asm/proc-fns.h> @@ -23,7 +24,6 @@ #include <mach/hardware.h> #include "at91_aic.h" -#include "at91_rstc.h" #include "soc.h" #include "generic.h" #include "sam9_smc.h" @@ -301,8 +301,6 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { - at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9261_BASE_RSTC); at91_ioremap_ramc(0, AT91SAM9261_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); @@ -313,7 +311,6 @@ static void __init at91sam9261_ioremap_registers(void) static void __init at91sam9261_initialize(void) { arm_pm_idle = at91sam9_idle; - arm_pm_restart = at91sam9_alt_restart; at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT); @@ -321,6 +318,45 @@ static void __init at91sam9261_initialize(void) at91_gpio_init(at91sam9261_gpio, 3); } +static struct resource rstc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_RSTC, + .end = AT91SAM9261_BASE_RSTC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_BASE_SDRAMC, + .end = AT91SAM9261_BASE_SDRAMC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rstc_device = { + .name = "at91-sam9260-reset", + .resource = rstc_resources, + .num_resources = ARRAY_SIZE(rstc_resources), +}; + +static struct resource shdwc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SHDWC, + .end = AT91SAM9261_BASE_SHDWC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device shdwc_device = { + .name = "at91-poweroff", + .resource = shdwc_resources, + .num_resources = ARRAY_SIZE(shdwc_resources), +}; + +static void __init at91sam9261_register_devices(void) +{ + platform_device_register(&rstc_device); + platform_device_register(&shdwc_device); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -363,6 +399,11 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; +static void __init at91sam9261_init_time(void) +{ + at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); +} + AT91_SOC_START(at91sam9261) .map_io = at91sam9261_map_io, .default_irq_priority = at91sam9261_default_irq_priority, @@ -370,5 +411,7 @@ AT91_SOC_START(at91sam9261) | (1 << AT91SAM9261_ID_IRQ2), .ioremap_registers = at91sam9261_ioremap_registers, .register_clocks = at91sam9261_register_clocks, + .register_devices = at91sam9261_register_devices, .init = at91sam9261_initialize, + .init_time = at91sam9261_init_time, AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 810fa5f15a5..fbff228cc63 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -11,6 +11,7 @@ */ #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/clk/at91_pmc.h> #include <asm/proc-fns.h> @@ -22,7 +23,6 @@ #include <mach/hardware.h> #include "at91_aic.h" -#include "at91_rstc.h" #include "soc.h" #include "generic.h" #include "sam9_smc.h" @@ -321,8 +321,6 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { - at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9263_BASE_RSTC); at91_ioremap_ramc(0, AT91SAM9263_BASE_SDRAMC0, 512); at91_ioremap_ramc(1, AT91SAM9263_BASE_SDRAMC1, 512); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); @@ -335,7 +333,6 @@ static void __init at91sam9263_ioremap_registers(void) static void __init at91sam9263_initialize(void) { arm_pm_idle = at91sam9_idle; - arm_pm_restart = at91sam9_alt_restart; at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0); at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1); @@ -344,6 +341,45 @@ static void __init at91sam9263_initialize(void) at91_gpio_init(at91sam9263_gpio, 5); } +static struct resource rstc_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_RSTC, + .end = AT91SAM9263_BASE_RSTC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9263_BASE_SDRAMC0, + .end = AT91SAM9263_BASE_SDRAMC0 + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rstc_device = { + .name = "at91-sam9260-reset", + .resource = rstc_resources, + .num_resources = ARRAY_SIZE(rstc_resources), +}; + +static struct resource shdwc_resources[] = { + [0] = { + .start = AT91SAM9263_BASE_SHDWC, + .end = AT91SAM9263_BASE_SHDWC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device shdwc_device = { + .name = "at91-poweroff", + .resource = shdwc_resources, + .num_resources = ARRAY_SIZE(shdwc_resources), +}; + +static void __init at91sam9263_register_devices(void) +{ + platform_device_register(&rstc_device); + platform_device_register(&shdwc_device); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -386,11 +422,18 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ1) */ }; +static void __init at91sam9263_init_time(void) +{ + at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); +} + AT91_SOC_START(at91sam9263) .map_io = at91sam9263_map_io, .default_irq_priority = at91sam9263_default_irq_priority, .extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1), .ioremap_registers = at91sam9263_ioremap_registers, .register_clocks = at91sam9263_register_clocks, + .register_devices = at91sam9263_register_devices, .init = at91sam9263_initialize, + .init_time = at91sam9263_init_time, AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c deleted file mode 100644 index 0a9e2fc8f79..00000000000 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x - * - * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France - * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France - * Converted to ClockSource/ClockEvents by David Brownell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/clk.h> -#include <linux/clockchips.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> - -#include <asm/mach/time.h> -#include <mach/hardware.h> - -#define AT91_PIT_MR 0x00 /* Mode Register */ -#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */ -#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */ -#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */ - -#define AT91_PIT_SR 0x04 /* Status Register */ -#define AT91_PIT_PITS (1 << 0) /* Timer Status */ - -#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */ -#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */ -#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */ -#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */ - -#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) -#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20) - -static u32 pit_cycle; /* write-once */ -static u32 pit_cnt; /* access only w/system irq blocked */ -static void __iomem *pit_base_addr __read_mostly; -static struct clk *mck; - -static inline unsigned int pit_read(unsigned int reg_offset) -{ - return __raw_readl(pit_base_addr + reg_offset); -} - -static inline void pit_write(unsigned int reg_offset, unsigned long value) -{ - __raw_writel(value, pit_base_addr + reg_offset); -} - -/* - * Clocksource: just a monotonic counter of MCK/16 cycles. - * We don't care whether or not PIT irqs are enabled. - */ -static cycle_t read_pit_clk(struct clocksource *cs) -{ - unsigned long flags; - u32 elapsed; - u32 t; - - raw_local_irq_save(flags); - elapsed = pit_cnt; - t = pit_read(AT91_PIT_PIIR); - raw_local_irq_restore(flags); - - elapsed += PIT_PICNT(t) * pit_cycle; - elapsed += PIT_CPIV(t); - return elapsed; -} - -static struct clocksource pit_clk = { - .name = "pit", - .rating = 175, - .read = read_pit_clk, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - - -/* - * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) - */ -static void -pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) -{ - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - /* update clocksource counter */ - pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR)); - pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN - | AT91_PIT_PITIEN); - break; - case CLOCK_EVT_MODE_ONESHOT: - BUG(); - /* FALLTHROUGH */ - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - /* disable irq, leaving the clocksource active */ - pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); - break; - case CLOCK_EVT_MODE_RESUME: - break; - } -} - -static void at91sam926x_pit_suspend(struct clock_event_device *cedev) -{ - /* Disable timer */ - pit_write(AT91_PIT_MR, 0); -} - -static void at91sam926x_pit_reset(void) -{ - /* Disable timer and irqs */ - pit_write(AT91_PIT_MR, 0); - - /* Clear any pending interrupts, wait for PIT to stop counting */ - while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0) - cpu_relax(); - - /* Start PIT but don't enable IRQ */ - pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); -} - -static void at91sam926x_pit_resume(struct clock_event_device *cedev) -{ - at91sam926x_pit_reset(); -} - -static struct clock_event_device pit_clkevt = { - .name = "pit", - .features = CLOCK_EVT_FEAT_PERIODIC, - .shift = 32, - .rating = 100, - .set_mode = pit_clkevt_mode, - .suspend = at91sam926x_pit_suspend, - .resume = at91sam926x_pit_resume, -}; - - -/* - * IRQ handler for the timer. - */ -static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) -{ - /* - * irqs should be disabled here, but as the irq is shared they are only - * guaranteed to be off if the timer irq is registered first. - */ - WARN_ON_ONCE(!irqs_disabled()); - - /* The PIT interrupt may be disabled, and is shared */ - if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC) - && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) { - unsigned nr_ticks; - - /* Get number of ticks performed before irq, and ack it */ - nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR)); - do { - pit_cnt += pit_cycle; - pit_clkevt.event_handler(&pit_clkevt); - nr_ticks--; - } while (nr_ticks); - - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static struct irqaction at91sam926x_pit_irq = { - .name = "at91_tick", - .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = at91sam926x_pit_interrupt, - .irq = NR_IRQS_LEGACY + AT91_ID_SYS, -}; - -#ifdef CONFIG_OF -static struct of_device_id pit_timer_ids[] = { - { .compatible = "atmel,at91sam9260-pit" }, - { /* sentinel */ } -}; - -static int __init of_at91sam926x_pit_init(void) -{ - struct device_node *np; - int ret; - - np = of_find_matching_node(NULL, pit_timer_ids); - if (!np) - goto err; - - pit_base_addr = of_iomap(np, 0); - if (!pit_base_addr) - goto node_err; - - mck = of_clk_get(np, 0); - - /* Get the interrupts property */ - ret = irq_of_parse_and_map(np, 0); - if (!ret) { - pr_crit("AT91: PIT: Unable to get IRQ from DT\n"); - if (!IS_ERR(mck)) - clk_put(mck); - goto ioremap_err; - } - at91sam926x_pit_irq.irq = ret; - - of_node_put(np); - - return 0; - -ioremap_err: - iounmap(pit_base_addr); -node_err: - of_node_put(np); -err: - return -EINVAL; -} -#else -static int __init of_at91sam926x_pit_init(void) -{ - return -EINVAL; -} -#endif - -/* - * Set up both clocksource and clockevent support. - */ -void __init at91sam926x_pit_init(void) -{ - unsigned long pit_rate; - unsigned bits; - int ret; - - mck = ERR_PTR(-ENOENT); - - /* For device tree enabled device: initialize here */ - of_at91sam926x_pit_init(); - - /* - * Use our actual MCK to figure out how many MCK/16 ticks per - * 1/HZ period (instead of a compile-time constant LATCH). - */ - if (IS_ERR(mck)) - mck = clk_get(NULL, "mck"); - - if (IS_ERR(mck)) - panic("AT91: PIT: Unable to get mck clk\n"); - pit_rate = clk_get_rate(mck) / 16; - pit_cycle = (pit_rate + HZ/2) / HZ; - WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0); - - /* Initialize and enable the timer */ - at91sam926x_pit_reset(); - - /* - * Register clocksource. The high order bits of PIV are unused, - * so this isn't a 32-bit counter unless we get clockevent irqs. - */ - bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */; - pit_clk.mask = CLOCKSOURCE_MASK(bits); - clocksource_register_hz(&pit_clk, pit_rate); - - /* Set up irq handler */ - ret = setup_irq(at91sam926x_pit_irq.irq, &at91sam926x_pit_irq); - if (ret) - pr_crit("AT91: PIT: Unable to setup IRQ\n"); - - /* Set up and register clockevents */ - pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift); - pit_clkevt.cpumask = cpumask_of(0); - clockevents_register_device(&pit_clkevt); -} - -void __init at91sam926x_ioremap_pit(u32 addr) -{ -#if defined(CONFIG_OF) - struct device_node *np = - of_find_matching_node(NULL, pit_timer_ids); - - if (np) { - of_node_put(np); - return; - } -#endif - pit_base_addr = ioremap(addr, 16); - - if (!pit_base_addr) - panic("Impossible to ioremap PIT\n"); -} diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S deleted file mode 100644 index f039538d3bd..00000000000 --- a/arch/arm/mach-at91/at91sam9_alt_reset.S +++ /dev/null @@ -1,40 +0,0 @@ -/* - * reset AT91SAM9G20 as per errata - * - * (C) BitBox Ltd 2010 - * - * unless the SDRAM is cleanly shutdown before we hit the - * reset register it can be left driving the data bus and - * killing the chance of a subsequent boot from NAND - * - * 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. - */ - -#include <linux/linkage.h> -#include <mach/hardware.h> -#include <mach/at91_ramc.h> -#include "at91_rstc.h" - - .arm - - .globl at91sam9_alt_restart - -at91sam9_alt_restart: ldr r0, =at91_ramc_base @ preload constants - ldr r0, [r0] - ldr r4, =at91_rstc_base - ldr r1, [r4] - - mov r2, #1 - mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN - ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST - - .balign 32 @ align to cache line - - str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access - str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM - str r4, [r1, #AT91_RSTC_CR] @ reset processor - - b . diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 9d45496e493..405427ec05f 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/clk/at91_pmc.h> +#include <linux/platform_device.h> #include <asm/irq.h> #include <asm/mach/arch.h> @@ -371,8 +372,6 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { - at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC); at91_ioremap_ramc(0, AT91SAM9G45_BASE_DDRSDRC1, 512); at91_ioremap_ramc(1, AT91SAM9G45_BASE_DDRSDRC0, 512); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); @@ -384,7 +383,6 @@ static void __init at91sam9g45_ioremap_registers(void) static void __init at91sam9g45_initialize(void) { arm_pm_idle = at91sam9_idle; - arm_pm_restart = at91sam9g45_restart; at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC); at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT); @@ -393,6 +391,50 @@ static void __init at91sam9g45_initialize(void) at91_gpio_init(at91sam9g45_gpio, 5); } +static struct resource rstc_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_RSTC, + .end = AT91SAM9G45_BASE_RSTC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9G45_BASE_DDRSDRC1, + .end = AT91SAM9G45_BASE_DDRSDRC1 + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9G45_BASE_DDRSDRC0, + .end = AT91SAM9G45_BASE_DDRSDRC0 + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rstc_device = { + .name = "at91-sam9g45-reset", + .resource = rstc_resources, + .num_resources = ARRAY_SIZE(rstc_resources), +}; + +static struct resource shdwc_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_SHDWC, + .end = AT91SAM9G45_BASE_SHDWC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device shdwc_device = { + .name = "at91-poweroff", + .resource = shdwc_resources, + .num_resources = ARRAY_SIZE(shdwc_resources), +}; + +static void __init at91sam9g45_register_devices(void) +{ + platform_device_register(&rstc_device); + platform_device_register(&shdwc_device); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -435,11 +477,18 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ0) */ }; +static void __init at91sam9g45_init_time(void) +{ + at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); +} + AT91_SOC_START(at91sam9g45) .map_io = at91sam9g45_map_io, .default_irq_priority = at91sam9g45_default_irq_priority, .extern_irq = (1 << AT91SAM9G45_ID_IRQ0), .ioremap_registers = at91sam9g45_ioremap_registers, .register_clocks = at91sam9g45_register_clocks, + .register_devices = at91sam9g45_register_devices, .init = at91sam9g45_initialize, + .init_time = at91sam9g45_init_time, AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S deleted file mode 100644 index c40c1e2ef80..00000000000 --- a/arch/arm/mach-at91/at91sam9g45_reset.S +++ /dev/null @@ -1,45 +0,0 @@ -/* - * reset AT91SAM9G45 as per errata - * - * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com> - * - * unless the SDRAM is cleanly shutdown before we hit the - * reset register it can be left driving the data bus and - * killing the chance of a subsequent boot from NAND - * - * GPLv2 Only - */ - -#include <linux/linkage.h> -#include <mach/hardware.h> -#include <mach/at91_ramc.h> -#include "at91_rstc.h" - .arm - -/* - * at91_ramc_base is an array void* - * init at NULL if only one DDR controler is present in or DT - */ - .globl at91sam9g45_restart - -at91sam9g45_restart: - ldr r5, =at91_ramc_base @ preload constants - ldr r0, [r5] - ldr r5, [r5, #4] @ ddr1 - cmp r5, #0 - ldr r4, =at91_rstc_base - ldr r1, [r4] - - mov r2, #1 - mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN - ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST - - .balign 32 @ align to cache line - - strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access - strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1 - str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access - str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0 - str r4, [r1, #AT91_RSTC_CR] @ reset processor - - b . diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 878d5015daa..f553e4ea034 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -10,6 +10,7 @@ */ #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/clk/at91_pmc.h> #include <asm/proc-fns.h> @@ -23,7 +24,6 @@ #include <mach/hardware.h> #include "at91_aic.h" -#include "at91_rstc.h" #include "soc.h" #include "generic.h" #include "sam9_smc.h" @@ -311,8 +311,6 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { - at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC); at91_ioremap_ramc(0, AT91SAM9RL_BASE_SDRAMC, 512); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); @@ -323,7 +321,6 @@ static void __init at91sam9rl_ioremap_registers(void) static void __init at91sam9rl_initialize(void) { arm_pm_idle = at91sam9_idle; - arm_pm_restart = at91sam9_alt_restart; at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC); at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT); @@ -332,6 +329,45 @@ static void __init at91sam9rl_initialize(void) at91_gpio_init(at91sam9rl_gpio, 4); } +static struct resource rstc_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_RSTC, + .end = AT91SAM9RL_BASE_RSTC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_BASE_SDRAMC, + .end = AT91SAM9RL_BASE_SDRAMC + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rstc_device = { + .name = "at91-sam9260-reset", + .resource = rstc_resources, + .num_resources = ARRAY_SIZE(rstc_resources), +}; + +static struct resource shdwc_resources[] = { + [0] = { + .start = AT91SAM9RL_BASE_SHDWC, + .end = AT91SAM9RL_BASE_SHDWC + SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device shdwc_device = { + .name = "at91-poweroff", + .resource = shdwc_resources, + .num_resources = ARRAY_SIZE(shdwc_resources), +}; + +static void __init at91sam9rl_register_devices(void) +{ + platform_device_register(&rstc_device); + platform_device_register(&shdwc_device); +} + /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -374,6 +410,11 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; +static void __init at91sam9rl_init_time(void) +{ + at91sam926x_pit_init(NR_IRQS_LEGACY + AT91_ID_SYS); +} + AT91_SOC_START(at91sam9rl) .map_io = at91sam9rl_map_io, .default_irq_priority = at91sam9rl_default_irq_priority, @@ -382,5 +423,7 @@ AT91_SOC_START(at91sam9rl) #if defined(CONFIG_OLD_CLK_AT91) .register_clocks = at91sam9rl_register_clocks, #endif + .register_devices = at91sam9rl_register_devices, .init = at91sam9rl_initialize, + .init_time = at91sam9rl_init_time, AT91_SOC_END diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 597c649170a..e76e35ce81e 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -167,6 +167,8 @@ static struct at91_cf_data afeb9260_cf_data = { static void __init afeb9260_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -211,7 +213,7 @@ static void __init afeb9260_board_init(void) MACHINE_START(AFEB9260, "Custom afeb9260 board") /* Maintainer: Sergey Lapin <slapin@ossfans.org> */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = afeb9260_init_early, diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index a30502c8d37..ae827dd2d0d 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -170,6 +170,8 @@ static void __init cam60_add_device_nand(void) static void __init cam60_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -188,7 +190,7 @@ static void __init cam60_board_init(void) MACHINE_START(CAM60, "KwikByte CAM60") /* Maintainer: KwikByte */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = cam60_init_early, diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 2037f78c84e..731c8318f4f 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -322,6 +322,8 @@ static struct mci_platform_data __initdata cpu9krea_mci0_data = { static void __init cpu9krea_board_init(void) { + at91_register_devices(); + /* NOR */ cpu9krea_add_device_nor(); /* Serial */ @@ -375,7 +377,7 @@ MACHINE_START(CPUAT9260, "Eukrea CPU9260") MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") #endif /* Maintainer: Eric Benard - EUKREA Electromatique */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = cpu9krea_init_early, diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c index 3a185faee79..61ea2144566 100644 --- a/arch/arm/mach-at91/board-dt-rm9200.c +++ b/arch/arm/mach-at91/board-dt-rm9200.c @@ -24,17 +24,6 @@ #include "at91_aic.h" #include "generic.h" - -static const struct of_device_id irq_of_match[] __initconst = { - { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { /*sentinel*/ } -}; - -static void __init at91rm9200_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static const char *at91rm9200_dt_board_compat[] __initdata = { "atmel,at91rm9200", NULL @@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = { DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") .init_time = at91rm9200_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, .init_early = at91rm9200_dt_initialize, - .init_irq = at91rm9200_dt_init_irq, .dt_compat = at91rm9200_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c index 575b0be66ca..d3048ccdc41 100644 --- a/arch/arm/mach-at91/board-dt-sam9.c +++ b/arch/arm/mach-at91/board-dt-sam9.c @@ -25,26 +25,6 @@ #include "board.h" #include "generic.h" - -static void __init sam9_dt_timer_init(void) -{ -#if defined(CONFIG_COMMON_CLK) - of_clk_init(NULL); -#endif - at91sam926x_pit_init(); -} - -static const struct of_device_id irq_of_match[] __initconst = { - - { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { /*sentinel*/ } -}; - -static void __init at91_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9", NULL @@ -52,10 +32,7 @@ static const char *at91_dt_board_compat[] __initdata = { DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") /* Maintainer: Atmel */ - .init_time = sam9_dt_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, .init_early = at91_dt_initialize, - .init_irq = at91_dt_init_irq, .dt_compat = at91_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c index 075ec0576ad..be6aa2e2c34 100644 --- a/arch/arm/mach-at91/board-dt-sama5.c +++ b/arch/arm/mach-at91/board-dt-sama5.c @@ -27,25 +27,6 @@ #include "at91_aic.h" #include "generic.h" -static void __init sama5_dt_timer_init(void) -{ -#if defined(CONFIG_COMMON_CLK) - of_clk_init(NULL); -#endif - at91sam926x_pit_init(); -} - -static const struct of_device_id irq_of_match[] __initconst = { - - { .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init }, - { /*sentinel*/ } -}; - -static void __init at91_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static int ksz9021rn_phy_fixup(struct phy_device *phy) { int value; @@ -80,11 +61,8 @@ static const char *sama5_dt_board_compat[] __initdata = { DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") /* Maintainer: Atmel */ - .init_time = sama5_dt_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic5_handle_irq, .init_early = at91_dt_initialize, - .init_irq = at91_dt_init_irq, .init_machine = sama5_dt_device_init, .dt_compat = sama5_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index 68f1ab6bd08..a6aa4a2432f 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -138,6 +138,8 @@ static struct gpio_led flexibity_leds[] = { static void __init flexibity_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -160,7 +162,7 @@ static void __init flexibity_board_init(void) MACHINE_START(FLEXIBITY, "Flexibity Connect") /* Maintainer: Maxim Osipov */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = flexibity_init_early, diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index 8b22c60bb23..ec290b6ed9d 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -263,7 +263,7 @@ static void __init foxg20_board_init(void) MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20") /* Maintainer: Sergio Tanzilli */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = foxg20_init_early, diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index b729dd1271b..bf5cc55c7db 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -576,7 +576,7 @@ static void __init gsia18s_board_init(void) } MACHINE_START(GSIA18S, "GS_IA18_S") - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = gsia18s_init_early, diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index b48d95ec515..9c26b94ce44 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -219,7 +219,7 @@ static void __init pcontrol_g20_board_init(void) MACHINE_START(PCONTROL_G20, "PControl G20") /* Maintainer: pgsellmann@portner-elektronik.at */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = pcontrol_g20_init_early, diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index d24dda67e2d..c2166e3a236 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -187,6 +187,8 @@ static struct gpio_led ek_leds[] = { static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -219,7 +221,7 @@ static void __init ek_board_init(void) MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260") /* Maintainer: Olimex */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 65dea12d685..bf8a946b4cd 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -45,7 +45,6 @@ #include <mach/system_rev.h> #include "at91_aic.h" -#include "at91_shdwc.h" #include "board.h" #include "sam9_smc.h" #include "generic.h" @@ -307,6 +306,8 @@ static void __init ek_add_device_buttons(void) {} static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -344,7 +345,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 4637432de08..e85ada820bf 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -49,7 +49,6 @@ #include <mach/system_rev.h> #include "at91_aic.h" -#include "at91_shdwc.h" #include "board.h" #include "sam9_smc.h" #include "generic.h" @@ -561,6 +560,8 @@ static struct gpio_led ek_leds[] = { static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -603,7 +604,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, @@ -613,7 +614,7 @@ MACHINE_END MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index fc446097f41..d76680f2a20 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -50,7 +50,6 @@ #include <mach/system_rev.h> #include "at91_aic.h" -#include "at91_shdwc.h" #include "board.h" #include "sam9_smc.h" #include "generic.h" @@ -439,6 +438,8 @@ static struct platform_device *devices[] __initdata = { static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -483,7 +484,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index e1be6e25b38..49f07521345 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -410,7 +410,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, @@ -420,7 +420,7 @@ MACHINE_END MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index b227732b0c8..a517c7f7af9 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -48,7 +48,6 @@ #include <mach/system_rev.h> #include "at91_aic.h" -#include "at91_shdwc.h" #include "board.h" #include "sam9_smc.h" #include "generic.h" @@ -471,6 +470,8 @@ static struct platform_device *devices[] __initdata = { static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DGBU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -517,7 +518,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index b64648b4a1f..8bca329b029 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -35,7 +35,6 @@ #include "at91_aic.h" -#include "at91_shdwc.h" #include "board.h" #include "sam9_smc.h" #include "generic.h" @@ -292,6 +291,8 @@ static void __init ek_add_device_buttons(void) {} static void __init ek_board_init(void) { + at91_register_devices(); + /* Serial */ /* DBGU on ttyS0. (Rx & Tx only) */ at91_register_uart(0, 0, 0); @@ -323,7 +324,7 @@ static void __init ek_board_init(void) MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = ek_init_early, diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 1b870e6def0..b4aff840a1a 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -154,6 +154,8 @@ static void __init snapper9260_add_device_nand(void) static void __init snapper9260_board_init(void) { + at91_register_devices(); + at91_add_device_i2c(snapper9260_i2c_devices, ARRAY_SIZE(snapper9260_i2c_devices)); @@ -178,7 +180,7 @@ static void __init snapper9260_board_init(void) } MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module") - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = snapper9260_init_early, diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 3b575036ff9..e825641a1de 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -275,7 +275,7 @@ static void __init stamp9g20evb_board_init(void) MACHINE_START(PORTUXG20, "taskit PortuxG20") /* Maintainer: taskit GmbH */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = stamp9g20_init_early, @@ -285,7 +285,7 @@ MACHINE_END MACHINE_START(STAMP9G20, "taskit Stamp9G20") /* Maintainer: taskit GmbH */ - .init_time = at91sam926x_pit_init, + .init_time = at91_init_time, .map_io = at91_map_io, .handle_irq = at91_aic_handle_irq, .init_early = stamp9g20_init_early, diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 631fa3b8c16..189d7c7e7f6 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -8,6 +8,9 @@ * published by the Free Software Foundation. */ +#ifndef _AT91_GENERIC_H +#define _AT91_GENERIC_H + #include <linux/clkdev.h> #include <linux/of.h> #include <linux/reboot.h> @@ -37,12 +40,15 @@ extern int __init at91_aic5_of_init(struct device_node *node, extern void __init at91_sysirq_mask_rtc(u32 rtc_base); extern void __init at91_sysirq_mask_rtt(u32 rtt_base); + /* Devices */ +extern void __init at91_register_devices(void); /* Timer */ +extern void __init at91_init_time(void); extern void at91rm9200_ioremap_st(u32 addr); extern void at91rm9200_timer_init(void); extern void at91sam926x_ioremap_pit(u32 addr); -extern void at91sam926x_pit_init(void); +extern void at91sam926x_pit_init(int irq); extern void at91x40_timer_init(void); /* Clocks */ @@ -62,14 +68,6 @@ extern void at91_irq_resume(void); /* idle */ extern void at91sam9_idle(void); -/* reset */ -extern void at91_ioremap_rstc(u32 base_addr); -extern void at91sam9_alt_restart(enum reboot_mode, const char *); -extern void at91sam9g45_restart(enum reboot_mode, const char *); - -/* shutdown */ -extern void at91_ioremap_shdwc(u32 base_addr); - /* Matrix */ extern void at91_ioremap_matrix(u32 base_addr); @@ -90,3 +88,5 @@ extern int __init at91_gpio_of_irq_setup(struct device_node *node, struct device_node *parent); extern u32 at91_get_extern_irq(void); + +#endif /* _AT91_GENERIC_H */ diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index 3d192c5aee6..cdb3ec9efd2 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -48,11 +48,6 @@ void __iomem *at91_aic_base; static struct irq_domain *at91_aic_domain; static struct device_node *at91_aic_np; static unsigned int n_irqs = NR_AIC_IRQS; -static unsigned long at91_aic_caps = 0; - -/* AIC5 introduces a Source Select Register */ -#define AT91_AIC_CAP_AIC5 (1 << 0) -#define has_aic5() (at91_aic_caps & AT91_AIC_CAP_AIC5) #ifdef CONFIG_PM @@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) void at91_irq_suspend(void) { - int bit = -1; - - if (has_aic5()) { - /* disable enabled irqs */ - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - } - /* enable wakeup irqs */ - bit = -1; - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - } - } else { - at91_aic_write(AT91_AIC_IDCR, *backups); - at91_aic_write(AT91_AIC_IECR, *wakeups); - } + at91_aic_write(AT91_AIC_IDCR, *backups); + at91_aic_write(AT91_AIC_IECR, *wakeups); } void at91_irq_resume(void) { - int bit = -1; - - if (has_aic5()) { - /* disable wakeup irqs */ - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - } - /* enable irqs disabled for suspend */ - bit = -1; - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - } - } else { - at91_aic_write(AT91_AIC_IDCR, *wakeups); - at91_aic_write(AT91_AIC_IECR, *backups); - } + at91_aic_write(AT91_AIC_IDCR, *wakeups); + at91_aic_write(AT91_AIC_IECR, *backups); } #else @@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs) handle_IRQ(irqnr, regs); } -asmlinkage void __exception_irq_entry -at91_aic5_handle_irq(struct pt_regs *regs) -{ - u32 irqnr; - u32 irqstat; - - irqnr = at91_aic_read(AT91_AIC5_IVR); - irqstat = at91_aic_read(AT91_AIC5_ISR); - - if (!irqstat) - at91_aic_write(AT91_AIC5_EOICR, 0); - else - handle_IRQ(irqnr, regs); -} - static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ @@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d) clear_backup(d->hwirq); } -static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d) -{ - /* Disable interrupt on AIC5 */ - at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - /* Update ISR cache */ - clear_backup(d->hwirq); -} - static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ @@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d) set_backup(d->hwirq); } -static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d) -{ - /* Enable interrupt on AIC5 */ - at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - /* Update ISR cache */ - set_backup(d->hwirq); -} - static void at91_aic_eoi(struct irq_data *d) { /* @@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d) at91_aic_write(AT91_AIC_EOICR, 0); } -static void __maybe_unused at91_aic5_eoi(struct irq_data *d) -{ - at91_aic_write(AT91_AIC5_EOICR, 0); -} - static unsigned long *at91_extern_irq; u32 at91_get_extern_irq(void) @@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) if (srctype < 0) return srctype; - if (has_aic5()) { - at91_aic_write(AT91_AIC5_SSR, - d->hwirq & AT91_AIC5_INTSEL_MSK); - smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC5_SMR, smr | srctype); - } else { - smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) - & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); - } + smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); return 0; } @@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector) at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); } -static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector) -{ - int i; - - /* - * Perform 8 End Of Interrupt Command to make sure AIC - * will not Lock out nIRQ - */ - for (i = 0; i < 8; i++) - at91_aic_write(AT91_AIC5_EOICR, 0); - - /* - * Spurious Interrupt ID in Spurious Vector Register. - * When there is no current interrupt, the IRQ Vector Register - * reads the value stored in AIC_SPU - */ - at91_aic_write(AT91_AIC5_SPU, spu_vector); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_aic_write(AT91_AIC5_DCR, 0); - - /* Disable and clear all interrupts initially */ - for (i = 0; i < n_irqs; i++) { - at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - at91_aic_write(AT91_AIC5_ICCR, 1); - } -} - -#if defined(CONFIG_OF) -static unsigned int *at91_aic_irq_priorities; - -static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - /* Put virq number in Source Vector Register */ - at91_aic_write(AT91_AIC_SVR(hw), virq); - - /* Active Low interrupt, with priority */ - at91_aic_write(AT91_AIC_SMR(hw), - AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]); - - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -} - -static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK); - - /* Put virq number in Source Vector Register */ - at91_aic_write(AT91_AIC5_SVR, virq); - - /* Active Low interrupt, with priority */ - at91_aic_write(AT91_AIC5_SMR, - AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]); - - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -} - -static int at91_aic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) -{ - if (WARN_ON(intsize < 3)) - return -EINVAL; - if (WARN_ON(intspec[0] >= n_irqs)) - return -EINVAL; - if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY) - || (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY))) - return -EINVAL; - - *out_hwirq = intspec[0]; - *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; - at91_aic_irq_priorities[*out_hwirq] = intspec[2]; - - return 0; -} - -static struct irq_domain_ops at91_aic_irq_ops = { - .map = at91_aic_irq_map, - .xlate = at91_aic_irq_domain_xlate, -}; - -int __init at91_aic_of_common_init(struct device_node *node, - struct device_node *parent) -{ - struct property *prop; - const __be32 *p; - u32 val; - - at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) - * sizeof(*at91_extern_irq), GFP_KERNEL); - if (!at91_extern_irq) - return -ENOMEM; - - if (at91_aic_pm_init()) { - kfree(at91_extern_irq); - return -ENOMEM; - } - - at91_aic_irq_priorities = kzalloc(n_irqs - * sizeof(*at91_aic_irq_priorities), - GFP_KERNEL); - if (!at91_aic_irq_priorities) - return -ENOMEM; - - at91_aic_base = of_iomap(node, 0); - at91_aic_np = node; - - at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs, - &at91_aic_irq_ops, NULL); - if (!at91_aic_domain) - panic("Unable to add AIC irq domain (DT)\n"); - - of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) { - if (val >= n_irqs) - pr_warn("AIC: external irq %d >= %d skip it\n", - val, n_irqs); - else - set_bit(val, at91_extern_irq); - } - - irq_set_default_host(at91_aic_domain); - - return 0; -} - -int __init at91_aic_of_init(struct device_node *node, - struct device_node *parent) -{ - int err; - - err = at91_aic_of_common_init(node, parent); - if (err) - return err; - - at91_aic_hw_init(n_irqs); - - return 0; -} - -int __init at91_aic5_of_init(struct device_node *node, - struct device_node *parent) -{ - int err; - - at91_aic_caps |= AT91_AIC_CAP_AIC5; - n_irqs = NR_AIC5_IRQS; - at91_aic_chip.irq_ack = at91_aic5_mask_irq; - at91_aic_chip.irq_mask = at91_aic5_mask_irq; - at91_aic_chip.irq_unmask = at91_aic5_unmask_irq; - at91_aic_chip.irq_eoi = at91_aic5_eoi; - at91_aic_irq_ops.map = at91_aic5_irq_map; - - err = at91_aic_of_common_init(node, parent); - if (err) - return err; - - at91_aic5_hw_init(n_irqs); - - return 0; -} -#endif - /* * Initialize the AIC interrupt controller. */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index e9555453298..4073ab7f38f 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -34,79 +34,8 @@ #include "pm.h" #include "gpio.h" -/* - * Show the reason for the previous system reset. - */ - -#include "at91_rstc.h" -#include "at91_shdwc.h" - static void (*at91_pm_standby)(void); -static void __init show_reset_status(void) -{ - static char reset[] __initdata = "reset"; - - static char general[] __initdata = "general"; - static char wakeup[] __initdata = "wakeup"; - static char watchdog[] __initdata = "watchdog"; - static char software[] __initdata = "software"; - static char user[] __initdata = "user"; - static char unknown[] __initdata = "unknown"; - - static char signal[] __initdata = "signal"; - static char rtc[] __initdata = "rtc"; - static char rtt[] __initdata = "rtt"; - static char restore[] __initdata = "power-restored"; - - char *reason, *r2 = reset; - u32 reset_type, wake_type; - - if (!at91_shdwc_base || !at91_rstc_base) - return; - - reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; - wake_type = at91_shdwc_read(AT91_SHDW_SR); - - switch (reset_type) { - case AT91_RSTC_RSTTYP_GENERAL: - reason = general; - break; - case AT91_RSTC_RSTTYP_WAKEUP: - /* board-specific code enabled the wakeup sources */ - reason = wakeup; - - /* "wakeup signal" */ - if (wake_type & AT91_SHDW_WAKEUP0) - r2 = signal; - else { - r2 = reason; - if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */ - reason = rtt; - else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */ - reason = rtc; - else if (wake_type == 0) /* power-restored wakeup */ - reason = restore; - else /* unknown wakeup */ - reason = unknown; - } - break; - case AT91_RSTC_RSTTYP_WATCHDOG: - reason = watchdog; - break; - case AT91_RSTC_RSTTYP_SOFTWARE: - reason = software; - break; - case AT91_RSTC_RSTTYP_USER: - reason = user; - break; - default: - reason = unknown; - break; - } - pr_info("AT91: Starting after %s %s\n", reason, r2); -} - static int at91_pm_valid_state(suspend_state_t state) { switch (state) { @@ -206,16 +135,19 @@ static int at91_pm_enter(suspend_state_t state) at91_pinctrl_gpio_suspend(); else at91_gpio_suspend(); - at91_irq_suspend(); - pr_debug("AT91: PM - wake mask %08x, pm state %d\n", - /* remember all the always-wake irqs */ - (at91_pmc_read(AT91_PMC_PCSR) - | (1 << AT91_ID_FIQ) - | (1 << AT91_ID_SYS) - | (at91_get_extern_irq())) - & at91_aic_read(AT91_AIC_IMR), - state); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) { + at91_irq_suspend(); + + pr_debug("AT91: PM - wake mask %08x, pm state %d\n", + /* remember all the always-wake irqs */ + (at91_pmc_read(AT91_PMC_PCSR) + | (1 << AT91_ID_FIQ) + | (1 << AT91_ID_SYS) + | (at91_get_extern_irq())) + & at91_aic_read(AT91_AIC_IMR), + state); + } switch (state) { /* @@ -280,12 +212,17 @@ static int at91_pm_enter(suspend_state_t state) goto error; } - pr_debug("AT91: PM - wakeup %08x\n", - at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) + pr_debug("AT91: PM - wakeup %08x\n", + at91_aic_read(AT91_AIC_IPR) & + at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; - at91_irq_resume(); + + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) + at91_irq_resume(); + if (of_have_populated_dt()) at91_pinctrl_gpio_resume(); else @@ -338,7 +275,6 @@ static int __init at91_pm_init(void) suspend_set_ops(&at91_pm_ops); - show_reset_status(); return 0; } arch_initcall(at91_pm_init); diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index f7a07a58ebb..51c22a2fcea 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -5,6 +5,8 @@ * Under GPLv2 */ +#define pr_fmt(fmt) "AT91: " fmt + #include <linux/module.h> #include <linux/io.h> #include <linux/mm.h> @@ -20,7 +22,6 @@ #include <mach/cpu.h> #include <mach/at91_dbgu.h> -#include "at91_shdwc.h" #include "soc.h" #include "generic.h" #include "pm.h" @@ -37,7 +38,7 @@ void __init at91rm9200_set_type(int type) else at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; - pr_info("AT91: filled in soc subtype: %s\n", + pr_info("filled in soc subtype: %s\n", at91_get_soc_subtype(&at91_soc_initdata)); } @@ -49,7 +50,8 @@ void __init at91_init_irq_default(void) void __init at91_init_interrupts(unsigned int *priority) { /* Initialize the AIC interrupt controller */ - at91_aic_init(priority, at91_boot_soc.extern_irq); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91)) + at91_aic_init(priority, at91_boot_soc.extern_irq); /* Enable GPIO interrupts */ at91_gpio_irq_setup(); @@ -66,7 +68,7 @@ void __init at91_ioremap_ramc(int id, u32 addr, u32 size) } at91_ramc_base[id] = ioremap(addr, size); if (!at91_ramc_base[id]) - panic("Impossible to ioremap ramc.%d 0x%x\n", id, addr); + panic(pr_fmt("Impossible to ioremap ramc.%d 0x%x\n"), id, addr); } static struct map_desc sram_desc[2] __initdata; @@ -83,7 +85,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length) desc->length = length; desc->type = MT_MEMORY_RWX_NONCACHED; - pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", + pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n", base, length, desc->virtual); iotable_init(desc, 1); @@ -302,45 +304,21 @@ void __init at91_map_io(void) soc_detect(AT91_BASE_DBGU1); if (!at91_soc_is_detected()) - panic("AT91: Impossible to detect the SOC type"); + panic(pr_fmt("Impossible to detect the SOC type")); - pr_info("AT91: Detected soc type: %s\n", + pr_info("Detected soc type: %s\n", at91_get_soc_type(&at91_soc_initdata)); if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE) - pr_info("AT91: Detected soc subtype: %s\n", + pr_info("Detected soc subtype: %s\n", at91_get_soc_subtype(&at91_soc_initdata)); if (!at91_soc_is_enabled()) - panic("AT91: Soc not enabled"); + panic(pr_fmt("Soc not enabled")); if (at91_boot_soc.map_io) at91_boot_soc.map_io(); } -void __iomem *at91_shdwc_base = NULL; - -static void at91sam9_poweroff(void) -{ - at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - -void __init at91_ioremap_shdwc(u32 base_addr) -{ - at91_shdwc_base = ioremap(base_addr, 16); - if (!at91_shdwc_base) - panic("Impossible to ioremap at91_shdwc_base\n"); - pm_power_off = at91sam9_poweroff; -} - -void __iomem *at91_rstc_base; - -void __init at91_ioremap_rstc(u32 base_addr) -{ - at91_rstc_base = ioremap(base_addr, 16); - if (!at91_rstc_base) - panic("Impossible to ioremap at91_rstc_base\n"); -} - void __iomem *at91_matrix_base; EXPORT_SYMBOL_GPL(at91_matrix_base); @@ -348,42 +326,15 @@ void __init at91_ioremap_matrix(u32 base_addr) { at91_matrix_base = ioremap(base_addr, 512); if (!at91_matrix_base) - panic("Impossible to ioremap at91_matrix_base\n"); + panic(pr_fmt("Impossible to ioremap at91_matrix_base\n")); } #if defined(CONFIG_OF) && !defined(CONFIG_ARCH_AT91X40) -static struct of_device_id rstc_ids[] = { - { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart }, - { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, - { /*sentinel*/ } -}; - -static void at91_dt_rstc(void) -{ - struct device_node *np; - const struct of_device_id *of_id; - - np = of_find_matching_node(NULL, rstc_ids); - if (!np) - panic("unable to find compatible rstc node in dtb\n"); - - at91_rstc_base = of_iomap(np, 0); - if (!at91_rstc_base) - panic("unable to map rstc cpu registers\n"); - - of_id = of_match_node(rstc_ids, np); - if (!of_id) - panic("AT91: rtsc no restart function available\n"); - - arm_pm_restart = of_id->data; - - of_node_put(np); -} - static struct of_device_id ramc_ids[] = { { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, + { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, { /*sentinel*/ } }; @@ -391,100 +342,29 @@ static void at91_dt_ramc(void) { struct device_node *np; const struct of_device_id *of_id; + int idx = 0; + const void *standby = NULL; - np = of_find_matching_node(NULL, ramc_ids); - if (!np) - panic("unable to find compatible ram controller node in dtb\n"); - - at91_ramc_base[0] = of_iomap(np, 0); - if (!at91_ramc_base[0]) - panic("unable to map ramc[0] cpu registers\n"); - /* the controller may have 2 banks */ - at91_ramc_base[1] = of_iomap(np, 1); - - of_id = of_match_node(ramc_ids, np); - if (!of_id) - pr_warn("AT91: ramc no standby function available\n"); - else - at91_pm_set_standby(of_id->data); - - of_node_put(np); -} - -static struct of_device_id shdwc_ids[] = { - { .compatible = "atmel,at91sam9260-shdwc", }, - { .compatible = "atmel,at91sam9rl-shdwc", }, - { .compatible = "atmel,at91sam9x5-shdwc", }, - { /*sentinel*/ } -}; - -static const char *shdwc_wakeup_modes[] = { - [AT91_SHDW_WKMODE0_NONE] = "none", - [AT91_SHDW_WKMODE0_HIGH] = "high", - [AT91_SHDW_WKMODE0_LOW] = "low", - [AT91_SHDW_WKMODE0_ANYLEVEL] = "any", -}; - -const int at91_dtget_shdwc_wakeup_mode(struct device_node *np) -{ - const char *pm; - int err, i; + for_each_matching_node_and_match(np, ramc_ids, &of_id) { + at91_ramc_base[idx] = of_iomap(np, 0); + if (!at91_ramc_base[idx]) + panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx); - err = of_property_read_string(np, "atmel,wakeup-mode", &pm); - if (err < 0) - return AT91_SHDW_WKMODE0_ANYLEVEL; + if (!standby) + standby = of_id->data; - for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++) - if (!strcasecmp(pm, shdwc_wakeup_modes[i])) - return i; - - return -ENODEV; -} - -static void at91_dt_shdwc(void) -{ - struct device_node *np; - int wakeup_mode; - u32 reg; - u32 mode = 0; - - np = of_find_matching_node(NULL, shdwc_ids); - if (!np) { - pr_debug("AT91: unable to find compatible shutdown (shdwc) controller node in dtb\n"); - return; + idx++; } - at91_shdwc_base = of_iomap(np, 0); - if (!at91_shdwc_base) - panic("AT91: unable to map shdwc cpu registers\n"); + if (!idx) + panic(pr_fmt("unable to find compatible ram controller node in dtb\n")); - wakeup_mode = at91_dtget_shdwc_wakeup_mode(np); - if (wakeup_mode < 0) { - pr_warn("AT91: shdwc unknown wakeup mode\n"); - goto end; - } - - if (!of_property_read_u32(np, "atmel,wakeup-counter", ®)) { - if (reg > AT91_SHDW_CPTWK0_MAX) { - pr_warn("AT91: shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n", - reg, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX); - reg = AT91_SHDW_CPTWK0_MAX; - } - mode |= AT91_SHDW_CPTWK0_(reg); + if (!standby) { + pr_warn("ramc no standby function available\n"); + return; } - if (of_property_read_bool(np, "atmel,wakeup-rtc-timer")) - mode |= AT91_SHDW_RTCWKEN; - - if (of_property_read_bool(np, "atmel,wakeup-rtt-timer")) - mode |= AT91_SHDW_RTTWKEN; - - at91_shdwc_write(AT91_SHDW_MR, wakeup_mode | mode); - -end: - pm_power_off = at91sam9_poweroff; - - of_node_put(np); + at91_pm_set_standby(standby); } void __init at91rm9200_dt_initialize(void) @@ -503,9 +383,7 @@ void __init at91rm9200_dt_initialize(void) void __init at91_dt_initialize(void) { - at91_dt_rstc(); at91_dt_ramc(); - at91_dt_shdwc(); /* Init clock subsystem */ at91_dt_clock_init(); @@ -533,3 +411,13 @@ void __init at91_initialize(unsigned long main_clock) pinctrl_provide_dummies(); } + +void __init at91_register_devices(void) +{ + at91_boot_soc.register_devices(); +} + +void __init at91_init_time(void) +{ + at91_boot_soc.init_time(); +} diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index a1e1482c6da..2886b83dd0d 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -11,7 +11,9 @@ struct at91_init_soc { void (*map_io)(void); void (*ioremap_registers)(void); void (*register_clocks)(void); + void (*register_devices)(void); void (*init)(void); + void (*init_time)(void); }; extern struct at91_init_soc at91_boot_soc; |