ARM: orion: Refactor the MPP code common in the orion platform
authorAndrew Lunn <andrew@lunn.ch>
Sun, 15 May 2011 11:32:52 +0000 (13:32 +0200)
committerNicolas Pitre <nico@fluxnic.net>
Mon, 16 May 2011 19:25:54 +0000 (15:25 -0400)
mv78xx0 and kirkwood use identical mpp code.

It should also be possible to rewrite the orion5x mpp to use this
platform code.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
arch/arm/mach-kirkwood/mpp.c
arch/arm/mach-kirkwood/mpp.h
arch/arm/mach-mv78xx0/mpp.c
arch/arm/mach-mv78xx0/mpp.h
arch/arm/plat-orion/Makefile
arch/arm/plat-orion/include/plat/mpp.h [new file with mode: 0644]
arch/arm/plat-orion/mpp.c [new file with mode: 0644]

index 7ce201848067fef794643927f47e5bbb3319948f..b0a7d979a8ed98e9fa35abed1d49577e0ec66b63 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <asm/gpio.h>
 #include <mach/hardware.h>
+#include <plat/mpp.h>
 #include "common.h"
 #include "mpp.h"
 
@@ -36,61 +37,8 @@ static unsigned int __init kirkwood_variant(void)
        return 0;
 }
 
-#define MPP_CTRL(i)    (DEV_BUS_VIRT_BASE + (i) * 4)
-#define MPP_NR_REGS    (1 + MPP_MAX/8)
-
 void __init kirkwood_mpp_conf(unsigned int *mpp_list)
 {
-       u32 mpp_ctrl[MPP_NR_REGS];
-       unsigned int variant_mask;
-       int i;
-
-       variant_mask = kirkwood_variant();
-       if (!variant_mask)
-               return;
-
-       printk(KERN_DEBUG "initial MPP regs:");
-       for (i = 0; i < MPP_NR_REGS; i++) {
-               mpp_ctrl[i] = readl(MPP_CTRL(i));
-               printk(" %08x", mpp_ctrl[i]);
-       }
-       printk("\n");
-
-       for ( ; *mpp_list; mpp_list++) {
-               unsigned int num = MPP_NUM(*mpp_list);
-               unsigned int sel = MPP_SEL(*mpp_list);
-               int shift, gpio_mode;
-
-               if (num > MPP_MAX) {
-                       printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP "
-                                       "number (%u)\n", num);
-                       continue;
-               }
-               if (!(*mpp_list & variant_mask)) {
-                       printk(KERN_WARNING
-                              "kirkwood_mpp_conf: requested MPP%u config "
-                              "unavailable on this hardware\n", num);
-                       continue;
-               }
-
-               shift = (num & 7) << 2;
-               mpp_ctrl[num / 8] &= ~(0xf << shift);
-               mpp_ctrl[num / 8] |= sel << shift;
-
-               gpio_mode = 0;
-               if (*mpp_list & MPP_INPUT_MASK)
-                       gpio_mode |= GPIO_INPUT_OK;
-               if (*mpp_list & MPP_OUTPUT_MASK)
-                       gpio_mode |= GPIO_OUTPUT_OK;
-               if (sel != 0)
-                       gpio_mode = 0;
-               orion_gpio_set_valid(num, gpio_mode);
-       }
-
-       printk(KERN_DEBUG "  final MPP regs:");
-       for (i = 0; i < MPP_NR_REGS; i++) {
-               writel(mpp_ctrl[i], MPP_CTRL(i));
-               printk(" %08x", mpp_ctrl[i]);
-       }
-       printk("\n");
+       orion_mpp_conf(mpp_list, kirkwood_variant(),
+                      MPP_MAX, DEV_BUS_VIRT_BASE);
 }
index 9b0a94d85c3ee6b4e2238c0db2e65117f63f44eb..ac787957e2d9f94e5a57afbce87c799b697d1cc3 100644 (file)
        /* available on F6281 */        ((!!(_F6281)) << 17) | \
        /* available on F6282 */        ((!!(_F6282)) << 18))
 
-#define MPP_NUM(x)     ((x) & 0xff)
-#define MPP_SEL(x)     (((x) >> 8) & 0xf)
-
                                /*   num sel  i  o  6180 6190 6192 6281 6282 */
 
