diff options
author | Olof Johansson <olof@lixom.net> | 2013-04-11 06:39:00 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-04-11 06:39:00 -0400 |
commit | b9d5868e342a9802db7b299be511ac547ff1034d (patch) | |
tree | 49c8fe5467b817bcaf2afa6468c2e362f50e4770 | |
parent | 83c15f4c05757b3c5fe1551a474458fd16d27bae (diff) | |
parent | bc34b5f27cd33f4213bc5c8df0099dd11408d29d (diff) |
Merge tag 'sunxi-cleanup-for-3.10' of git://github.com/mripard/linux into next/cleanup
From Maxime Ripard:
Cleanups for Allwinner sunXi architecture:
- Remove sunxi.dtsi
- Switch to clocksource/irqchip device tree handlers
- Cleanup the watchdog code
* tag 'sunxi-cleanup-for-3.10' of git://github.com/mripard/linux:
ARM: sunxi: Rework the restart code
irqchip: sunxi: Rename sunxi to sun4i
irqchip: sunxi: Make use of the IRQCHIP_DECLARE macro
clocksource: sunxi: Rename sunxi to sun4i
clocksource: sunxi: make use of CLKSRC_OF
clocksource: sunxi: Cleanup the timer code
clocksource: make CLOCKSOURCE_OF_DECLARE type safe
Signed-off-by: Olof Johansson <olof@lixom.net>
Add/change conflict in drivers/clocksource/Makefile resolved.
16 files changed, 261 insertions, 299 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt index 7f9fb85f5456..e7f4dc14eff2 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-ic.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt | |||
@@ -2,7 +2,7 @@ Allwinner Sunxi Interrupt Controller | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | 4 | ||
5 | - compatible : should be "allwinner,sunxi-ic" | 5 | - compatible : should be "allwinner,sun4i-ic" |
6 | - reg : Specifies base physical address and size of the registers. | 6 | - reg : Specifies base physical address and size of the registers. |
7 | - interrupt-controller : Identifies the node as an interrupt controller | 7 | - interrupt-controller : Identifies the node as an interrupt controller |
8 | - #interrupt-cells : Specifies the number of cells needed to encode an | 8 | - #interrupt-cells : Specifies the number of cells needed to encode an |
@@ -97,7 +97,7 @@ The interrupt sources are as follows: | |||
97 | Example: | 97 | Example: |
98 | 98 | ||
99 | intc: interrupt-controller { | 99 | intc: interrupt-controller { |
100 | compatible = "allwinner,sunxi-ic"; | 100 | compatible = "allwinner,sun4i-ic"; |
101 | reg = <0x01c20400 0x400>; | 101 | reg = <0x01c20400 0x400>; |
102 | interrupt-controller; | 102 | interrupt-controller; |
103 | #interrupt-cells = <2>; | 103 | #interrupt-cells = <2>; |
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt index 0c7b64e95a61..48aeb7884ed3 100644 --- a/Documentation/devicetree/bindings/timer/allwinner,sunxi-timer.txt +++ b/Documentation/devicetree/bindings/timer/allwinner,sun4i-timer.txt | |||
@@ -2,7 +2,7 @@ Allwinner A1X SoCs Timer Controller | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | 4 | ||
5 | - compatible : should be "allwinner,sunxi-timer" | 5 | - compatible : should be "allwinner,sun4i-timer" |
6 | - reg : Specifies base physical address and size of the registers. | 6 | - reg : Specifies base physical address and size of the registers. |
7 | - interrupts : The interrupt of the first timer | 7 | - interrupts : The interrupt of the first timer |
8 | - clocks: phandle to the source clock (usually a 24 MHz fixed clock) | 8 | - clocks: phandle to the source clock (usually a 24 MHz fixed clock) |
@@ -10,7 +10,7 @@ Required properties: | |||
10 | Example: | 10 | Example: |
11 | 11 | ||
12 | timer { | 12 | timer { |
13 | compatible = "allwinner,sunxi-timer"; | 13 | compatible = "allwinner,sun4i-timer"; |
14 | reg = <0x01c20c00 0x400>; | 14 | reg = <0x01c20c00 0x400>; |
15 | interrupts = <22>; | 15 | interrupts = <22>; |
16 | clocks = <&osc>; | 16 | clocks = <&osc>; |
diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sun4i-wdt.txt index 0b2717775600..ecd650adff31 100644 --- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/sun4i-wdt.txt | |||
@@ -1,13 +1,13 @@ | |||
1 | Allwinner sunXi Watchdog timer | 1 | Allwinner sun4i Watchdog timer |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | 4 | ||
5 | - compatible : should be "allwinner,sunxi-wdt" | 5 | - compatible : should be "allwinner,sun4i-wdt" |
6 | - reg : Specifies base physical address and size of the registers. | 6 | - reg : Specifies base physical address and size of the registers. |
7 | 7 | ||
8 | Example: | 8 | Example: |
9 | 9 | ||
10 | wdt: watchdog@01c20c90 { | 10 | wdt: watchdog@01c20c90 { |
11 | compatible = "allwinner,sunxi-wdt"; | 11 | compatible = "allwinner,sun4i-wdt"; |
12 | reg = <0x01c20c90 0x10>; | 12 | reg = <0x01c20c90 0x10>; |
13 | }; | 13 | }; |
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 8709a39bd34c..d259c782d742 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | config ARCH_SUNXI | 1 | config ARCH_SUNXI |
2 | bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 | 2 | bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 |
3 | select CLKSRC_MMIO | 3 | select CLKSRC_MMIO |
4 | select CLKSRC_OF | ||
4 | select COMMON_CLK | 5 | select COMMON_CLK |
5 | select GENERIC_CLOCKEVENTS | 6 | select GENERIC_CLOCKEVENTS |
6 | select GENERIC_IRQ_CHIP | 7 | select GENERIC_IRQ_CHIP |
7 | select PINCTRL | 8 | select PINCTRL |
8 | select SPARSE_IRQ | 9 | select SPARSE_IRQ |
9 | select SUNXI_TIMER | 10 | select SUN4I_TIMER |
10 | select PINCTRL_SUNXI \ No newline at end of file | 11 | select PINCTRL_SUNXI |
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index 23afb732cb40..706ce35396b8 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c | |||
@@ -10,63 +10,77 @@ | |||
10 | * warranty of any kind, whether express or implied. | 10 | * warranty of any kind, whether express or implied. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/clocksource.h> | ||
13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/irqchip.h> | ||
16 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
17 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
18 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
19 | #include <linux/io.h> | 21 | #include <linux/io.h> |
20 | #include <linux/sunxi_timer.h> | ||
21 | 22 | ||
22 | #include <linux/irqchip/sunxi.h> | 23 | #include <linux/clk/sunxi.h> |
23 | 24 | ||
24 | #include <asm/mach/arch.h> | 25 | #include <asm/mach/arch.h> |
25 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <asm/system_misc.h> | ||
26 | 28 | ||
27 | #include "sunxi.h" | 29 | #include "sunxi.h" |
28 | 30 | ||
29 | #define WATCHDOG_CTRL_REG 0x00 | 31 | #define SUN4I_WATCHDOG_CTRL_REG 0x00 |
30 | #define WATCHDOG_CTRL_RESTART (1 << 0) | 32 | #define SUN4I_WATCHDOG_CTRL_RESTART (1 << 0) |
31 | #define WATCHDOG_MODE_REG 0x04 | 33 | #define SUN4I_WATCHDOG_MODE_REG 0x04 |
32 | #define WATCHDOG_MODE_ENABLE (1 << 0) | 34 | #define SUN4I_WATCHDOG_MODE_ENABLE (1 << 0) |
33 | #define WATCHDOG_MODE_RESET_ENABLE (1 << 1) | 35 | #define SUN4I_WATCHDOG_MODE_RESET_ENABLE (1 << 1) |
34 | 36 | ||
35 | static void __iomem *wdt_base; | 37 | static void __iomem *wdt_base; |
36 | 38 | ||
37 | static void sunxi_setup_restart(void) | 39 | static void sun4i_restart(char mode, const char *cmd) |
38 | { | ||
39 | struct device_node *np = of_find_compatible_node(NULL, NULL, | ||
40 | "allwinner,sunxi-wdt"); | ||
41 | if (WARN(!np, "unable to setup watchdog restart")) | ||
42 | return; | ||
43 | |||
44 | wdt_base = of_iomap(np, 0); | ||
45 | WARN(!wdt_base, "failed to map watchdog base address"); | ||
46 | } | ||
47 | |||
48 | static void sunxi_restart(char mode, const char *cmd) | ||
49 | { | 40 | { |
50 | if (!wdt_base) | 41 | if (!wdt_base) |
51 | return; | 42 | return; |
52 | 43 | ||
53 | /* Enable timer and set reset bit in the watchdog */ | 44 | /* Enable timer and set reset bit in the watchdog */ |
54 | writel(WATCHDOG_MODE_ENABLE | WATCHDOG_MODE_RESET_ENABLE, | 45 | writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE, |
55 | wdt_base + WATCHDOG_MODE_REG); | 46 | wdt_base + SUN4I_WATCHDOG_MODE_REG); |
56 | 47 | ||
57 | /* | 48 | /* |
58 | * Restart the watchdog. The default (and lowest) interval | 49 | * Restart the watchdog. The default (and lowest) interval |
59 | * value for the watchdog is 0.5s. | 50 | * value for the watchdog is 0.5s. |
60 | */ | 51 | */ |
61 | writel(WATCHDOG_CTRL_RESTART, wdt_base + WATCHDOG_CTRL_REG); | 52 | writel(SUN4I_WATCHDOG_CTRL_RESTART, wdt_base + SUN4I_WATCHDOG_CTRL_REG); |
62 | 53 | ||
63 | while (1) { | 54 | while (1) { |
64 | mdelay(5); | 55 | mdelay(5); |
65 | writel(WATCHDOG_MODE_ENABLE | WATCHDOG_MODE_RESET_ENABLE, | 56 | writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE, |
66 | wdt_base + WATCHDOG_MODE_REG); | 57 | wdt_base + SUN4I_WATCHDOG_MODE_REG); |
67 | } | 58 | } |
68 | } | 59 | } |
69 | 60 | ||
61 | static struct of_device_id sunxi_restart_ids[] = { | ||
62 | { .compatible = "allwinner,sun4i-wdt", .data = sun4i_restart }, | ||
63 | { /*sentinel*/ } | ||
64 | }; | ||
65 | |||
66 | static void sunxi_setup_restart(void) | ||
67 | { | ||
68 | const struct of_device_id *of_id; | ||
69 | struct device_node *np; | ||
70 | |||
71 | np = of_find_matching_node(NULL, sunxi_restart_ids); | ||
72 | if (WARN(!np, "unable to setup watchdog restart")) | ||
73 | return; | ||
74 | |||
75 | wdt_base = of_iomap(np, 0); | ||
76 | WARN(!wdt_base, "failed to map watchdog base address"); | ||
77 | |||
78 | of_id = of_match_node(sunxi_restart_ids, np); | ||
79 | WARN(!of_id, "restart function not available"); | ||
80 | |||
81 | arm_pm_restart = of_id->data; | ||
82 | } | ||
83 | |||
70 | static struct map_desc sunxi_io_desc[] __initdata = { | 84 | static struct map_desc sunxi_io_desc[] __initdata = { |
71 | { | 85 | { |
72 | .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE, | 86 | .virtual = (unsigned long) SUNXI_REGS_VIRT_BASE, |
@@ -81,6 +95,12 @@ void __init sunxi_map_io(void) | |||
81 | iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc)); | 95 | iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc)); |
82 | } | 96 | } |
83 | 97 | ||
98 | static void __init sunxi_timer_init(void) | ||
99 | { | ||
100 | sunxi_init_clocks(); | ||
101 | clocksource_of_init(); | ||
102 | } | ||
103 | |||
84 | static void __init sunxi_dt_init(void) | 104 | static void __init sunxi_dt_init(void) |
85 | { | 105 | { |
86 | sunxi_setup_restart(); | 106 | sunxi_setup_restart(); |
@@ -97,9 +117,7 @@ static const char * const sunxi_board_dt_compat[] = { | |||
97 | DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") | 117 | DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") |
98 | .init_machine = sunxi_dt_init, | 118 | .init_machine = sunxi_dt_init, |
99 | .map_io = sunxi_map_io, | 119 | .map_io = sunxi_map_io, |
100 | .init_irq = sunxi_init_irq, | 120 | .init_irq = irqchip_init, |
101 | .handle_irq = sunxi_handle_irq, | 121 | .init_time = sunxi_timer_init, |
102 | .restart = sunxi_restart, | ||
103 | .init_time = &sunxi_timer_init, | ||
104 | .dt_compat = sunxi_board_dt_compat, | 122 | .dt_compat = sunxi_board_dt_compat, |
105 | MACHINE_END | 123 | MACHINE_END |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index e507ab7df60b..9002185a0a1a 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -25,7 +25,7 @@ config DW_APB_TIMER_OF | |||
25 | config ARMADA_370_XP_TIMER | 25 | config ARMADA_370_XP_TIMER |
26 | bool | 26 | bool |
27 | 27 | ||
28 | config SUNXI_TIMER | 28 | config SUN4I_TIMER |
29 | bool | 29 | bool |
30 | 30 | ||
31 | config VT8500_TIMER | 31 | config VT8500_TIMER |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 89c5adc498b3..98f220a7a92c 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -17,7 +17,7 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | |||
17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 18 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o |
19 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o | 19 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o |
20 | obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o | 20 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o |
21 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o | 21 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o |
22 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 22 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
23 | 23 | ||
diff --git a/drivers/clocksource/clksrc-of.c b/drivers/clocksource/clksrc-of.c index 3ef11fba781c..37f5325bec95 100644 --- a/drivers/clocksource/clksrc-of.c +++ b/drivers/clocksource/clksrc-of.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/clocksource.h> | ||
19 | 20 | ||
20 | extern struct of_device_id __clksrc_of_table[]; | 21 | extern struct of_device_id __clksrc_of_table[]; |
21 | 22 | ||
@@ -26,7 +27,7 @@ void __init clocksource_of_init(void) | |||
26 | { | 27 | { |
27 | struct device_node *np; | 28 | struct device_node *np; |
28 | const struct of_device_id *match; | 29 | const struct of_device_id *match; |
29 | void (*init_func)(struct device_node *); | 30 | clocksource_of_init_fn init_func; |
30 | 31 | ||
31 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { | 32 | for_each_matching_node_and_match(np, __clksrc_of_table, &match) { |
32 | init_func = match->data; | 33 | init_func = match->data; |
diff --git a/drivers/clocksource/sunxi_timer.c b/drivers/clocksource/sun4i_timer.c index 0ce85e29769b..d4674e78ef35 100644 --- a/drivers/clocksource/sunxi_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
@@ -22,66 +22,64 @@ | |||
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
25 | #include <linux/sunxi_timer.h> | ||
26 | #include <linux/clk/sunxi.h> | ||
27 | 25 | ||
28 | #define TIMER_CTL_REG 0x00 | 26 | #define TIMER_IRQ_EN_REG 0x00 |
29 | #define TIMER_CTL_ENABLE (1 << 0) | 27 | #define TIMER_IRQ_EN(val) (1 << val) |
30 | #define TIMER_IRQ_ST_REG 0x04 | 28 | #define TIMER_IRQ_ST_REG 0x04 |
31 | #define TIMER0_CTL_REG 0x10 | 29 | #define TIMER_CTL_REG(val) (0x10 * val + 0x10) |
32 | #define TIMER0_CTL_ENABLE (1 << 0) | 30 | #define TIMER_CTL_ENABLE (1 << 0) |
33 | #define TIMER0_CTL_AUTORELOAD (1 << 1) | 31 | #define TIMER_CTL_AUTORELOAD (1 << 1) |
34 | #define TIMER0_CTL_ONESHOT (1 << 7) | 32 | #define TIMER_CTL_ONESHOT (1 << 7) |
35 | #define TIMER0_INTVAL_REG 0x14 | 33 | #define TIMER_INTVAL_REG(val) (0x10 * val + 0x14) |
36 | #define TIMER0_CNTVAL_REG 0x18 | 34 | #define TIMER_CNTVAL_REG(val) (0x10 * val + 0x18) |
37 | 35 | ||
38 | #define TIMER_SCAL 16 | 36 | #define TIMER_SCAL 16 |
39 | 37 | ||
40 | static void __iomem *timer_base; | 38 | static void __iomem *timer_base; |
41 | 39 | ||
42 | static void sunxi_clkevt_mode(enum clock_event_mode mode, | 40 | static void sun4i_clkevt_mode(enum clock_event_mode mode, |
43 | struct clock_event_device *clk) | 41 | struct clock_event_device *clk) |
44 | { | 42 | { |
45 | u32 u = readl(timer_base + TIMER0_CTL_REG); | 43 | u32 u = readl(timer_base + TIMER_CTL_REG(0)); |
46 | 44 | ||
47 | switch (mode) { | 45 | switch (mode) { |
48 | case CLOCK_EVT_MODE_PERIODIC: | 46 | case CLOCK_EVT_MODE_PERIODIC: |
49 | u &= ~(TIMER0_CTL_ONESHOT); | 47 | u &= ~(TIMER_CTL_ONESHOT); |
50 | writel(u | TIMER0_CTL_ENABLE, timer_base + TIMER0_CTL_REG); | 48 | writel(u | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(0)); |
51 | break; | 49 | break; |
52 | 50 | ||
53 | case CLOCK_EVT_MODE_ONESHOT: | 51 | case CLOCK_EVT_MODE_ONESHOT: |
54 | writel(u | TIMER0_CTL_ONESHOT, timer_base + TIMER0_CTL_REG); | 52 | writel(u | TIMER_CTL_ONESHOT, timer_base + TIMER_CTL_REG(0)); |
55 | break; | 53 | break; |
56 | case CLOCK_EVT_MODE_UNUSED: | 54 | case CLOCK_EVT_MODE_UNUSED: |
57 | case CLOCK_EVT_MODE_SHUTDOWN: | 55 | case CLOCK_EVT_MODE_SHUTDOWN: |
58 | default: | 56 | default: |
59 | writel(u & ~(TIMER0_CTL_ENABLE), timer_base + TIMER0_CTL_REG); | 57 | writel(u & ~(TIMER_CTL_ENABLE), timer_base + TIMER_CTL_REG(0)); |
60 | break; | 58 | break; |
61 | } | 59 | } |
62 | } | 60 | } |
63 | 61 | ||
64 | static int sunxi_clkevt_next_event(unsigned long evt, | 62 | static int sun4i_clkevt_next_event(unsigned long evt, |
65 | struct clock_event_device *unused) | 63 | struct clock_event_device *unused) |
66 | { | 64 | { |
67 | u32 u = readl(timer_base + TIMER0_CTL_REG); | 65 | u32 u = readl(timer_base + TIMER_CTL_REG(0)); |
68 | writel(evt, timer_base + TIMER0_CNTVAL_REG); | 66 | writel(evt, timer_base + TIMER_CNTVAL_REG(0)); |
69 | writel(u | TIMER0_CTL_ENABLE | TIMER0_CTL_AUTORELOAD, | 67 | writel(u | TIMER_CTL_ENABLE | TIMER_CTL_AUTORELOAD, |
70 | timer_base + TIMER0_CTL_REG); | 68 | timer_base + TIMER_CTL_REG(0)); |
71 | 69 | ||
72 | return 0; | 70 | return 0; |
73 | } | 71 | } |
74 | 72 | ||
75 | static struct clock_event_device sunxi_clockevent = { | 73 | static struct clock_event_device sun4i_clockevent = { |
76 | .name = "sunxi_tick", | 74 | .name = "sun4i_tick", |
77 | .rating = 300, | 75 | .rating = 300, |
78 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 76 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
79 | .set_mode = sunxi_clkevt_mode, | 77 | .set_mode = sun4i_clkevt_mode, |
80 | .set_next_event = sunxi_clkevt_next_event, | 78 | .set_next_event = sun4i_clkevt_next_event, |
81 | }; | 79 | }; |
82 | 80 | ||
83 | 81 | ||
84 | static irqreturn_t sunxi_timer_interrupt(int irq, void *dev_id) | 82 | static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) |
85 | { | 83 | { |
86 | struct clock_event_device *evt = (struct clock_event_device *)dev_id; | 84 | struct clock_event_device *evt = (struct clock_event_device *)dev_id; |
87 | 85 | ||
@@ -91,30 +89,20 @@ static irqreturn_t sunxi_timer_interrupt(int irq, void *dev_id) | |||
91 | return IRQ_HANDLED; | 89 | return IRQ_HANDLED; |
92 | } | 90 | } |
93 | 91 | ||
94 | static struct irqaction sunxi_timer_irq = { | 92 | static struct irqaction sun4i_timer_irq = { |
95 | .name = "sunxi_timer0", | 93 | .name = "sun4i_timer0", |
96 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 94 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
97 | .handler = sunxi_timer_interrupt, | 95 | .handler = sun4i_timer_interrupt, |
98 | .dev_id = &sunxi_clockevent, | 96 | .dev_id = &sun4i_clockevent, |
99 | }; | ||
100 | |||
101 | static struct of_device_id sunxi_timer_dt_ids[] = { | ||
102 | { .compatible = "allwinner,sunxi-timer" }, | ||
103 | { } | ||
104 | }; | 97 | }; |
105 | 98 | ||
106 | void __init sunxi_timer_init(void) | 99 | static void __init sun4i_timer_init(struct device_node *node) |
107 | { | 100 | { |
108 | struct device_node *node; | ||
109 | unsigned long rate = 0; | 101 | unsigned long rate = 0; |
110 | struct clk *clk; | 102 | struct clk *clk; |
111 | int ret, irq; | 103 | int ret, irq; |
112 | u32 val; | 104 | u32 val; |
113 | 105 | ||
114 | node = of_find_matching_node(NULL, sunxi_timer_dt_ids); | ||
115 | if (!node) | ||
116 | panic("No sunxi timer node"); | ||
117 | |||
118 | timer_base = of_iomap(node, 0); | 106 | timer_base = of_iomap(node, 0); |
119 | if (!timer_base) | 107 | if (!timer_base) |
120 | panic("Can't map registers"); | 108 | panic("Can't map registers"); |
@@ -123,8 +111,6 @@ void __init sunxi_timer_init(void) | |||
123 | if (irq <= 0) | 111 | if (irq <= 0) |
124 | panic("Can't parse IRQ"); | 112 | panic("Can't parse IRQ"); |
125 | 113 | ||
126 | sunxi_init_clocks(); | ||
127 | |||
128 | clk = of_clk_get(node, 0); | 114 | clk = of_clk_get(node, 0); |
129 | if (IS_ERR(clk)) | 115 | if (IS_ERR(clk)) |
130 | panic("Can't get timer clock"); | 116 | panic("Can't get timer clock"); |
@@ -132,29 +118,31 @@ void __init sunxi_timer_init(void) | |||
132 | rate = clk_get_rate(clk); | 118 | rate = clk_get_rate(clk); |
133 | 119 | ||
134 | writel(rate / (TIMER_SCAL * HZ), | 120 | writel(rate / (TIMER_SCAL * HZ), |
135 | timer_base + TIMER0_INTVAL_REG); | 121 | timer_base + TIMER_INTVAL_REG(0)); |
136 | 122 | ||
137 | /* set clock source to HOSC, 16 pre-division */ | 123 | /* set clock source to HOSC, 16 pre-division */ |
138 | val = readl(timer_base + TIMER0_CTL_REG); | 124 | val = readl(timer_base + TIMER_CTL_REG(0)); |
139 | val &= ~(0x07 << 4); | 125 | val &= ~(0x07 << 4); |
140 | val &= ~(0x03 << 2); | 126 | val &= ~(0x03 << 2); |
141 | val |= (4 << 4) | (1 << 2); | 127 | val |= (4 << 4) | (1 << 2); |
142 | writel(val, timer_base + TIMER0_CTL_REG); | 128 | writel(val, timer_base + TIMER_CTL_REG(0)); |
143 | 129 | ||
144 | /* set mode to auto reload */ | 130 | /* set mode to auto reload */ |
145 | val = readl(timer_base + TIMER0_CTL_REG); | 131 | val = readl(timer_base + TIMER_CTL_REG(0)); |
146 | writel(val | TIMER0_CTL_AUTORELOAD, timer_base + TIMER0_CTL_REG); | 132 | writel(val | TIMER_CTL_AUTORELOAD, timer_base + TIMER_CTL_REG(0)); |
147 | 133 | ||
148 | ret = setup_irq(irq, &sunxi_timer_irq); | 134 | ret = setup_irq(irq, &sun4i_timer_irq); |
149 | if (ret) | 135 | if (ret) |
150 | pr_warn("failed to setup irq %d\n", irq); | 136 | pr_warn("failed to setup irq %d\n", irq); |
151 | 137 | ||
152 | /* Enable timer0 interrupt */ | 138 | /* Enable timer0 interrupt */ |
153 | val = readl(timer_base + TIMER_CTL_REG); | 139 | val = readl(timer_base + TIMER_IRQ_EN_REG); |
154 | writel(val | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG); | 140 | writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG); |
155 | 141 | ||
156 | sunxi_clockevent.cpumask = cpumask_of(0); | 142 | sun4i_clockevent.cpumask = cpumask_of(0); |
157 | 143 | ||
158 | clockevents_config_and_register(&sunxi_clockevent, rate / TIMER_SCAL, | 144 | clockevents_config_and_register(&sun4i_clockevent, rate / TIMER_SCAL, |
159 | 0x1, 0xff); | 145 | 0x1, 0xff); |
160 | } | 146 | } |
147 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer", | ||
148 | sun4i_timer_init); | ||
diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c index 242255285597..64f553f04fa4 100644 --- a/drivers/clocksource/vt8500_timer.c +++ b/drivers/clocksource/vt8500_timer.c | |||
@@ -165,4 +165,4 @@ static void __init vt8500_timer_init(struct device_node *np) | |||
165 | 4, 0xf0000000); | 165 | 4, 0xf0000000); |
166 | } | 166 | } |
167 | 167 | ||
168 | CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init) | 168 | CLOCKSOURCE_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 9d8f4f1c6e39..d5e119ca9425 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -5,7 +5,7 @@ obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o | |||
5 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o | 5 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o |
6 | obj-$(CONFIG_METAG) += irq-metag-ext.o | 6 | obj-$(CONFIG_METAG) += irq-metag-ext.o |
7 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o | 7 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o |
8 | obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o | 8 | obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o |
9 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o | 9 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o |
10 | obj-$(CONFIG_ARM_GIC) += irq-gic.o | 10 | obj-$(CONFIG_ARM_GIC) += irq-gic.o |
11 | obj-$(CONFIG_ARM_VIC) += irq-vic.o | 11 | obj-$(CONFIG_ARM_VIC) += irq-vic.o |
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c new file mode 100644 index 000000000000..b66d4ae06898 --- /dev/null +++ b/drivers/irqchip/irq-sun4i.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Allwinner A1X SoCs IRQ chip driver. | ||
3 | * | ||
4 | * Copyright (C) 2012 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * Based on code from | ||
9 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> | ||
10 | * Benn Huang <benn@allwinnertech.com> | ||
11 | * | ||
12 | * This file is licensed under the terms of the GNU General Public | ||
13 | * License version 2. This program is licensed "as is" without any | ||
14 | * warranty of any kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | |||
23 | #include <asm/exception.h> | ||
24 | #include <asm/mach/irq.h> | ||
25 | |||
26 | #include "irqchip.h" | ||
27 | |||
28 | #define SUN4I_IRQ_VECTOR_REG 0x00 | ||
29 | #define SUN4I_IRQ_PROTECTION_REG 0x08 | ||
30 | #define SUN4I_IRQ_NMI_CTRL_REG 0x0c | ||
31 | #define SUN4I_IRQ_PENDING_REG(x) (0x10 + 0x4 * x) | ||
32 | #define SUN4I_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x) | ||
33 | #define SUN4I_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x) | ||
34 | #define SUN4I_IRQ_MASK_REG(x) (0x50 + 0x4 * x) | ||
35 | |||
36 | static void __iomem *sun4i_irq_base; | ||
37 | static struct irq_domain *sun4i_irq_domain; | ||
38 | |||
39 | static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs); | ||
40 | |||
41 | void sun4i_irq_ack(struct irq_data *irqd) | ||
42 | { | ||
43 | unsigned int irq = irqd_to_hwirq(irqd); | ||
44 | unsigned int irq_off = irq % 32; | ||
45 | int reg = irq / 32; | ||
46 | u32 val; | ||
47 | |||
48 | val = readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); | ||
49 | writel(val | (1 << irq_off), | ||
50 | sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); | ||
51 | } | ||
52 | |||
53 | static void sun4i_irq_mask(struct irq_data *irqd) | ||
54 | { | ||
55 | unsigned int irq = irqd_to_hwirq(irqd); | ||
56 | unsigned int irq_off = irq % 32; | ||
57 | int reg = irq / 32; | ||
58 | u32 val; | ||
59 | |||
60 | val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); | ||
61 | writel(val & ~(1 << irq_off), | ||
62 | sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); | ||
63 | } | ||
64 | |||
65 | static void sun4i_irq_unmask(struct irq_data *irqd) | ||
66 | { | ||
67 | unsigned int irq = irqd_to_hwirq(irqd); | ||
68 | unsigned int irq_off = irq % 32; | ||
69 | int reg = irq / 32; | ||
70 | u32 val; | ||
71 | |||
72 | val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); | ||
73 | writel(val | (1 << irq_off), | ||
74 | sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg)); | ||
75 | } | ||
76 | |||
77 | static struct irq_chip sun4i_irq_chip = { | ||
78 | .name = "sun4i_irq", | ||
79 | .irq_ack = sun4i_irq_ack, | ||
80 | .irq_mask = sun4i_irq_mask, | ||
81 | .irq_unmask = sun4i_irq_unmask, | ||
82 | }; | ||
83 | |||
84 | static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, | ||
85 | irq_hw_number_t hw) | ||
86 | { | ||
87 | irq_set_chip_and_handler(virq, &sun4i_irq_chip, | ||
88 | handle_level_irq); | ||
89 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static struct irq_domain_ops sun4i_irq_ops = { | ||
95 | .map = sun4i_irq_map, | ||
96 | .xlate = irq_domain_xlate_onecell, | ||
97 | }; | ||
98 | |||
99 | static int __init sun4i_of_init(struct device_node *node, | ||
100 | struct device_node *parent) | ||
101 | { | ||
102 | sun4i_irq_base = of_iomap(node, 0); | ||
103 | if (!sun4i_irq_base) | ||
104 | panic("%s: unable to map IC registers\n", | ||
105 | node->full_name); | ||
106 | |||
107 | /* Disable all interrupts */ | ||
108 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(0)); | ||
109 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1)); | ||
110 | writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2)); | ||
111 | |||
112 | /* Mask all the interrupts */ | ||
113 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0)); | ||
114 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1)); | ||
115 | writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2)); | ||
116 | |||
117 | /* Clear all the pending interrupts */ | ||
118 | writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)); | ||
119 | writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(1)); | ||
120 | writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(2)); | ||
121 | |||
122 | /* Enable protection mode */ | ||
123 | writel(0x01, sun4i_irq_base + SUN4I_IRQ_PROTECTION_REG); | ||
124 | |||
125 | /* Configure the external interrupt source type */ | ||
126 | writel(0x00, sun4i_irq_base + SUN4I_IRQ_NMI_CTRL_REG); | ||
127 | |||
128 | sun4i_irq_domain = irq_domain_add_linear(node, 3 * 32, | ||
129 | &sun4i_irq_ops, NULL); | ||
130 | if (!sun4i_irq_domain) | ||
131 | panic("%s: unable to create IRQ domain\n", node->full_name); | ||
132 | |||
133 | set_handle_irq(sun4i_handle_irq); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-ic", sun4i_of_init); | ||
138 | |||
139 | static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs) | ||
140 | { | ||
141 | u32 irq, hwirq; | ||
142 | |||
143 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; | ||
144 | while (hwirq != 0) { | ||
145 | irq = irq_find_mapping(sun4i_irq_domain, hwirq); | ||
146 | handle_IRQ(irq, regs); | ||
147 | hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; | ||
148 | } | ||
149 | } | ||
diff --git a/drivers/irqchip/irq-sunxi.c b/drivers/irqchip/irq-sunxi.c deleted file mode 100644 index 10974fa42653..000000000000 --- a/drivers/irqchip/irq-sunxi.c +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* | ||
2 | * Allwinner A1X SoCs IRQ chip driver. | ||
3 | * | ||
4 | * Copyright (C) 2012 Maxime Ripard | ||
5 | * | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * Based on code from | ||
9 | * Allwinner Technology Co., Ltd. <www.allwinnertech.com> | ||
10 | * Benn Huang <benn@allwinnertech.com> | ||
11 | * | ||
12 | * This file is licensed under the terms of the GNU General Public | ||
13 | * License version 2. This program is licensed "as is" without any | ||
14 | * warranty of any kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | #include <linux/io.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | |||
23 | #include <linux/irqchip/sunxi.h> | ||
24 | |||
25 | #define SUNXI_IRQ_VECTOR_REG 0x00 | ||
26 | #define SUNXI_IRQ_PROTECTION_REG 0x08 | ||
27 | #define SUNXI_IRQ_NMI_CTRL_REG 0x0c | ||
28 | #define SUNXI_IRQ_PENDING_REG(x) (0x10 + 0x4 * x) | ||
29 | #define SUNXI_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x) | ||
30 | #define SUNXI_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x) | ||
31 | #define SUNXI_IRQ_MASK_REG(x) (0x50 + 0x4 * x) | ||
32 | |||
33 | static void __iomem *sunxi_irq_base; | ||
34 | static struct irq_domain *sunxi_irq_domain; | ||
35 | |||
36 | void sunxi_irq_ack(struct irq_data *irqd) | ||
37 | { | ||
38 | unsigned int irq = irqd_to_hwirq(irqd); | ||
39 | unsigned int irq_off = irq % 32; | ||
40 | int reg = irq / 32; | ||
41 | u32 val; | ||
42 | |||
43 | val = readl(sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); | ||
44 | writel(val | (1 << irq_off), | ||
45 | sunxi_irq_base + SUNXI_IRQ_PENDING_REG(reg)); | ||
46 | } | ||
47 | |||
48 | static void sunxi_irq_mask(struct irq_data *irqd) | ||
49 | { | ||
50 | unsigned int irq = irqd_to_hwirq(irqd); | ||
51 | unsigned int irq_off = irq % 32; | ||
52 | int reg = irq / 32; | ||
53 | u32 val; | ||
54 | |||
55 | val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); | ||
56 | writel(val & ~(1 << irq_off), | ||
57 | sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); | ||
58 | } | ||
59 | |||
60 | static void sunxi_irq_unmask(struct irq_data *irqd) | ||
61 | { | ||
62 | unsigned int irq = irqd_to_hwirq(irqd); | ||
63 | unsigned int irq_off = irq % 32; | ||
64 | int reg = irq / 32; | ||
65 | u32 val; | ||
66 | |||
67 | val = readl(sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); | ||
68 | writel(val | (1 << irq_off), | ||
69 | sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(reg)); | ||
70 | } | ||
71 | |||
72 | static struct irq_chip sunxi_irq_chip = { | ||
73 | .name = "sunxi_irq", | ||
74 | .irq_ack = sunxi_irq_ack, | ||
75 | .irq_mask = sunxi_irq_mask, | ||
76 | .irq_unmask = sunxi_irq_unmask, | ||
77 | }; | ||
78 | |||
79 | static int sunxi_irq_map(struct irq_domain *d, unsigned int virq, | ||
80 | irq_hw_number_t hw) | ||
81 | { | ||
82 | irq_set_chip_and_handler(virq, &sunxi_irq_chip, | ||
83 | handle_level_irq); | ||
84 | set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static struct irq_domain_ops sunxi_irq_ops = { | ||
90 | .map = sunxi_irq_map, | ||
91 | .xlate = irq_domain_xlate_onecell, | ||
92 | }; | ||
93 | |||
94 | static int __init sunxi_of_init(struct device_node *node, | ||
95 | struct device_node *parent) | ||
96 | { | ||
97 | sunxi_irq_base = of_iomap(node, 0); | ||
98 | if (!sunxi_irq_base) | ||
99 | panic("%s: unable to map IC registers\n", | ||
100 | node->full_name); | ||
101 | |||
102 | /* Disable all interrupts */ | ||
103 | writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(0)); | ||
104 | writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(1)); | ||
105 | writel(0, sunxi_irq_base + SUNXI_IRQ_ENABLE_REG(2)); | ||
106 | |||
107 | /* Mask all the interrupts */ | ||
108 | writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(0)); | ||
109 | writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(1)); | ||
110 | writel(0, sunxi_irq_base + SUNXI_IRQ_MASK_REG(2)); | ||
111 | |||
112 | /* Clear all the pending interrupts */ | ||
113 | writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(0)); | ||
114 | writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(1)); | ||
115 | writel(0xffffffff, sunxi_irq_base + SUNXI_IRQ_PENDING_REG(2)); | ||
116 | |||
117 | /* Enable protection mode */ | ||
118 | writel(0x01, sunxi_irq_base + SUNXI_IRQ_PROTECTION_REG); | ||
119 | |||
120 | /* Configure the external interrupt source type */ | ||
121 | writel(0x00, sunxi_irq_base + SUNXI_IRQ_NMI_CTRL_REG); | ||
122 | |||
123 | sunxi_irq_domain = irq_domain_add_linear(node, 3 * 32, | ||
124 | &sunxi_irq_ops, NULL); | ||
125 | if (!sunxi_irq_domain) | ||
126 | panic("%s: unable to create IRQ domain\n", node->full_name); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static struct of_device_id sunxi_irq_dt_ids[] __initconst = { | ||
132 | { .compatible = "allwinner,sunxi-ic", .data = sunxi_of_init }, | ||
133 | { } | ||
134 | }; | ||
135 | |||
136 | void __init sunxi_init_irq(void) | ||
137 | { | ||
138 | of_irq_init(sunxi_irq_dt_ids); | ||
139 | } | ||
140 | |||
141 | asmlinkage void __exception_irq_entry sunxi_handle_irq(struct pt_regs *regs) | ||
142 | { | ||
143 | u32 irq, hwirq; | ||
144 | |||
145 | hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; | ||
146 | while (hwirq != 0) { | ||
147 | irq = irq_find_mapping(sunxi_irq_domain, hwirq); | ||
148 | handle_IRQ(irq, regs); | ||
149 | hwirq = readl(sunxi_irq_base + SUNXI_IRQ_VECTOR_REG) >> 2; | ||
150 | } | ||
151 | } | ||
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 08ed5e19d8c6..192d6d1771ee 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -332,16 +332,23 @@ extern int clocksource_mmio_init(void __iomem *, const char *, | |||
332 | 332 | ||
333 | extern int clocksource_i8253_init(void); | 333 | extern int clocksource_i8253_init(void); |
334 | 334 | ||
335 | struct device_node; | ||
336 | typedef void(*clocksource_of_init_fn)(struct device_node *); | ||
335 | #ifdef CONFIG_CLKSRC_OF | 337 | #ifdef CONFIG_CLKSRC_OF |
336 | extern void clocksource_of_init(void); | 338 | extern void clocksource_of_init(void); |
337 | 339 | ||
338 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ | 340 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ |
339 | static const struct of_device_id __clksrc_of_table_##name \ | 341 | static const struct of_device_id __clksrc_of_table_##name \ |
340 | __used __section(__clksrc_of_table) \ | 342 | __used __section(__clksrc_of_table) \ |
341 | = { .compatible = compat, .data = fn }; | 343 | = { .compatible = compat, \ |
344 | .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } | ||
342 | #else | 345 | #else |
343 | static inline void clocksource_of_init(void) {} | 346 | static inline void clocksource_of_init(void) {} |
344 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) | 347 | #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ |
348 | static const struct of_device_id __clksrc_of_table_##name \ | ||
349 | __attribute__((unused)) \ | ||
350 | = { .compatible = compat, \ | ||
351 | .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } | ||
345 | #endif | 352 | #endif |
346 | 353 | ||
347 | #endif /* _LINUX_CLOCKSOURCE_H */ | 354 | #endif /* _LINUX_CLOCKSOURCE_H */ |
diff --git a/include/linux/irqchip/sunxi.h b/include/linux/irqchip/sunxi.h deleted file mode 100644 index 1fe2c2260e2b..000000000000 --- a/include/linux/irqchip/sunxi.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef __LINUX_IRQCHIP_SUNXI_H | ||
18 | #define __LINUX_IRQCHIP_SUNXI_H | ||
19 | |||
20 | #include <asm/exception.h> | ||
21 | |||
22 | extern void sunxi_init_irq(void); | ||
23 | |||
24 | extern asmlinkage void __exception_irq_entry sunxi_handle_irq( | ||
25 | struct pt_regs *regs); | ||
26 | |||
27 | #endif | ||
diff --git a/include/linux/sunxi_timer.h b/include/linux/sunxi_timer.h deleted file mode 100644 index 18081787e5f3..000000000000 --- a/include/linux/sunxi_timer.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef __SUNXI_TIMER_H | ||
18 | #define __SUNXI_TIMER_H | ||
19 | |||
20 | #include <asm/mach/time.h> | ||
21 | |||
22 | void sunxi_timer_init(void); | ||
23 | |||
24 | #endif | ||