diff options
Diffstat (limited to 'arch/arm/mach-dove')
-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 |
3 files changed, 32 insertions, 102 deletions
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 @@ #include <linux/platform_data/dma-mv_xor.h> #include <linux/platform_data/usb-ehci-orion.h> #include <linux/platform_device.h> +#include <linux/soc/dove/pmu.h> #include <asm/hardware/cache-tauros2.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -392,6 +393,30 @@ static void __init __maybe_unused orion_wdt_init(void) platform_device_register(&orion_wdt_device); } +static const struct dove_pmu_domain_initdata pmu_domains[] __initconst = { + { + .pwr_mask = PMU_PWR_VPU_PWR_DWN_MASK, + .rst_mask = PMU_SW_RST_VIDEO_MASK, + .iso_mask = PMU_ISO_VIDEO_MASK, + .name = "vpu-domain", + }, { + .pwr_mask = PMU_PWR_GPU_PWR_DWN_MASK, + .rst_mask = PMU_SW_RST_GPU_MASK, + .iso_mask = PMU_ISO_GPU_MASK, + .name = "gpu-domain", + }, { + /* sentinel */ + }, +}; + +static const struct dove_pmu_initdata pmu_data __initconst = { + .pmc_base = DOVE_PMU_VIRT_BASE, + .pmu_base = DOVE_PMU_VIRT_BASE + 0x8000, + .irq = IRQ_DOVE_PMU, + .irq_domain_start = IRQ_DOVE_PMU_START, + .domains = pmu_domains, +}; + void __init dove_init(void) { pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n", @@ -406,6 +431,7 @@ void __init dove_init(void) dove_clk_init(); /* internal devices that every board has */ + dove_init_pmu_legacy(&pmu_data); dove_rtc_init(); dove_xor0_init(); 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 @@ #define CLOCK_GATING_GIGA_PHY_MASK (1 << CLOCK_GATING_BIT_GIGA_PHY) #define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50) -#define PMU_INTERRUPT_MASK (DOVE_PMU_VIRT_BASE + 0x54) -static inline int pmu_to_irq(int pin) -{ - if (pin < NR_PMU_IRQS) - return pin + IRQ_DOVE_PMU_START; +#define PMU_SW_RST_VIDEO_MASK BIT(16) +#define PMU_SW_RST_GPU_MASK BIT(18) - return -EINVAL; -} +#define PMU_PWR_GPU_PWR_DWN_MASK BIT(2) +#define PMU_PWR_VPU_PWR_DWN_MASK BIT(3) -static inline int irq_to_pmu(int irq) -{ - if (IRQ_DOVE_PMU_START <= irq && irq < DOVE_NR_IRQS) - return irq - IRQ_DOVE_PMU_START; - - return -EINVAL; -} +#define PMU_ISO_VIDEO_MASK BIT(0) +#define PMU_ISO_GPU_MASK BIT(1) #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 @@ * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ - -#include <linux/kernel.h> #include <linux/init.h> #include <linux/irq.h> -#include <linux/gpio.h> #include <linux/io.h> #include <asm/exception.h> -#include <asm/mach/arch.h> #include <plat/irq.h> -#include <asm/mach/irq.h> -#include <mach/pm.h> #include <mach/bridge-regs.h> #include <plat/orion-gpio.h> #include "common.h" -static void pmu_irq_mask(struct irq_data *d) -{ - int pin = irq_to_pmu(d->irq); - u32 u; - - u = readl(PMU_INTERRUPT_MASK); - u &= ~(1 << (pin & 31)); - writel(u, PMU_INTERRUPT_MASK); -} - -static void pmu_irq_unmask(struct irq_data *d) -{ - int pin = irq_to_pmu(d->irq); - u32 u; - - u = readl(PMU_INTERRUPT_MASK); - u |= 1 << (pin & 31); - writel(u, PMU_INTERRUPT_MASK); -} - -static void pmu_irq_ack(struct irq_data *d) -{ - int pin = irq_to_pmu(d->irq); - u32 u; - - /* - * The PMU mask register is not RW0C: it is RW. This means that - * the bits take whatever value is written to them; if you write - * a '1', you will set the interrupt. - * - * Unfortunately this means there is NO race free way to clear - * these interrupts. - * - * So, let's structure the code so that the window is as small as - * possible. - */ - u = ~(1 << (pin & 31)); - u &= readl_relaxed(PMU_INTERRUPT_CAUSE); - writel_relaxed(u, PMU_INTERRUPT_CAUSE); -} - -static struct irq_chip pmu_irq_chip = { - .name = "pmu_irq", - .irq_mask = pmu_irq_mask, - .irq_unmask = pmu_irq_unmask, - .irq_ack = pmu_irq_ack, -}; - -static void pmu_irq_handler(struct irq_desc *desc) -{ - unsigned long cause = readl(PMU_INTERRUPT_CAUSE); - unsigned int irq; - - cause &= readl(PMU_INTERRUPT_MASK); - if (cause == 0) { - do_bad_IRQ(desc); - return; - } - - for (irq = 0; irq < NR_PMU_IRQS; irq++) { - if (!(cause & (1 << irq))) - continue; - irq = pmu_to_irq(irq); - generic_handle_irq(irq); - } -} - static int __initdata gpio0_irqs[4] = { IRQ_DOVE_GPIO_0_7, IRQ_DOVE_GPIO_8_15, @@ -135,8 +62,6 @@ __exception_irq_entry dove_legacy_handle_irq(struct pt_regs *regs) void __init dove_init_irq(void) { - int i; - orion_irq_init(1, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); orion_irq_init(33, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); @@ -153,17 +78,4 @@ void __init dove_init_irq(void) orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0, IRQ_DOVE_GPIO_START + 64, gpio2_irqs); - - /* - * Mask and clear PMU interrupts - */ - writel(0, PMU_INTERRUPT_MASK); - writel(0, PMU_INTERRUPT_CAUSE); - - for (i = IRQ_DOVE_PMU_START; i < DOVE_NR_IRQS; i++) { - irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); - irq_set_status_flags(i, IRQ_LEVEL); - irq_clear_status_flags(i, IRQ_NOREQUEST); - } - irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); } |