ARM: dove: convert legacy dove to PMU support
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 8 Dec 2015 10:58:09 +0000 (10:58 +0000)
committerGregory CLEMENT <gregory.clement@free-electrons.com>
Tue, 8 Dec 2015 12:23:14 +0000 (13:23 +0100)
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>
arch/arm/Kconfig
arch/arm/mach-dove/common.c
arch/arm/mach-dove/include/mach/pm.h
arch/arm/mach-dove/irq.c

index 473c1417968a8c69d85b4c9a062639c965213054..72af9d6f8c132f6a14a4a264dcb21d91566bac13 100644 (file)
@@ -516,6 +516,7 @@ config ARCH_DOVE
        select PINCTRL_DOVE
        select PLAT_ORION_LEGACY
        select SPARSE_IRQ
+       select PM_GENERIC_DOMAINS if PM
        help
          Support for the Marvell Dove SoC 88AP510
 
index 25a682fd444f783692a9eeb9dc52f2905fa978b7..0cdaa3851d2e3950d441664a1db33cc6e56beb94 100644 (file)
@@ -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();
index 9834ba10cd13f8877e71edce2d655bfe46955296..d22b9b174007fa4c39a82f172542d352d9dd7770 100644 (file)
 #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
index ad785d34c1e781093073a068627f2adf670bc124..d6627c1f7f30bb9691ea5eda9c42059df5c5c9cb 100644 (file)
@@ -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);
 }