-#define MPP_INPUT_MASK         MPP(  0, 0x0, 1, 0, 0,   0,   0,   0,   0 )
-#define MPP_OUTPUT_MASK                MPP(  0, 0x0, 0, 1, 0,   0,   0,   0,   0 )
-
 #define MPP_F6180_MASK         MPP(  0, 0x0, 0, 0, 1,   0,   0,   0,   0 )
 #define MPP_F6190_MASK         MPP(  0, 0x0, 0, 0, 0,   1,   0,   0,   0 )
 #define MPP_F6192_MASK         MPP(  0, 0x0, 0, 0, 0,   0,   1,   0,   0 )
index 65b72c454cb078b6b2c20a7d981a11f25c9ad8a4..59b7686b92097f30f36175ccfeb8ead5f12d42c3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mbus.h>
 #include <linux/io.h>
+#include <plat/mpp.h>
 #include <asm/gpio.h>
 #include <mach/hardware.h>
 #include "common.h"
@@ -31,61 +32,8 @@ static unsigned int __init mv78xx0_variant(void)
        return 0;
 }
 
-#define MPP_CTRL(i)    (DEV_BUS_VIRT_BASE + (i) * 4)
-#define MPP_NR_REGS    (1 + MPP_MAX/8)
-
 void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
 {
-       u32 mpp_ctrl[MPP_NR_REGS];
-       unsigned int variant_mask;
-       int i;
-
-       variant_mask = mv78xx0_variant();
-       if (!variant_mask)
-               return;
-
-       printk(KERN_DEBUG "initial MPP regs:");
-       for (i = 0; i < MPP_NR_REGS; i++) {
-               mpp_ctrl[i] = readl(MPP_CTRL(i));
-               printk(" %08x", mpp_ctrl[i]);
-       }
-       printk("\n");
-
-       for ( ; *mpp_list; mpp_list++) {
-               unsigned int num = MPP_NUM(*mpp_list);
-               unsigned int sel = MPP_SEL(*mpp_list);
-               int shift, gpio_mode;
-
-               if (num > MPP_MAX) {
-                       printk(KERN_ERR "mv78xx0_mpp_conf: invalid MPP "
-                                       "number (%u)\n", num);
-                       continue;
-               }
-               if (!(*mpp_list & variant_mask)) {
-                       printk(KERN_WARNING
-                                       "mv78xx0_mpp_conf: requested MPP%u config "
-                                       "unavailable on this hardware\n", num);
-                       continue;
-               }
-
-               shift = (num & 7) << 2;
-               mpp_ctrl[num / 8] &= ~(0xf << shift);
-               mpp_ctrl[num / 8] |= sel << shift;
-
-               gpio_mode = 0;
-               if (*mpp_list & MPP_INPUT_MASK)
-                       gpio_mode |= GPIO_INPUT_OK;
-               if (*mpp_list & MPP_OUTPUT_MASK)
-                       gpio_mode |= GPIO_OUTPUT_OK;
-               if (sel != 0)
-                       gpio_mode = 0;
-               orion_gpio_set_valid(num, gpio_mode);
-       }
-
-       printk(KERN_DEBUG "  final MPP regs:");
-       for (i = 0; i < MPP_NR_REGS; i++) {
-               writel(mpp_ctrl[i], MPP_CTRL(i));
-               printk(" %08x", mpp_ctrl[i]);
-       }
-       printk("\n");
+       orion_mpp_conf(mpp_list, mv78xx0_variant(),
+                      MPP_MAX, DEV_BUS_VIRT_BASE);
 }
index 80840b781eaa26cac4232b2e319c2b0bff186919..b61b50927123f3178320f084de9fe19910eb1862 100644 (file)
     /* may be output signal */    ((!!(_out)) << 13) | \
     /* available on A0 */    ((!!(_78100_A0)) << 14))
 
-#define MPP_NUM(x)    ((x) & 0xff)
-#define MPP_SEL(x)    (((x) >> 8) & 0xf)
-
                 /*   num sel  i  o  78100_A0  */
 
-#define MPP_INPUT_MASK        MPP(0, 0x0, 1, 0, 0)
-#define MPP_OUTPUT_MASK        MPP(0, 0x0, 0, 1, 0)
-
 #define MPP_78100_A0_MASK    MPP(0, 0x0, 0, 0, 1)
 
 #define MPP0_GPIO        MPP(0, 0x0, 1, 1, 1)
