Merge branch 'soc-core' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesa...
authorOlof Johansson <olof@lixom.net>
Wed, 5 Sep 2012 22:35:48 +0000 (15:35 -0700)
committerOlof Johansson <olof@lixom.net>
Wed, 5 Sep 2012 22:35:48 +0000 (15:35 -0700)
* 'soc-core' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
  ARM: mach-shmobile: Add compilation support for dtbs using 'make dtbs'
  + sync to 3.6-rc3

23 files changed:
Documentation/devicetree/bindings/arm/mrvl/tauros2.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/pxa-rtc.txt [new file with mode: 0644]
arch/arm/boot/dts/mmp2.dtsi
arch/arm/boot/dts/pxa27x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/pxa2xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/pxa3xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/pxa910.dtsi
arch/arm/include/asm/hardware/cache-tauros2.h
arch/arm/mach-dove/common.c
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/clock-pxa3xx.c
arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/pxa-dt.c [new file with mode: 0644]
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mm/cache-tauros2.c
drivers/gpio/gpio-pxa.c
drivers/mtd/nand/pxa3xx_nand.c
drivers/rtc/rtc-pxa.c

diff --git a/Documentation/devicetree/bindings/arm/mrvl/tauros2.txt b/Documentation/devicetree/bindings/arm/mrvl/tauros2.txt
new file mode 100644 (file)
index 0000000..31af1cb
--- /dev/null
@@ -0,0 +1,17 @@
+* Marvell Tauros2 Cache
+
+Required properties:
+- compatible : Should be "marvell,tauros2-cache".
+- marvell,tauros2-cache-features : Specify the features supported for the
+  tauros2 cache.
+  The features including
+    CACHE_TAUROS2_PREFETCH_ON       (1 << 0)
+    CACHE_TAUROS2_LINEFILL_BURST8   (1 << 1)
+  The definition can be found at
+  arch/arm/include/asm/hardware/cache-tauros2.h
+
+Example:
+       L2: l2-cache {
+               compatible = "marvell,tauros2-cache";
+               marvell,tauros2-cache-features = <0x3>;
+       };
diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
new file mode 100644 (file)
index 0000000..f1421e2
--- /dev/null
@@ -0,0 +1,31 @@
+PXA3xx NAND DT bindings
+
+Required properties:
+
+ - compatible:         Should be "marvell,pxa3xx-nand"
+ - reg:                The register base for the controller
+ - interrupts:         The interrupt to map
+ - #address-cells:     Set to <1> if the node includes partitions
+
+Optional properties:
+
+ - marvell,nand-enable-arbiter:        Set to enable the bus arbiter
+ - marvell,nand-keep-config:   Set to keep the NAND controller config as set
+                               by the bootloader
+ - num-cs:                     Number of chipselect lines to usw
+
+Example:
+
+       nand0: nand@43100000 {
+               compatible = "marvell,pxa3xx-nand";
+               reg = <0x43100000 90>;
+               interrupts = <45>;
+               #address-cells = <1>;
+
+               marvell,nand-enable-arbiter;
+               marvell,nand-keep-config;
+               num-cs = <1>;
+
+               /* partitions (optional) */
+       };
+
diff --git a/Documentation/devicetree/bindings/rtc/pxa-rtc.txt b/Documentation/devicetree/bindings/rtc/pxa-rtc.txt
new file mode 100644 (file)
index 0000000..8c6672a
--- /dev/null
@@ -0,0 +1,14 @@
+* PXA RTC
+
+PXA specific RTC driver.
+
+Required properties:
+- compatible : Should be "marvell,pxa-rtc"
+
+Examples:
+
+rtc@40900000 {
+       compatible = "marvell,pxa-rtc";
+       reg = <0x40900000 0x3c>;
+       interrupts = <30 31>;
+};
index 80f74e2..0514fb4 100644 (file)
                interrupt-parent = <&intc>;
                ranges;
 
