Merge branch 'renesas/dt' into next/dt
authorArnd Bergmann <arnd@arndb.de>
Sun, 22 Apr 2012 20:12:57 +0000 (22:12 +0200)
committerOlof Johansson <olof@lixom.net>
Wed, 9 May 2012 09:14:11 +0000 (02:14 -0700)
First part of DT changes for the Renesas shmobile platform,
pulled from:

  git://git.kernel.org/pub/scm/linux/kernel/git/rafael/renesas.git dt

* renesas/dt:
  ARM: mach-shmobile: sh7372 generic board support via DT V2
  ARM: mach-shmobile: Rework sh7372 INTCS demuxer V2
  ARM: mach-shmobile: Use INTC_IRQ_PINS_16H on sh7372
  ARM: mach-shmobile: Use 0x3400 as INTCS vector offset
  ARM: mach-shmobile: Introduce INTC_IRQ_PINS_16H
  ARM: mach-shmobile: Introduce shmobile_setup_delay()

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
[olof: rebuilt branch due to drop of an early merge]
Signed-off-by: Olof Johansson <olof@lixom.net>
arch/arm/boot/dts/sh7372.dtsi [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/common.h
arch/arm/mach-shmobile/include/mach/intc.h
arch/arm/mach-shmobile/include/mach/irqs.h
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/setup-sh7372.c
arch/arm/mach-shmobile/timer.c

diff --git a/arch/arm/boot/dts/sh7372.dtsi b/arch/arm/boot/dts/sh7372.dtsi
new file mode 100644 (file)
index 0000000..677fc60
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Device Tree Source for the sh7372 SoC
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "renesas,sh7372";
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,cortex-a8";
+               };
+       };
+};
index 83ad3fe..cc1d735 100644 (file)
@@ -3,6 +3,8 @@
 
 extern void shmobile_earlytimer_init(void);
 extern struct sys_timer shmobile_timer;
+extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
+                                unsigned int mult, unsigned int div);
 struct twd_local_timer;
 void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
 extern void shmobile_setup_console(void);
index 8b22258..a5603c7 100644 (file)
@@ -142,6 +142,50 @@ static struct intc_desc p ## _desc __initdata = {                  \
                             p ## _sense_registers, p ## _ack_registers) \
 }
 
+#define INTC_IRQ_PINS_16H(p, base, vect, str)                          \
+                                                                       \
+static struct resource p ## _resources[] __initdata = {                        \
+       [0] = {                                                         \
+               .start  = base,                                         \
+               .end    = base + 0x64,                                  \
+               .flags  = IORESOURCE_MEM,                               \
+       },                                                              \
+};                                                                     \
+                                                                       \
+enum {                                                                 \
+       p ## _UNUSED = 0,                                               \
+       INTC_IRQ_PINS_ENUM_16H(p),                                      \
+};                                                                     \
+                                                                       \
+static struct intc_vect p ## _vectors[] __initdata = {                 \
+       INTC_IRQ_PINS_VECT_16H(p, vect),                                \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _mask_registers[] __initdata = {      \
+       INTC_IRQ_PINS_MASK_16H(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_prio_reg p ## _prio_registers[] __initdata = {      \
+       INTC_IRQ_PINS_PRIO_16H(p, base),                                \
+};                                                                     \
+                                                                       \
+static struct intc_sense_reg p ## _sense_registers[] __initdata = {    \
+       INTC_IRQ_PINS_SENSE_16H(p, base),                               \
+};                                                                     \
+                                                                       \
+static struct intc_mask_reg p ## _ack_registers[] __initdata = {       \
+       INTC_IRQ_PINS_ACK_16H(p, base),                                 \
+};                                                                     \
+                                                                       \
+static struct intc_desc p ## _desc __initdata = {                      \
+       .name = str,                                                    \
+       .resource = p ## _resources,                                    \
+       .num_resources = ARRAY_SIZE(p ## _resources),                   \
+       .hw = INTC_HW_DESC(p ## _vectors, NULL,                         \
+                            p ## _mask_registers, p ## _prio_registers, \
+                            p ## _sense_registers, p ## _ack_registers) \
+}
+
 #define INTC_IRQ_PINS_32(p, base, vect, str)                           \
                                                                        \
 static struct resource p ## _resources[] __initdata = {                        \
index 4e686cc..06a5da3 100644 (file)
@@ -7,7 +7,7 @@
 #define gic_spi(nr)            ((nr) + 32)
 
 /* INTCS */
-#define INTCS_VECT_BASE                0x2200
+#define INTCS_VECT_BASE                0x3400
 #define INTCS_VECT(n, vect)    INTC_VECT((n), INTCS_VECT_BASE + (vect))
 #define intcs_evt2irq(evt)     evt2irq(INTCS_VECT_BASE + (evt))
 
index 6447e0a..2587a22 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/sh_intc.h>
@@ -305,14 +306,16 @@ static DECLARE_INTC_DESC(intca_desc, "sh7372-intca",
                         intca_mask_registers, intca_prio_registers,
                         NULL);
 
-INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
-                INTC_VECT, "sh7372-intca-irq-pins");
+INTC_IRQ_PINS_16(intca_irq_pins_lo, 0xe6900000,
+                INTC_VECT, "sh7372-intca-irq-lo");
+
+INTC_IRQ_PINS_16H(intca_irq_pins_hi, 0xe6900000,
+                INTC_VECT, "sh7372-intca-irq-hi");
+
 enum {
        UNUSED_INTCS = 0,
        ENABLED_INTCS,
 
-       INTCS,
-
        /* interrupt sources INTCS */
 
        /* IRQ0S - IRQ31S */
@@ -426,8 +429,6 @@ static struct intc_vect intcs_vectors[] = {
        INTCS_VECT(CPORTS2R, 0x1a20),
        /* CEC */
        INTCS_VECT(JPU6E, 0x1a80),
-
-       INTC_VECT(INTCS, 0xf80),
 };
 
 static struct intc_group intcs_groups[] __initdata = {
@@ -490,9 +491,6 @@ static struct intc_mask_reg intcs_mask_registers[] = {
        { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
          { MFIS2_INTCS, CPORTS2R, 0, 0,
            JPU6E, 0, 0, 0 } },
-       { 0xffd20104, 0, 16, /* INTAMASK */
-         { 0, 0, 0, 0, 0, 0, 0, 0,
-           0, 0, 0, 0, 0, 0, 0, INTCS } },
 };
 
 /* Priority is needed for INTCA to receive the INTCS interrupt */
@@ -557,18 +555,30 @@ static void __iomem *intcs_ffd5;
 void __init sh7372_init_irq(void)
 {
        void __iomem *intevtsa;
+       int n;
 
        intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE);
        intevtsa = intcs_ffd2 + 0x100;
        intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);
 
        register_intc_controller(&intca_desc);
-       register_intc_controller(&intca_irq_pins_desc);
+       register_intc_controller(&intca_irq_pins_lo_desc);
+       register_intc_controller(&intca_irq_pins_hi_desc);
        register_intc_controller(&intcs_desc);
 
+       /* setup dummy cascade chip for INTCS */
+       n = evt2irq(0xf80);
+       irq_alloc_desc_at(n, numa_node_id());
+       irq_set_chip_and_handler_name(n, &dummy_irq_chip,
+                                     handle_level_irq, "level");
+       set_irq_flags(n, IRQF_VALID); /* yuck */
+
        /* demux using INTEVTSA */
-       irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
-       irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
+       irq_set_handler_data(n, (void *)intevtsa);
+       irq_set_chained_handler(n, intcs_demux);
+
+       /* unmask INTCS in INTAMASK */
+       iowrite16(0, intcs_ffd2 + 0x104);
 }
 
 static unsigned short ffd2[0x200];