index 0f048c58b4c9ea35c7e3d01a6709914456cc379c..95a5fc53b6db4c6fd3ea0d0e8c8055e3b7283b58 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y  := irq.o pcie.o time.o common.o
+obj-y  := irq.o pcie.o time.o common.o mpp.o
 obj-m  :=
 obj-n  :=
 obj-   :=
diff --git a/arch/arm/plat-orion/include/plat/mpp.h b/arch/arm/plat-orion/include/plat/mpp.h
new file mode 100644 (file)
index 0000000..723adce
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-orion/include/plat/mpp.h
+ *
+ * Marvell Orion SoC MPP handling.
+ *
+ * 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.
+ */
+
+#ifndef __PLAT_MPP_H
+#define __PLAT_MPP_H
+
+#define MPP_NUM(x)     ((x) & 0xff)
+#define MPP_SEL(x)     (((x) >> 8) & 0xf)
+
+/* This is the generic MPP macro, without any variant information.
+   Each machine architecture is expected to extend this with further
+   bit fields indicating which MPP configurations are valid for a
+   specific variant. */
+
+#define GENERIC_MPP(_num, _sel, _in, _out) ( \
+       /* MPP number */                ((_num) & 0xff) | \
+       /* MPP select value */          (((_sel) & 0xf) << 8) | \
+       /* may be input signal */       ((!!(_in)) << 12) | \
+       /* may be output signal */      ((!!(_out)) << 13))
+
+#define MPP_INPUT_MASK         GENERIC_MPP(0, 0x0, 1, 0)
+#define MPP_OUTPUT_MASK                GENERIC_MPP(0, 0x0, 0, 1)
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+                          unsigned int mpp_max, unsigned int dev_bus);
+
+#endif
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
new file mode 100644 (file)
index 0000000..248c022
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/plat-orion/mpp.c
+ *
+ * MPP functions for Marvell orion SoCs
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <plat/mpp.h>
+
+/* Address of the ith MPP control register */
+static __init unsigned long mpp_ctrl_addr(unsigned int i,
+                                         unsigned long dev_bus)
+{
+       return dev_bus + (i) * 4;
+}
+
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+                          unsigned int mpp_max, unsigned int dev_bus)
+{
+       unsigned int mpp_nr_regs = (1 + mpp_max/8);
+       u32 mpp_ctrl[mpp_nr_regs];
+       int i;
+
+       if (!variant_mask)
+               return;
+
+       printk(KERN_DEBUG "initial MPP regs:");
+       for (i = 0; i < mpp_nr_regs; i++) {
+               mpp_ctrl[i] = readl(mpp_ctrl_addr(i, dev_bus));
+               printk(" %08x", mpp_ctrl[i]);
+       }
+       printk("\n");
+
+       for ( ; *mpp_list; mpp_list++) {
+               unsigned int num = MPP_NUM(*mpp_list);
+               unsigned int sel = MPP_SEL(*mpp_list);
+               int shift, gpio_mode;
+
+               if (num > mpp_max) {
+                       printk(KERN_ERR "orion_mpp_conf: invalid MPP "
+                                       "number (%u)\n", num);
+                       continue;
+               }
+               if (!(*mpp_list & variant_mask)) {
+                       printk(KERN_WARNING
+                              "orion_mpp_conf: requested MPP%u config "
+                              "unavailable on this hardware\n", num);
+                       continue;
+               }
+
+               shift = (num & 7) << 2;
+               mpp_ctrl[num / 8] &= ~(0xf << shift);
+               mpp_ctrl[num / 8] |= sel << shift;
+
+               gpio_mode = 0;
+               if (*mpp_list & MPP_INPUT_MASK)
+                       gpio_mode |= GPIO_INPUT_OK;
+               if (*mpp_list & MPP_OUTPUT_MASK)
+                       gpio_mode |= GPIO_OUTPUT_OK;
+               if (sel != 0)
+                       gpio_mode = 0;
+               orion_gpio_set_valid(num, gpio_mode);
+       }
+
+       printk(KERN_DEBUG "  final MPP regs:");
+       for (i = 0; i < mpp_nr_regs; i++) {
+               writel(mpp_ctrl[i], mpp_ctrl_addr(i, dev_bus));
+               printk(" %08x", mpp_ctrl[i]);
+       }
+       printk("\n");
+}