+               L2: l2-cache {
+                       compatible = "marvell,tauros2-cache";
+                       marvell,tauros2-cache-features = <0x3>;
+               };
+
                axi@d4200000 {  /* AXI */
                        compatible = "mrvl,axi-bus", "simple-bus";
                        #address-cells = <1>;
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
new file mode 100644 (file)
index 0000000..d7c5d72
--- /dev/null
@@ -0,0 +1,14 @@
+/* The pxa3xx skeleton simply augments the 2xx version */
+/include/ "pxa2xx.dtsi"
+
+/ {
+       model = "Marvell PXA27x familiy SoC";
+       compatible = "marvell,pxa27x";
+
+       pxabus {
+               pxairq: interrupt-controller@40d00000 {
+                       marvell,intc-priority;
+                       marvell,intc-nr-irqs = <34>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/pxa2xx.dtsi b/arch/arm/boot/dts/pxa2xx.dtsi
new file mode 100644 (file)
index 0000000..f18aad3
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * pxa2xx.dtsi - Device Tree Include file for Marvell PXA2xx family SoC
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       model = "Marvell PXA2xx family SoC";
+       compatible = "marvell,pxa2xx";
+       interrupt-parent = <&pxairq>;
+
+       aliases {
+               serial0 = &ffuart;
+               serial1 = &btuart;
+               serial2 = &stuart;
+               serial3 = &hwuart;
+               i2c0 = &pwri2c;
+               i2c1 = &pxai2c1;
+       };
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,xscale";
+               };
+       };
+
+       pxabus {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               pxairq: interrupt-controller@40d00000 {
+                       #interrupt-cells = <1>;
+                       compatible = "marvell,pxa-intc";
+                       interrupt-controller;
+                       interrupt-parent;
+                       marvell,intc-nr-irqs = <32>;
+                       reg = <0x40d00000 0xd0>;
+               };
+
+               gpio: gpio@40e00000 {
+                       compatible = "mrvl,pxa-gpio";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x40e00000 0x10000>;
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+                       interrupts = <10>;
+                       interrupt-names = "gpio_mux";
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+                       ranges;
+
+                       gcb0: gpio@40e00000 {
+                               reg = <0x40e00000 0x4>;
+                       };
+
+                       gcb1: gpio@40e00004 {
+                               reg = <0x40e00004 0x4>;
+                       };
+
+                       gcb2: gpio@40e00008 {
+                               reg = <0x40e00008 0x4>;
+                       };
+                       gcb3: gpio@40e0000c {
+                               reg = <0x40e0000c 0x4>;
+                       };
+               };
+
+               ffuart: uart@40100000 {
+                       compatible = "mrvl,pxa-uart";
+                       reg = <0x40100000 0x30>;
+                       interrupts = <22>;
+                       status = "disabled";
+               };
+
+               btuart: uart@40200000 {
+                       compatible = "mrvl,pxa-uart";
+                       reg = <0x40200000 0x30>;
+                       interrupts = <21>;
+                       status = "disabled";
+               };
+
+               stuart: uart@40700000 {
+                       compatible = "mrvl,pxa-uart";
+                       reg = <0x40700000 0x30>;
+                       interrupts = <20>;
+                       status = "disabled";
+               };
+
+               hwuart: uart@41100000 {
+                       compatible = "mrvl,pxa-uart";
+                       reg = <0x41100000 0x30>;
+                       interrupts = <7>;
+                       status = "disabled";
+               };
+
+               pxai2c1: i2c@40301680 {
+                       compatible = "mrvl,pxa-i2c";
+                       reg = <0x40301680 0x30>;
+                       interrupts = <18>;
+                       #address-cells = <0x1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               usb0: ohci@4c000000 {
+                       compatible = "mrvl,pxa-ohci";
+                       reg = <0x4c000000 0x10000>;
+                       interrupts = <3>;
+                       status = "disabled";
+               };
+
+               mmc0: mmc@41100000 {
+                       compatible = "mrvl,pxa-mmc";
+                       reg = <0x41100000 0x1000>;
+                       interrupts = <23>;
+                       status = "disabled";
+               };
+
+               rtc@40900000 {
+                       compatible = "marvell,pxa-rtc";
+                       reg = <0x40900000 0x3c>;
+                       interrupts = <30 31>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi
new file mode 100644 (file)
index 0000000..f9d92da
--- /dev/null
@@ -0,0 +1,32 @@
+/* The pxa3xx skeleton simply augments the 2xx version */
+/include/ "pxa2xx.dtsi"
+
+/ {
+       model = "Marvell PXA3xx familiy SoC";
+       compatible = "marvell,pxa3xx";
+
+       pxabus {
+               pwri2c: i2c@40f500c0 {
+                       compatible = "mrvl,pwri2c";
+                       reg = <0x40f500c0 0x30>;
+                       interrupts = <6>;
+                       #address-cells = <0x1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               nand0: nand@43100000 {
+                       compatible = "marvell,pxa3xx-nand";
+                       reg = <0x43100000 90>;
+                       interrupts = <45>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;      
+                       status = "disabled";
+               };
+
+               pxairq: interrupt-controller@40d00000 {
+                       marvell,intc-priority;
+                       marvell,intc-nr-irqs = <56>;
+               };
+       };
+};
index aebf32d..a3be44d 100644 (file)
                interrupt-parent = <&intc>;
                ranges;
 
+               L2: l2-cache {
+                       compatible = "marvell,tauros2-cache";
+                       marvell,tauros2-cache-features = <0x3>;
+               };
+
                axi@d4200000 {  /* AXI */
                        compatible = "mrvl,axi-bus", "simple-bus";
                        #address-cells = <1>;
index 538f17c..295e2e4 100644 (file)
@@ -8,4 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 
-extern void __init tauros2_init(void);
+#define CACHE_TAUROS2_PREFETCH_ON      (1 << 0)
+#define CACHE_TAUROS2_LINEFILL_BURST8  (1 << 1)
+
+extern void __init tauros2_init(unsigned int features);
index 4db5de5..db399df 100644 (file)
@@ -288,7 +288,7 @@ void __init dove_init(void)
        printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
 
 #ifdef CONFIG_CACHE_TAUROS2
-       tauros2_init();
+       tauros2_init(0);
 #endif
        dove_setup_cpu_mbus();
 
index c709a24..c2bb95c 100644 (file)
@@ -163,7 +163,7 @@ static int __init mmp2_init(void)
 {
        if (cpu_is_mmp2()) {
 #ifdef CONFIG_CACHE_TAUROS2
-               tauros2_init();
+               tauros2_init(0);
 #endif
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(mmp2_addr_map);
index 6da52e9..51ac8d1 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
+#include <asm/hardware/cache-tauros2.h>
 #include <asm/mach/time.h>
 #include <mach/addr-map.h>
 #include <mach/regs-apbc.h>
@@ -116,6 +117,9 @@ static struct clk_lookup pxa910_clkregs[] = {
 static int __init pxa910_init(void)
 {
        if (cpu_is_pxa910()) {
+#ifdef CONFIG_CACHE_TAUROS2
+               tauros2_init(0);
+#endif
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(pxa910_mfp_addr_map);
                pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
index fe2d1f8..8e6288d 100644 (file)
@@ -25,6 +25,18 @@ config PXA_V7_MACH_AUTO
 if !ARCH_PXA_V7
 comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
 
+config MACH_PXA3XX_DT
+       bool "Support PXA3xx platforms from device tree"
+       select PXA3xx
+       select CPU_PXA300
+       select POWER_SUPPLY
+       select HAVE_PWM
+       select USE_OF
+       help
+         Include support for Marvell PXA3xx based platforms using
+         the device tree. Needn't select any other machine while
+         MACH_PXA3XX_DT is enabled.
+
 config ARCH_LUBBOCK
        bool "Intel DBPXA250 Development Platform (aka Lubbock)"
        select PXA25x
index be0f7df..2bedc9e 100644 (file)
@@ -26,6 +26,9 @@ obj-$(CONFIG_CPU_PXA930)      += pxa930.o
 
 # NOTE: keep the order of boards in accordance to their order in Kconfig
 
+# Device Tree support
+obj-$(CONFIG_MACH_PXA3XX_DT)   += pxa-dt.o
+
 # Intel/Marvell Dev Platforms
 obj-$(CONFIG_ARCH_LUBBOCK)     += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE)   += mainstone.o
index 2a37a9a..d4e9499 100644 (file)
@@ -127,8 +127,10 @@ void clk_pxa3xx_cken_enable(struct clk *clk)
 
        if (clk->cken < 32)
                CKENA |= mask;
-       else
+       else if (clk->cken < 64)
                CKENB |= mask;
+       else
+               CKENC |= mask;
 }
 
 void clk_pxa3xx_cken_disable(struct clk *clk)
@@ -137,8 +139,10 @@ void clk_pxa3xx_cken_disable(struct clk *clk)
 
        if (clk->cken < 32)
                CKENA &= ~mask;
-       else
+       else if (clk->cken < 64)
                CKENB &= ~mask;
+       else
+               CKENC &= ~mask;
 }
 
 const struct clkops clk_pxa3xx_cken_ops = {
index 207ecb4..f4d48d2 100644 (file)
 #define AICSR          __REG(0x41340008)       /* Application Subsystem Interrupt Control/Status Register */
 #define CKENA          __REG(0x4134000C)       /* A Clock Enable Register */
 #define CKENB          __REG(0x41340010)       /* B Clock Enable Register */
+#define CKENC          __REG(0x41340024)       /* C Clock Enable Register */
 #define AC97_DIV       __REG(0x41340014)       /* AC97 clock divisor value register */
 
 #define ACCR_XPDIS             (1 << 31)       /* Core PLL Output Disable */
index 5dae15e..b6cc181 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/syscore_ops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/exception.h>
 
@@ -25,8 +27,6 @@
 
 #include "generic.h"
 
-#define IRQ_BASE               io_p2v(0x40d00000)
-
 #define ICIP                   (0x000)
 #define ICMR                   (0x004)
 #define ICLR                   (0x008)
  * This is for peripheral IRQs internal to the PXA chip.
  */
 
+static void __iomem *pxa_irq_base;
 static int pxa_internal_irq_nr;
-
-static inline int cpu_has_ipr(void)
-{
-       return !cpu_is_pxa25x();
-}
+static bool cpu_has_ipr;
 
 static inline void __iomem *irq_base(int i)
 {
-       static unsigned long phys_base[] = {
-               0x40d00000,
-               0x40d0009c,
-               0x40d00130,
+       static unsigned long phys_base_offset[] = {
+               0x0,
+               0x9c,
+               0x130,
        };
 
-       return io_p2v(phys_base[i]);
+       return pxa_irq_base + phys_base_offset[i];
 }
 
 void pxa_mask_irq(struct irq_data *d)
@@ -96,8 +93,8 @@ asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs)
        uint32_t icip, icmr, mask;
 
        do {
-               icip = __raw_readl(IRQ_BASE + ICIP);
-               icmr = __raw_readl(IRQ_BASE + ICMR);
+               icip = __raw_readl(pxa_irq_base + ICIP);
+               icmr = __raw_readl(pxa_irq_base + ICMR);
                mask = icip & icmr;
 
                if (mask == 0)
@@ -128,6 +125,8 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
        BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
 
        pxa_internal_irq_nr = irq_nr;
+       cpu_has_ipr = !cpu_is_pxa25x();
+       pxa_irq_base = io_p2v(0x40d00000);
 
        for (n = 0; n < irq_nr; n += 32) {
                void __iomem *base = irq_base(n >> 5);
@@ -136,8 +135,8 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
                __raw_writel(0, base + ICLR);   /* all IRQs are IRQ, not FIQ */
                for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
                        /* initialize interrupt priority */
-                       if (cpu_has_ipr())
-                               __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
+                       if (cpu_has_ipr)
+                               __raw_writel(i | IPR_VALID, pxa_irq_base + IPR(i));
 
                        irq = PXA_IRQ(i);
                        irq_set_chip_and_handler(irq, &pxa_internal_irq_chip,
@@ -168,9 +167,9 @@ static int pxa_irq_suspend(void)
                __raw_writel(0, base + ICMR);
        }
 
-       if (cpu_has_ipr()) {
+       if (cpu_has_ipr) {
                for (i = 0; i < pxa_internal_irq_nr; i++)
-                       saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
+                       saved_ipr[i] = __raw_readl(pxa_irq_base + IPR(i));
        }
 
        return 0;
@@ -187,11 +186,11 @@ static void pxa_irq_resume(void)
                __raw_writel(0, base + ICLR);
        }
 
-       if (cpu_has_ipr())
+       if (cpu_has_ipr)
                for (i = 0; i < pxa_internal_irq_nr; i++)
-                       __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
+                       __raw_writel(saved_ipr[i], pxa_irq_base + IPR(i));
 
-       __raw_writel(1, IRQ_BASE + ICCR);
+       __raw_writel(1, pxa_irq_base + ICCR);
 }
 #else
 #define pxa_irq_suspend                NULL
@@ -202,3 +201,93 @@ struct syscore_ops pxa_irq_syscore_ops = {
        .suspend        = pxa_irq_suspend,
        .resume         = pxa_irq_resume,
 };
+
+#ifdef CONFIG_OF
+static struct irq_domain *pxa_irq_domain;
+
+static int pxa_irq_map(struct irq_domain *h, unsigned int virq,
+                      irq_hw_number_t hw)
+{
+       void __iomem *base = irq_base(hw / 32);
+
+       /* initialize interrupt priority */
+       if (cpu_has_ipr)
+               __raw_writel(hw | IPR_VALID, pxa_irq_base + IPR(hw));
+
+       irq_set_chip_and_handler(hw, &pxa_internal_irq_chip,
+                                handle_level_irq);
+       irq_set_chip_data(hw, base);
+       set_irq_flags(hw, IRQF_VALID);
+
+       return 0;
+}
+
+static struct irq_domain_ops pxa_irq_ops = {
+       .map    = pxa_irq_map,
+       .xlate  = irq_domain_xlate_onecell,
+};
+
+static const struct of_device_id intc_ids[] __initconst = {
+       { .compatible = "marvell,pxa-intc", },
+       {}
+};
+
+void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int))
+{
+       struct device_node *node;
+       const struct of_device_id *of_id;
+       struct pxa_intc_conf *conf;
+       struct resource res;
+       int n, ret;
+
+       node = of_find_matching_node(NULL, intc_ids);
+       if (!node) {
+               pr_err("Failed to find interrupt controller in arch-pxa\n");
+               return;
+       }
+       of_id = of_match_node(intc_ids, node);
+       conf = of_id->data;
+
+       ret = of_property_read_u32(node, "marvell,intc-nr-irqs",
+                                  &pxa_internal_irq_nr);
+       if (ret) {
+               pr_err("Not found marvell,intc-nr-irqs property\n");
+               return;
+       }
+
+       ret = of_address_to_resource(node, 0, &res);
+       if (ret < 0) {
+               pr_err("No registers defined for node\n");
+               return;
+       }
+       pxa_irq_base = io_p2v(res.start);
+
+       if (of_find_property(node, "marvell,intc-priority", NULL))
+               cpu_has_ipr = 1;
+
+       ret = irq_alloc_descs(-1, 0, pxa_internal_irq_nr, 0);
+       if (ret < 0) {
+               pr_err("Failed to allocate IRQ numbers\n");
+               return;
+       }
+
+       pxa_irq_domain = irq_domain_add_legacy(node, pxa_internal_irq_nr, 0, 0,
+                                              &pxa_irq_ops, NULL);
+       if (!pxa_irq_domain)
+               panic("Unable to add PXA IRQ domain\n");
+
+       irq_set_default_host(pxa_irq_domain);
+
+       for (n = 0; n < pxa_internal_irq_nr; n += 32) {
+               void __iomem *base = irq_base(n >> 5);
+
+               __raw_writel(0, base + ICMR);   /* disable all IRQs */
+               __raw_writel(0, base + ICLR);   /* all IRQs are IRQ, not FIQ */
+       }
+
+       /* only unmasked interrupts kick us out of idle */
+       __raw_writel(1, irq_base(0) + ICCR);
+
+       pxa_internal_irq_chip.irq_set_wake = fn;
+}
+#endif /* CONFIG_OF */
diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c
new file mode 100644 (file)
index 0000000..c9192ce
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  linux/arch/arm/mach-pxa/pxa-dt.c
+ *
+ *  Copyright (C) 2012 Daniel Mack
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/pxa3xx.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PXA3xx
+extern void __init pxa3xx_dt_init_irq(void);
+
+static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = {
+       OF_DEV_AUXDATA("mrvl,pxa-uart",         0x40100000, "pxa2xx-uart.0", NULL),
+       OF_DEV_AUXDATA("mrvl,pxa-uart",         0x40200000, "pxa2xx-uart.1", NULL),
+       OF_DEV_AUXDATA("mrvl,pxa-uart",         0x40700000, "pxa2xx-uart.2", NULL),
+       OF_DEV_AUXDATA("mrvl,pxa-uart",         0x41600000, "pxa2xx-uart.3", NULL),
+       OF_DEV_AUXDATA("marvell,pxa-mmc",       0x41100000, "pxa2xx-mci.0", NULL),
+       OF_DEV_AUXDATA("mrvl,pxa-gpio",         0x40e00000, "pxa-gpio", NULL),
+       OF_DEV_AUXDATA("marvell,pxa-ohci",      0x4c000000, "pxa27x-ohci", NULL),
+       OF_DEV_AUXDATA("mrvl,pxa-i2c",          0x40301680, "pxa2xx-i2c.0", NULL),
+       OF_DEV_AUXDATA("mrvl,pwri2c",           0x40f500c0, "pxa3xx-i2c.1", NULL),
+       OF_DEV_AUXDATA("marvell,pxa3xx-nand",   0x43100000, "pxa3xx-nand", NULL),
+       {}
+};
+
+static void __init pxa3xx_dt_init(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            pxa3xx_auxdata_lookup, NULL);
+}
+
+static const char *pxa3xx_dt_board_compat[] __initdata = {
+       "marvell,pxa300",
+       "marvell,pxa310",
+       "marvell,pxa320",
+       NULL,
+};
+#endif
+
+#ifdef CONFIG_PXA3xx
+DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
+       .map_io         = pxa3xx_map_io,
+       .init_irq       = pxa3xx_dt_init_irq,
+       .handle_irq     = pxa3xx_handle_irq,
+       .timer          = &pxa_timer,
+       .restart        = pxa_restart,
+       .init_machine   = pxa3xx_dt_init,
+       .dt_compat      = pxa3xx_dt_board_compat,
+MACHINE_END
+#endif
index dffb7e8..ff9c957 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
 #include <linux/syscore_ops.h>
 #include <linux/i2c/pxa-i2c.h>
 
@@ -40,6 +41,8 @@
 #define PECR_IE(n)     ((1 << ((n) * 2)) << 28)
 #define PECR_IS(n)     ((1 << ((n) * 2)) << 29)
 
+extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
+
 static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
 static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
 static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
@@ -382,7 +385,7 @@ static void __init pxa_init_ext_wakeup_irq(int (*fn)(struct irq_data *,
        pxa_ext_wakeup_chip.irq_set_wake = fn;
 }
 
-void __init pxa3xx_init_irq(void)
+static void __init __pxa3xx_init_irq(void)
 {
        /* enable CP6 access */
        u32 value;
@@ -390,10 +393,23 @@ void __init pxa3xx_init_irq(void)
        value |= (1 << 6);
        __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
 
-       pxa_init_irq(56, pxa3xx_set_wake);
        pxa_init_ext_wakeup_irq(pxa3xx_set_wake);
 }
 
+void __init pxa3xx_init_irq(void)
+{
+       __pxa3xx_init_irq();
+       pxa_init_irq(56, pxa3xx_set_wake);
+}
+
+#ifdef CONFIG_OF
+void __init pxa3xx_dt_init_irq(void)
+{
+       __pxa3xx_init_irq();
+       pxa_dt_irq_init(pxa3xx_set_wake);
+}
+#endif /* CONFIG_OF */
+
 static struct map_desc pxa3xx_io_desc[] __initdata = {
        {       /* Mem Ctl */
                .virtual        = (unsigned long)SMEMC_VIRT,
@@ -466,7 +482,8 @@ static int __init pxa3xx_init(void)
                register_syscore_ops(&pxa3xx_mfp_syscore_ops);
                register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
-               ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+               if (!of_have_populated_dt())
+                       ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
 
        return ret;
index 23a7643..1be0f4e 100644 (file)
  */
 
 #include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
+#include <asm/cputype.h>
 #include <asm/hardware/cache-tauros2.h>
 
 
@@ -144,25 +147,8 @@ static inline void __init write_extra_features(u32 u)
        __asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
 }
 
-static void __init disable_l2_prefetch(void)
-{
-       u32 u;
-
-       /*
-        * Read the CPU Extra Features register and verify that the
-        * Disable L2 Prefetch bit is set.
-        */
-       u = read_extra_features();
-       if (!(u & 0x01000000)) {
-               printk(KERN_INFO "Tauros2: Disabling L2 prefetch.\n");
-               write_extra_features(u | 0x01000000);
-       }
-}
-
 static inline int __init cpuid_scheme(void)
 {
-       extern int processor_id;
-
        return !!((processor_id & 0x000f0000) == 0x000f0000);
 }
 
@@ -189,12 +175,36 @@ static inline void __init write_actlr(u32 actlr)
        __asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
 }
 
-void __init tauros2_init(void)
+static void enable_extra_feature(unsigned int features)
+{
+       u32 u;
+
+       u = read_extra_features();
+
+       if (features & CACHE_TAUROS2_PREFETCH_ON)
+               u &= ~0x01000000;
+       else
+               u |= 0x01000000;
+       printk(KERN_INFO "Tauros2: %s L2 prefetch.\n",
+                       (features & CACHE_TAUROS2_PREFETCH_ON)
+                       ? "Enabling" : "Disabling");
+
+       if (features & CACHE_TAUROS2_LINEFILL_BURST8)
+               u |= 0x00100000;
+       else
+               u &= ~0x00100000;
+       printk(KERN_INFO "Tauros2: %s line fill burt8.\n",
+                       (features & CACHE_TAUROS2_LINEFILL_BURST8)
+                       ? "Enabling" : "Disabling");
+
+       write_extra_features(u);
+}
+
+static void __init tauros2_internal_init(unsigned int features)
 {
-       extern int processor_id;
-       char *mode;
+       char *mode = NULL;
 
-       disable_l2_prefetch();
+       enable_extra_feature(features);
 
 #ifdef CONFIG_CPU_32v5
        if ((processor_id & 0xff0f0000) == 0x56050000) {
@@ -286,3 +296,34 @@ void __init tauros2_init(void)
        printk(KERN_INFO "Tauros2: L2 cache support initialised "
                         "in %s mode.\n", mode);
 }
+
+#ifdef CONFIG_OF
+static const struct of_device_id tauros2_ids[] __initconst = {
+       { .compatible = "marvell,tauros2-cache"},
+       {}
+};
+#endif
+
+void __init tauros2_init(unsigned int features)
+{
+#ifdef CONFIG_OF
+       struct device_node *node;
+       int ret;
+       unsigned int f;
+
+       node = of_find_matching_node(NULL, tauros2_ids);
+       if (!node) {
+               pr_info("Not found marvell,tauros2-cache, disable it\n");
+               return;
+       }
+
+       ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f);
+       if (ret) {
+               pr_info("Not found marvell,tauros-cache-features property, "
+                       "disable extra features\n");
+               features = 0;
+       } else
+               features = f;
+#endif
+       tauros2_internal_init(features);
+}
index 9cac88a..9528779 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
+#include <asm/mach/irq.h>
+
 #include <mach/irqs.h>
 
 /*
@@ -59,6 +61,7 @@
 #define BANK_OFF(n)    (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
 
 int pxa_last_gpio;
+static int irq_base;
 
 #ifdef CONFIG_OF
 static struct irq_domain *domain;
@@ -167,63 +170,14 @@ static inline int __gpio_is_occupied(unsigned gpio)
        return ret;
 }
 
-#ifdef CONFIG_ARCH_PXA
-static inline int __pxa_gpio_to_irq(int gpio)
-{
-       if (gpio_is_pxa_type(gpio_type))
-               return PXA_GPIO_TO_IRQ(gpio);
-       return -1;
-}
-
-static inline int __pxa_irq_to_gpio(int irq)
-{
-       if (gpio_is_pxa_type(gpio_type))
-               return irq - PXA_GPIO_TO_IRQ(0);
-       return -1;
-}
-#else
-static inline int __pxa_gpio_to_irq(int gpio) { return -1; }
-static inline int __pxa_irq_to_gpio(int irq) { return -1; }
-#endif
-
-#ifdef CONFIG_ARCH_MMP
-static inline int __mmp_gpio_to_irq(int gpio)
-{
-       if (gpio_is_mmp_type(gpio_type))
-               return MMP_GPIO_TO_IRQ(gpio);
-       return -1;
-}
-
-static inline int __mmp_irq_to_gpio(int irq)
-{
-       if (gpio_is_mmp_type(gpio_type))
-               return irq - MMP_GPIO_TO_IRQ(0);
-       return -1;
-}
-#else
-static inline int __mmp_gpio_to_irq(int gpio) { return -1; }
-static inline int __mmp_irq_to_gpio(int irq) { return -1; }
-#endif
-
 static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-       int gpio, ret;
-
-       gpio = chip->base + offset;
-       ret = __pxa_gpio_to_irq(gpio);
-       if (ret >= 0)
-               return ret;
-       return __mmp_gpio_to_irq(gpio);
+       return chip->base + offset + irq_base;
 }
 
 int pxa_irq_to_gpio(int irq)
 {
-       int ret;
-
-       ret = __pxa_irq_to_gpio(irq);
-       if (ret >= 0)
-               return ret;
-       return __mmp_irq_to_gpio(irq);
+       return irq - irq_base;
 }
 
 static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -403,6 +357,9 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
        struct pxa_gpio_chip *c;
        int loop, gpio, gpio_base, n;
        unsigned long gedr;
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+
+       chained_irq_enter(chip, desc);
 
        do {
                loop = 0;
@@ -422,6 +379,8 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
                        }
                }
        } while (loop);
+
+       chained_irq_exit(chip, desc);
 }
 
 static void pxa_ack_muxed_gpio(struct irq_data *d)
@@ -535,7 +494,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
 
 static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
 {
-       int ret, nr_banks, nr_gpios, irq_base;
+       int ret, nr_banks, nr_gpios;
        struct device_node *prev, *next, *np = pdev->dev.of_node;
        const struct of_device_id *of_id =
                                of_match_device(pxa_gpio_dt_ids, &pdev->dev);
@@ -590,10 +549,20 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
        int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
 
        ret = pxa_gpio_probe_dt(pdev);
-       if (ret < 0)
+       if (ret < 0) {
                pxa_last_gpio = pxa_gpio_nums();
-       else
+#ifdef CONFIG_ARCH_PXA
+               if (gpio_is_pxa_type(gpio_type))
+                       irq_base = PXA_GPIO_TO_IRQ(0);
+#endif
+#ifdef CONFIG_ARCH_MMP
+               if (gpio_is_mmp_type(gpio_type))
+                       irq_base = MMP_GPIO_TO_IRQ(0);
+#endif
+       } else {
                use_of = 1;
+       }
+
        if (!pxa_last_gpio)
                return -EINVAL;
 
index 252aaef..d944d6e 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <mach/dma.h>
 #include <plat/pxa3xx_nand.h>
@@ -1032,7 +1034,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
        struct pxa3xx_nand_platform_data *pdata;
        struct pxa3xx_nand_info *info;
        struct pxa3xx_nand_host *host;
-       struct nand_chip *chip;
+       struct nand_chip *chip = NULL;
        struct mtd_info *mtd;
        struct resource *r;
        int ret, irq, cs;
@@ -1081,21 +1083,31 @@ static int alloc_nand_resource(struct platform_device *pdev)
        }
        clk_enable(info->clk);
 
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no resource defined for data DMA\n");
-               ret = -ENXIO;
-               goto fail_put_clk;
-       }
-       info->drcmr_dat = r->start;
+       /*
+        * This is a dirty hack to make this driver work from devicetree
+        * bindings. It can be removed once we have a prober DMA controller
+        * framework for DT.
+        */
+       if (pdev->dev.of_node && cpu_is_pxa3xx()) {
+               info->drcmr_dat = 97;
+               info->drcmr_cmd = 99;
+       } else {
+               r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+               if (r == NULL) {
+                       dev_err(&pdev->dev, "no resource defined for data DMA\n");
+                       ret = -ENXIO;
+                       goto fail_put_clk;
+               }
+               info->drcmr_dat = r->start;
 
-       r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no resource defined for command DMA\n");
-               ret = -ENXIO;
-               goto fail_put_clk;
+               r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+               if (r == NULL) {
+                       dev_err(&pdev->dev, "no resource defined for command DMA\n");
+                       ret = -ENXIO;
+                       goto fail_put_clk;
+               }
+               info->drcmr_cmd = r->start;
        }
-       info->drcmr_cmd = r->start;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -1200,12 +1212,55 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id pxa3xx_nand_dt_ids[] = {
+       { .compatible = "marvell,pxa3xx-nand" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
+
+static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
+{
+       struct pxa3xx_nand_platform_data *pdata;
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
+
+       if (!of_id)
+               return 0;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       if (of_get_property(np, "marvell,nand-enable-arbiter", NULL))
+               pdata->enable_arbiter = 1;
+       if (of_get_property(np, "marvell,nand-keep-config", NULL))
+               pdata->keep_config = 1;
+       of_property_read_u32(np, "num-cs", &pdata->num_cs);
+
+       pdev->dev.platform_data = pdata;
+
+       return 0;
+}
+#else
+static inline int pxa3xx_nand_probe_dt(struct platform_device *pdev)
+{
+       return 0;
+}
+#endif
+
 static int pxa3xx_nand_probe(struct platform_device *pdev)
 {
        struct pxa3xx_nand_platform_data *pdata;
+       struct mtd_part_parser_data ppdata = {};
        struct pxa3xx_nand_info *info;
        int ret, cs, probe_success;
 
+       ret = pxa3xx_nand_probe_dt(pdev);
+       if (ret)
+               return ret;
+
        pdata = pdev->dev.platform_data;
        if (!pdata) {
                dev_err(&pdev->dev, "no platform data defined\n");
@@ -1229,8 +1284,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
                        continue;
                }
 
+               ppdata.of_node = pdev->dev.of_node;
                ret = mtd_device_parse_register(info->host[cs]->mtd, NULL,
-                                               NULL, pdata->parts[cs],
+                                               &ppdata, pdata->parts[cs],
                                                pdata->nr_parts[cs]);
                if (!ret)
                        probe_success = 1;
@@ -1306,6 +1362,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
 static struct platform_driver pxa3xx_nand_driver = {
        .driver = {
                .name   = "pxa3xx-nand",
+               .of_match_table = of_match_ptr(pxa3xx_nand_dt_ids),
        },
        .probe          = pxa3xx_nand_probe,
        .remove         = pxa3xx_nand_remove,
index 0075c8f..f771b2e 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <mach/hardware.h>
 
@@ -396,6 +398,14 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id pxa_rtc_dt_ids[] = {
+       { .compatible = "marvell,pxa-rtc" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, pxa_rtc_dt_ids);
+#endif
+
 #ifdef CONFIG_PM
 static int pxa_rtc_suspend(struct device *dev)
 {
@@ -425,6 +435,7 @@ static struct platform_driver pxa_rtc_driver = {
        .remove         = __exit_p(pxa_rtc_remove),
        .driver         = {
                .name   = "pxa-rtc",
+               .of_match_table = of_match_ptr(pxa_rtc_dt_ids),
 #ifdef CONFIG_PM
                .pm     = &pxa_rtc_pm_ops,
 #endif