diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-12-08 05:58:09 -0500 |
---|---|---|
committer | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2015-12-08 07:23:14 -0500 |
commit | c5d431e8c511788556651b91debd7d77d4508f4b (patch) | |
tree | 8461d77d858316f318b35eac78f2187eb5482f76 | |
parent | 67098119abeb596823ed0a74dd8cdcfbee4c2210 (diff) |
ARM: dove: convert legacy dove to PMU support
Since Dove has non-DT support for various facilities in the PMU, convert
the legacy support to use the new PMU driver.
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-dove/common.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-dove/include/mach/pm.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-dove/irq.c | 88 |
4 files changed, 33 insertions, 102 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 473c1417968a..72af9d6f8c13 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -516,6 +516,7 @@ config ARCH_DOVE | |||
516 | select PINCTRL_DOVE | 516 | select PINCTRL_DOVE |
517 | select PLAT_ORION_LEGACY | 517 | select PLAT_ORION_LEGACY |
518 | select SPARSE_IRQ | 518 | select SPARSE_IRQ |
519 | select PM_GENERIC_DOMAINS if PM | ||
519 | help | 520 | help |
520 | Support for the Marvell Dove SoC 88AP510 | 521 | Support for the Marvell Dove SoC 88AP510 |
521 | 522 | ||
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 25a682fd444f..0cdaa3851d2e 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/platform_data/dma-mv_xor.h> | 16 | #include <linux/platform_data/dma-mv_xor.h> |
17 | #include <linux/platform_data/usb-ehci-orion.h> | 17 | #include <linux/platform_data/usb-ehci-orion.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/soc/dove/pmu.h> | ||
19 | #include <asm/hardware/cache-tauros2.h> | 20 | #include <asm/hardware/cache-tauros2.h> |
20 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
21 | #include <asm/mach/map.h> | 22 | #include <asm/mach/map.h> |
@@ -392,6 +393,30 @@ static void __init __maybe_unused orion_wdt_init(void) | |||
392 | platform_device_register(&orion_wdt_device); | 393 | platform_device_register(&orion_wdt_device); |
393 | } | 394 | } |
394 | 395 | ||
396 | static const struct dove_pmu_domain_initdata pmu_domains[] __initconst = { | ||
397 | { | ||
398 | .pwr_mask = PMU_PWR_VPU_PWR_DWN_MASK, | ||
399 | .rst_mask = PMU_SW_RST_VIDEO_MASK, | ||
400 | .iso_mask = PMU_ISO_VIDEO_MASK, | ||
401 | .name = "vpu-domain", | ||
402 | }, { | ||
403 | .pwr_mask = PMU_PWR_GPU_PWR_DWN_MASK, | ||
404 | .rst_mask = PMU_SW_RST_GPU_MASK, | ||
405 | .iso_mask = PMU_ISO_GPU_MASK, | ||
406 | .name = "gpu-domain", | ||
407 | }, { | ||
408 | /* sentinel */ | ||
409 | }, | ||
410 | }; | ||
411 | |||
412 | static const struct dove_pmu_initdata pmu_data __initconst = { | ||
413 | .pmc_base = DOVE_PMU_VIRT_BASE, | ||
414 | .pmu_base = DOVE_PMU_VIRT_BASE + 0x8000, | ||
415 | .irq = IRQ_DOVE_PMU, | ||
416 | .irq_domain_start = IRQ_DOVE_PMU_START, | ||
417 | .domains = pmu_domains, | ||
418 | }; | ||
419 | |||
395 | void __init dove_init(void) | 420 | void __init dove_init(void) |
396 | { | 421 | { |
397 | pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n", | 422 | pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n", |
@@ -406,6 +431,7 @@ void __init dove_init(void) | |||
406 | dove_clk_init(); | 431 | dove_clk_init(); |
407 | 432 | ||
408 | /* internal devices that every board has */ | 433 | /* internal devices that every board has */ |
434 | dove_init_pmu_legacy(&pmu_data); | ||
409 | dove_rtc_init(); | 435 | dove_rtc_init(); |
410 | dove_xor0_init(); | 436 | dove_xor0_init(); |
411 | dove_xor1_init(); | 437 | dove_xor1_init(); |
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h index 9834ba10cd13..d22b9b174007 100644 --- a/arch/arm/mach-dove/include/mach/pm.h +++ b/arch/arm/mach-dove/include/mach/pm.h | |||
@@ -51,22 +51,14 @@ | |||
51 | #define CLOCK_GATING_GIGA_PHY_MASK (1 << CLOCK_GATING_BIT_GIGA_PHY) | 51 | #define CLOCK_GATING_GIGA_PHY_MASK (1 << CLOCK_GATING_BIT_GIGA_PHY) |
52 | 52 | ||
53 | #define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50) | 53 | #define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50) |
54 | #define PMU_INTERRUPT_MASK (DOVE_PMU_VIRT_BASE + 0x54) | ||
55 | 54 | ||
56 | static inline int pmu_to_irq(int pin) | 55 | #define PMU_SW_RST_VIDEO_MASK BIT(16) |
57 | { | 56 | #define PMU_SW_RST_GPU_MASK BIT(18) |
58 | if (pin < NR_PMU_IRQS) | ||
59 | return pin + IRQ_DOVE_PMU_START; | ||
60 | 57 | ||
61 | return -EINVAL; | 58 | #define PMU_PWR_GPU_PWR_DWN_MASK BIT(2) |
62 | } | 59 | #define PMU_PWR_VPU_PWR_DWN_MASK BIT(3) |
63 | 60 | ||
64 | static inline int irq_to_pmu(int irq) | 61 | #define PMU_ISO_VIDEO_MASK BIT(0) |
65 | { | 62 | #define PMU_ISO_GPU_MASK BIT(1) |
66 | if (IRQ_DOVE_PMU_START <= irq && irq < DOVE_NR_IRQS) | ||
67 | return irq - IRQ_DOVE_PMU_START; | ||
68 | |||
69 | return -EINVAL; | ||
70 | } | ||
71 | 63 | ||
72 | #endif | 64 | #endif |
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index ad785d34c1e7..d6627c1f7f30 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c | |||
@@ -7,88 +7,15 @@ | |||
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | 10 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
14 | #include <linux/gpio.h> | ||
15 | #include <linux/io.h> | 12 | #include <linux/io.h> |
16 | #include <asm/exception.h> | 13 | #include <asm/exception.h> |
17 | #include <asm/mach/arch.h> | ||
18 | #include <plat/irq.h> | 14 | #include <plat/irq.h> |
19 | #include <asm/mach/irq.h> | ||
20 | #include <mach/pm.h> | ||
21 | #include <mach/bridge-regs.h> | 15 | #include <mach/bridge-regs.h> |
22 | #include <plat/orion-gpio.h> | 16 | #include <plat/orion-gpio.h> |
23 | #include "common.h" | 17 | #include "common.h" |
24 | 18 | ||
25 | static void pmu_irq_mask(struct irq_data *d) | ||
26 | { | ||
27 | int pin = irq_to_pmu(d->irq); | ||
28 | u32 u; | ||
29 | |||
30 | u = readl(PMU_INTERRUPT_MASK); | ||
31 | u &= ~(1 << (pin & 31)); | ||
32 | writel(u, PMU_INTERRUPT_MASK); | ||
33 | } | ||
34 | |||
35 | static void pmu_irq_unmask(struct irq_data *d) | ||
36 | { | ||
37 | int pin = irq_to_pmu(d->irq); | ||
38 | u32 u; | ||
39 | |||
40 | u = readl(PMU_INTERRUPT_MASK); | ||
41 | u |= 1 << (pin & 31); | ||
42 | writel(u, PMU_INTERRUPT_MASK); | ||
43 | } | ||
44 | |||
45 | static void pmu_irq_ack(struct irq_data *d) | ||
46 | { | ||
47 | int pin = irq_to_pmu(d->irq); | ||
48 | u32 u; | ||
49 | |||
50 | /* | ||
51 | * The PMU mask register is not RW0C: it is RW. This means that | ||
52 | * the bits take whatever value is written to them; if you write | ||
53 | * a '1', you will set the interrupt. | ||
54 | * | ||
55 | * Unfortunately this means there is NO race free way to clear | ||
56 | * these interrupts. | ||
57 | * | ||
58 | * So, let's structure the code so that the window is as small as | ||
59 | * possible. | ||
60 | */ | ||
61 | u = ~(1 << (pin & 31)); | ||
62 | u &= readl_relaxed(PMU_INTERRUPT_CAUSE); | ||
63 | writel_relaxed(u, PMU_INTERRUPT_CAUSE); | ||
64 | } | ||
65 | |||
66 | static struct irq_chip pmu_irq_chip = { | ||
67 | .name = "pmu_irq", | ||
68 | .irq_mask = pmu_irq_mask, | ||
69 | .irq_unmask = pmu_irq_unmask, | ||
70 | .irq_ack = pmu_irq_ack, | ||
71 | }; | ||
72 | |||
73 | static void pmu_irq_handler(struct irq_desc *desc) | ||
74 | { | ||
75 | unsigned long cause = readl(PMU_INTERRUPT_CAUSE); | ||
76 | unsigned int irq; | ||
77 | |||
78 | cause &= readl(PMU_INTERRUPT_MASK); | ||
79 | if (cause == 0) { | ||
80 | do_bad_IRQ(desc); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | for (irq = 0; irq < NR_PMU_IRQS; irq++) { | ||
85 | if (!(cause & (1 << irq))) | ||
86 | continue; | ||
87 | irq = pmu_to_irq(irq); | ||
88 | generic_handle_irq(irq); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | static int __initdata gpio0_irqs[4] = { | 19 | static int __initdata gpio0_irqs[4] = { |
93 | IRQ_DOVE_GPIO_0_7, | 20 | IRQ_DOVE_GPIO_0_7, |
94 | IRQ_DOVE_GPIO_8_15, | 21 | IRQ_DOVE_GPIO_8_15, |
@@ -135,8 +62,6 @@ __exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs) | |||
135 | 62 | ||
136 | void __init dove_init_irq(void) | 63 | void __init dove_init_irq(void) |
137 | { | 64 | { |
138 | int i; | ||
139 | |||
140 | orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); | 65 | orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); |
141 | orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); | 66 | orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); |
142 | 67 | ||
@@ -153,17 +78,4 @@ void __init dove_init_irq(void) | |||
153 | 78 | ||
154 | orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0, | 79 | orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0, |
155 | IRQ_DOVE_GPIO_START + 64, gpio2_irqs); | 80 | IRQ_DOVE_GPIO_START + 64, gpio2_irqs); |
156 | |||
157 | /* | ||
158 | * Mask and clear PMU interrupts | ||
159 | */ | ||
160 | writel(0, PMU_INTERRUPT_MASK); | ||
161 | writel(0, PMU_INTERRUPT_CAUSE); | ||
162 | |||
163 | for (i = IRQ_DOVE_PMU_START; i < DOVE_NR_IRQS; i++) { | ||
164 | irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); | ||
165 | irq_set_status_flags(i, IRQ_LEVEL); | ||
166 | irq_clear_status_flags(i, IRQ_NOREQUEST); | ||
167 | } | ||
168 | irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); | ||
169 | } | 81 | } |