index 2fe8f83..4c7fece 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
 #include <linux/uio_driver.h>
 #include <linux/delay.h>
 #include <linux/input.h>
@@ -1092,3 +1093,50 @@ void __init sh7372_add_early_devices(void)
        /* override timer setup with soc-specific code */
        shmobile_timer.init = sh7372_earlytimer_init;
 }
+
+#ifdef CONFIG_USE_OF
+
+void __init sh7372_add_early_devices_dt(void)
+{
+       shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */
+
+       early_platform_add_devices(sh7372_early_devices,
+                                  ARRAY_SIZE(sh7372_early_devices));
+
+       /* setup early console here as well */
+       shmobile_setup_console();
+}
+
+static const struct of_dev_auxdata sh7372_auxdata_lookup[] __initconst = {
+       { }
+};
+
+void __init sh7372_add_standard_devices_dt(void)
+{
+       /* clocks are setup late during boot in the case of DT */
+       sh7372_clock_init();
+
+       platform_add_devices(sh7372_early_devices,
+                           ARRAY_SIZE(sh7372_early_devices));
+
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            sh7372_auxdata_lookup, NULL);
+}
+
+static const char *sh7372_boards_compat_dt[] __initdata = {
+       "renesas,sh7372",
+       NULL,
+};
+
+DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)")
+       .map_io         = sh7372_map_io,
+       .init_early     = sh7372_add_early_devices_dt,
+       .nr_irqs        = NR_IRQS_LEGACY,
+       .init_irq       = sh7372_init_irq,
+       .handle_irq     = shmobile_handle_irq_intc,
+       .init_machine   = sh7372_add_standard_devices_dt,
+       .timer          = &shmobile_timer,
+       .dt_compat      = sh7372_boards_compat_dt,
+MACHINE_END
+
+#endif /* CONFIG_USE_OF */
index 2fba5f3..599e008 100644 (file)
  *
  */
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 #include <asm/mach/time.h>
 #include <asm/smp_twd.h>
 
+void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
+                                unsigned int mult, unsigned int div)
+{
+       /* calculate a worst-case loops-per-jiffy value
+        * based on maximum cpu core mhz setting and the
+        * __delay() implementation in arch/arm/lib/delay.S
+        *
+        * this will result in a longer delay than expected
+        * when the cpu core runs on lower frequencies.
+        */
+
+       unsigned int value = (1000000 * mult) / (HZ * div);
+
+       lpj_fine = max_cpu_core_mhz * value;
+}
+
 static void __init shmobile_late_time_init(void)
 {
        /*