Merge tag 'mvebu-pinctrl-3.15' of git://git.infradead.org/linux-mvebu into pinctrl...
authorLinus Walleij <linus.walleij@linaro.org>
Mon, 3 Mar 2014 05:39:20 +0000 (13:39 +0800)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 3 Mar 2014 05:39:20 +0000 (13:39 +0800)
mvebu pinctrl changes for v3.15

 - various cleanup and refactorization
 - add drivers for the Armada 375, 380, and 385 SoCs
 - prepare dove for SoC code moving into mach-mvebu
 - DT documentation updates

18 files changed:
Documentation/devicetree/bindings/arm/marvell,dove.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/marvell,armada-375-pinctrl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/marvell,armada-38x-pinctrl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/marvell,armada-xp-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt
drivers/pinctrl/mvebu/Kconfig
drivers/pinctrl/mvebu/Makefile
drivers/pinctrl/mvebu/pinctrl-armada-370.c
drivers/pinctrl/mvebu/pinctrl-armada-375.c [new file with mode: 0644]
drivers/pinctrl/mvebu/pinctrl-armada-38x.c [new file with mode: 0644]
drivers/pinctrl/mvebu/pinctrl-armada-xp.c
drivers/pinctrl/mvebu/pinctrl-dove.c
drivers/pinctrl/mvebu/pinctrl-kirkwood.c
drivers/pinctrl/mvebu/pinctrl-mvebu.c
drivers/pinctrl/mvebu/pinctrl-mvebu.h

diff --git a/Documentation/devicetree/bindings/arm/marvell,dove.txt b/Documentation/devicetree/bindings/arm/marvell,dove.txt
new file mode 100644 (file)
index 0000000..aaaf64c
--- /dev/null
@@ -0,0 +1,22 @@
+Marvell Dove Platforms Device Tree Bindings
+-----------------------------------------------
+
+Boards with a Marvell Dove SoC shall have the following properties:
+
+Required root node property:
+- compatible: must contain "marvell,dove";
+
+* Global Configuration registers
+
+Global Configuration registers of Dove SoC are shared by a syscon node.
+
+Required properties:
+- compatible: must contain "marvell,dove-global-config" and "syscon".
+- reg: base address and size of the Global Configuration registers.
+
+Example:
+
+gconf: global-config@e802c {
+       compatible = "marvell,dove-global-config", "syscon";
+       reg = <0xe802c 0x14>;
+};
index 01ef408e205f18ce5ac3c16b44e559f01f877f08..adda2a8d1d5298dcf3b35634d26a3022fc686a14 100644 (file)
@@ -5,6 +5,7 @@ part and usage.
 
 Required properties:
 - compatible: "marvell,88f6710-pinctrl"
+- reg: register specifier of MPP registers
 
 Available mpp pins/groups and functions:
 Note: brackets (x) are not part of the mpp name for marvell,function and given
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-375-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-375-pinctrl.txt
new file mode 100644 (file)
index 0000000..7de0cda
--- /dev/null
@@ -0,0 +1,82 @@
+* Marvell Armada 375 SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,88f6720-pinctrl"
+- reg: register specifier of MPP registers
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name          pins     functions
+================================================================================
+mpp0          0        gpio, dev(ad2), spi0(cs1), spi1(cs1)
+mpp1          1        gpio, dev(ad3), spi0(mosi), spi1(mosi)
+mpp2          2        gpio, dev(ad4), ptp(eventreq), led(c0), audio(sdi)
+mpp3          3        gpio, dev(ad5), ptp(triggen), led(p3), audio(mclk)
+mpp4          4        gpio, dev(ad6), spi0(miso), spi1(miso)
+mpp5          5        gpio, dev(ad7), spi0(cs2), spi1(cs2)
+mpp6          6        gpio, dev(ad0), led(p1), audio(rclk)
+mpp7          7        gpio, dev(ad1), ptp(clk), led(p2), audio(extclk)
+mpp8          8        gpio, dev (bootcs), spi0(cs0), spi1(cs0)
+mpp9          9        gpio, nf(wen), spi0(sck), spi1(sck)
+mpp10        10        gpio, nf(ren), dram(vttctrl), led(c1)
+mpp11        11        gpio, dev(a0), led(c2), audio(sdo)
+mpp12        12        gpio, dev(a1), audio(bclk)
+mpp13        13        gpio, dev(readyn), pcie0(rstoutn), pcie1(rstoutn)
+mpp14        14        gpio, i2c0(sda), uart1(txd)
+mpp15        15        gpio, i2c0(sck), uart1(rxd)
+mpp16        16        gpio, uart0(txd)
+mpp17        17        gpio, uart0(rxd)
+mpp18        18        gpio, tdm(intn)
+mpp19        19        gpio, tdm(rstn)
+mpp20        20        gpio, tdm(pclk)
+mpp21        21        gpio, tdm(fsync)
+mpp22        22        gpio, tdm(drx)
+mpp23        23        gpio, tdm(dtx)
+mpp24        24        gpio, led(p0), ge1(rxd0), sd(cmd), uart0(rts)
+mpp25        25        gpio, led(p2), ge1(rxd1), sd(d0), uart0(cts)
+mpp26        26        gpio, pcie0(clkreq), ge1(rxd2), sd(d2), uart1(rts)
+mpp27        27        gpio, pcie1(clkreq), ge1(rxd3), sd(d1), uart1(cts)
+mpp28        28        gpio, led(p3), ge1(txctl), sd(clk)
+mpp29        29        gpio, pcie1(clkreq), ge1(rxclk), sd(d3)
+mpp30        30        gpio, ge1(txd0), spi1(cs0)
+mpp31        31        gpio, ge1(txd1), spi1(mosi)
+mpp32        32        gpio, ge1(txd2), spi1(sck), ptp(triggen)
+mpp33        33        gpio, ge1(txd3), spi1(miso)
+mpp34        34        gpio, ge1(txclkout), spi1(sck)
+mpp35        35        gpio, ge1(rxctl), spi1(cs1), spi0(cs2)
+mpp36        36        gpio, pcie0(clkreq)
+mpp37        37        gpio, pcie0(clkreq), tdm(intn), ge(mdc)
+mpp38        38        gpio, pcie1(clkreq), ge(mdio)
+mpp39        39        gpio, ref(clkout)
+mpp40        40        gpio, uart1(txd)
+mpp41        41        gpio, uart1(rxd)
+mpp42        42        gpio, spi1(cs2), led(c0)
+mpp43        43        gpio, sata0(prsnt), dram(vttctrl)
+mpp44        44        gpio, sata0(prsnt)
+mpp45        45        gpio, spi0(cs2), pcie0(rstoutn)
+mpp46        46        gpio, led(p0), ge0(txd0), ge1(txd0)
+mpp47        47        gpio, led(p1), ge0(txd1), ge1(txd1)
+mpp48        48        gpio, led(p2), ge0(txd2), ge1(txd2)
+mpp49        49        gpio, led(p3), ge0(txd3), ge1(txd3)
+mpp50        50        gpio, led(c0), ge0(rxd0), ge1(rxd0)
+mpp51        51        gpio, led(c1), ge0(rxd1), ge1(rxd1)
+mpp52        52        gpio, led(c2), ge0(rxd2), ge1(rxd2)
+mpp53        53        gpio, pcie1(rstoutn), ge0(rxd3), ge1(rxd3)
+mpp54        54        gpio, pcie0(rstoutn), ge0(rxctl), ge1(rxctl)
+mpp55        55        gpio, ge0(rxclk), ge1(rxclk)
+mpp56        56        gpio, ge0(txclkout), ge1(txclkout)
+mpp57        57        gpio, ge0(txctl), ge1(txctl)
+mpp58        58        gpio, led(c0)
+mpp59        59        gpio, led(c1)
+mpp60        60        gpio, uart1(txd), led(c2)
+mpp61        61        gpio, i2c1(sda), uart1(rxd), spi1(cs2), led(p0)
+mpp62        62        gpio, i2c1(sck), led(p1)
+mpp63        63        gpio, ptp(triggen), led(p2)
+mpp64        64        gpio, dram(vttctrl), led(p3)
+mpp65        65        gpio, sata1(prsnt)
+mpp66        66        gpio, ptp(eventreq), spi1(cs3)
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-38x-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-38x-pinctrl.txt
new file mode 100644 (file)
index 0000000..b17c968
--- /dev/null
@@ -0,0 +1,80 @@
+* Marvell Armada 380/385 SoC pinctrl driver for mpp
+
+Please refer to marvell,mvebu-pinctrl.txt in this directory for common binding
+part and usage.
+
+Required properties:
+- compatible: "marvell,88f6810-pinctrl", "marvell,88f6820-pinctrl" or
+  "marvell,88f6828-pinctrl" depending on the specific variant of the
+  SoC being used.
+- reg: register specifier of MPP registers
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name          pins     functions
+================================================================================
+mpp0          0        gpio, ua0(rxd)
+mpp1          1        gpio, ua0(txd)
+mpp2          2        gpio, i2c0(sck)
+mpp3          3        gpio, i2c0(sda)
+mpp4          4        gpio, ge(mdc), ua1(txd), ua0(rts)
+mpp5          5        gpio, ge(mdio), ua1(rxd), ua0(cts)
+mpp6          6        gpio, ge0(txclkout), ge0(crs), dev(cs3)
+mpp7          7        gpio, ge0(txd0), dev(ad9)
+mpp8          8        gpio, ge0(txd1), dev(ad10)
+mpp9          9        gpio, ge0(txd2), dev(ad11)
+mpp10         10       gpio, ge0(txd3), dev(ad12)
+mpp11         11       gpio, ge0(txctl), dev(ad13)
+mpp12         12       gpio, ge0(rxd0), pcie0(rstout), pcie1(rstout) [1], spi0(cs1), dev(ad14)
+mpp13         13       gpio, ge0(rxd1), pcie0(clkreq), pcie1(clkreq) [1], spi0(cs2), dev(ad15)
+mpp14         14       gpio, ge0(rxd2), ptp(clk), m(vtt_ctrl), spi0(cs3), dev(wen1)
+mpp15         15       gpio, ge0(rxd3), ge(mdc slave), pcie0(rstout), spi0(mosi), pcie1(rstout) [1]
+mpp16         16       gpio, ge0(rxctl), ge(mdio slave), m(decc_err), spi0(miso), pcie0(clkreq)
+mpp17         17       gpio, ge0(rxclk), ptp(clk), ua1(rxd), spi0(sck), sata1(prsnt)
+mpp18         18       gpio, ge0(rxerr), ptp(trig_gen), ua1(txd), spi0(cs0), pcie1(rstout) [1]
+mpp19         19       gpio, ge0(col), ptp(event_req), pcie0(clkreq), sata1(prsnt), ua0(cts)
+mpp20         20       gpio, ge0(txclk), ptp(clk), pcie1(rstout) [1], sata0(prsnt), ua0(rts)
+mpp21         21       gpio, spi0(cs1), ge1(rxd0), sata0(prsnt), sd0(cmd), dev(bootcs)
+mpp22         22       gpio, spi0(mosi), dev(ad0)
+mpp23         23       gpio, spi0(sck), dev(ad2)
+mpp24         24       gpio, spi0(miso), ua0(cts), ua1(rxd), sd0(d4), dev(ready)
+mpp25         25       gpio, spi0(cs0), ua0(rts), ua1(txd), sd0(d5), dev(cs0)
+mpp26         26       gpio, spi0(cs2), i2c1(sck), sd0(d6), dev(cs1)
+mpp27         27       gpio, spi0(cs3), ge1(txclkout), i2c1(sda), sd0(d7), dev(cs2)
+mpp28         28       gpio, ge1(txd0), sd0(clk), dev(ad5)
+mpp29         29       gpio, ge1(txd1), dev(ale0)
+mpp30         30       gpio, ge1(txd2), dev(oen)
+mpp31         31       gpio, ge1(txd3), dev(ale1)
+mpp32         32       gpio, ge1(txctl), dev(wen0)
+mpp33         33       gpio, m(decc_err), dev(ad3)
+mpp34         34       gpio, dev(ad1)
+mpp35         35       gpio, ref(clk_out1), dev(a1)
+mpp36         36       gpio, ptp(trig_gen), dev(a0)
+mpp37         37       gpio, ptp(clk), ge1(rxclk), sd0(d3), dev(ad8)
+mpp38         38       gpio, ptp(event_req), ge1(rxd1), ref(clk_out0), sd0(d0), dev(ad4)
+mpp39         39       gpio, i2c1(sck), ge1(rxd2), ua0(cts), sd0(d1), dev(a2)
+mpp40         40       gpio, i2c1(sda), ge1(rxd3), ua0(rts), sd0(d2), dev(ad6)
+mpp41         41       gpio, ua1(rxd), ge1(rxctl), ua0(cts), spi1(cs3), dev(burst/last)
+mpp42         42       gpio, ua1(txd), ua0(rts), dev(ad7)
+mpp43         43       gpio, pcie0(clkreq), m(vtt_ctrl), m(decc_err), pcie0(rstout), dev(clkout)
+mpp44         44       gpio, sata0(prsnt), sata1(prsnt), sata2(prsnt) [2], sata3(prsnt) [3], pcie0(rstout)
+mpp45         45       gpio, ref(clk_out0), pcie0(rstout), pcie1(rstout) [1], pcie2(rstout), pcie3(rstout)
+mpp46         46       gpio, ref(clk_out1), pcie0(rstout), pcie1(rstout) [1], pcie2(rstout), pcie3(rstout)
+mpp47         47       gpio, sata0(prsnt), sata1(prsnt), sata2(prsnt) [2], spi1(cs2), sata3(prsnt) [2]
+mpp48         48       gpio, sata0(prsnt), m(vtt_ctrl), tdm2c(pclk), audio(mclk), sd0(d4)
+mpp49         49       gpio, sata2(prsnt) [2], sata3(prsnt) [2], tdm2c(fsync), audio(lrclk), sd0(d5)
+mpp50         50       gpio, pcie0(rstout), pcie1(rstout) [1], tdm2c(drx), audio(extclk), sd0(cmd)
+mpp51         51       gpio, tdm2c(dtx), audio(sdo), m(decc_err)
+mpp52         52       gpio, pcie0(rstout), pcie1(rstout) [1], tdm2c(intn), audio(sdi), sd0(d6)
+mpp53         53       gpio, sata1(prsnt), sata0(prsnt), tdm2c(rstn), audio(bclk), sd0(d7)
+mpp54         54       gpio, sata0(prsnt), sata1(prsnt), pcie0(rstout), pcie1(rstout) [1], sd0(d3)
+mpp55         55       gpio, ua1(cts), ge(mdio), pcie1(clkreq) [1], spi1(cs1), sd0(d0)
+mpp56         56       gpio, ua1(rts), ge(mdc), m(decc_err), spi1(mosi)
+mpp57         57       gpio, spi1(sck), sd0(clk)
+mpp58         58       gpio, pcie1(clkreq) [1], i2c1(sck), pcie2(clkreq), spi1(miso), sd0(d1)
+mpp59         59       gpio, pcie0(rstout), i2c1(sda), pcie1(rstout) [1], spi1(cs0), sd0(d2)
+
+[1]: only available on 88F6820 and 88F6828
+[2]: only available on 88F6828
index bfa0a2e5e0cb929d91f666537fe45a99199005d0..373dbccd7ab0e7c5b4905b7c700e8fada265be1a 100644 (file)
@@ -6,6 +6,7 @@ part and usage.
 Required properties:
 - compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl",
               "marvell,mv78460-pinctrl"
+- reg: register specifier of MPP registers
 
 This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460.
 
index 50ec3512a292c3cbfc8a2ab4aba5c005c10ad2db..cf52477cc7ee3affd5527ccfeaef0fd841e80cff 100644 (file)
@@ -6,6 +6,7 @@ part and usage.
 Required properties:
 - compatible: "marvell,dove-pinctrl"
 - clocks: (optional) phandle of pdma clock
+- reg: register specifiers of MPP, MPP4, and PMU MPP registers
 
 Available mpp pins/groups and functions:
 Note: brackets (x) are not part of the mpp name for marvell,function and given
index 95daf6335c3796e2256ddb94e3e21190cf0c1b35..730444a9a4de8a3aba0e6be2864f974b4f5da1a5 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
               "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl",
               "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl"
               "marvell,98dx4122-pinctrl"
+- reg: register specifier of MPP registers
 
 This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x.
 It also support the 88f6281-based variant in the 98dx412x Bobcat SoCs.
index 0a26c3aa4e6d0ccc20ad78c981f52fb4733e14aa..0c09f4eb2af09db6aa785d6c6ea70f0086de6240 100644 (file)
@@ -37,7 +37,7 @@ uart1: serial@12100 {
 
 pinctrl: pinctrl@d0200 {
        compatible = "marvell,dove-pinctrl";
-       reg = <0xd0200 0x20>;
+       reg = <0xd0200 0x14>, <0xd0440 0x04>, <0xd802c 0x08>;
 
        pmx_uart1_sw: pmx-uart1-sw {
                marvell,pins = "mpp_uart1";
index 366fa541ee9121591e78f66c7ec4307a5d415203..cc298fade93a79e359eb43c2daac3ef50bc91cc1 100644 (file)
@@ -8,6 +8,7 @@ config PINCTRL_MVEBU
 config PINCTRL_DOVE
        bool
        select PINCTRL_MVEBU
+       select MFD_SYSCON
 
 config PINCTRL_KIRKWOOD
        bool
@@ -17,6 +18,14 @@ config PINCTRL_ARMADA_370
        bool
        select PINCTRL_MVEBU
 
+config PINCTRL_ARMADA_375
+       bool
+       select PINCTRL_MVEBU
+
+config PINCTRL_ARMADA_38X
+       bool
+       select PINCTRL_MVEBU
+
 config PINCTRL_ARMADA_XP
        bool
        select PINCTRL_MVEBU
index 37c253297af004767252ec5c26eb8a4c75f19ef4..bc1b9f14f539a23c4e4a97312f03ae9730ac482a 100644 (file)
@@ -2,4 +2,6 @@ obj-$(CONFIG_PINCTRL_MVEBU)     += pinctrl-mvebu.o
 obj-$(CONFIG_PINCTRL_DOVE)     += pinctrl-dove.o
 obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
 obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
+obj-$(CONFIG_PINCTRL_ARMADA_375) += pinctrl-armada-375.o
+obj-$(CONFIG_PINCTRL_ARMADA_38X) += pinctrl-armada-38x.o
 obj-$(CONFIG_PINCTRL_ARMADA_XP)  += pinctrl-armada-xp.o
index ae1f760cbdd2b28cae4c0aa17f2fae0cba0fd50f..670e5b01c6781b3b97245f8b83f72576eeb020af 100644 (file)
 
 #include "pinctrl-mvebu.h"
 
+static void __iomem *mpp_base;
+
+static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
+{
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
 static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
        MPP_MODE(0,
           MPP_FUNCTION(0x0, "gpio", NULL),
@@ -373,7 +385,7 @@ static struct of_device_id armada_370_pinctrl_of_match[] = {
 };
 
 static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
-       MPP_REG_CTRL(0, 65),
+       MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
@@ -385,6 +397,12 @@ static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
 static int armada_370_pinctrl_probe(struct platform_device *pdev)
 {
        struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
 
        soc->variant = 0; /* no variants for Armada 370 */
        soc->controls = mv88f6710_mpp_controls;
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-375.c b/drivers/pinctrl/mvebu/pinctrl-armada-375.c
new file mode 100644 (file)
index 0000000..db078fe
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Marvell Armada 375 pinctrl driver based on mvebu pinctrl core
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+static void __iomem *mpp_base;
+
+static int armada_375_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int armada_375_mpp_ctrl_set(unsigned pid, unsigned long config)
+{
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
+static struct mvebu_mpp_mode mv88f6720_mpp_modes[] = {
+       MPP_MODE(0,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad2"),
+                MPP_FUNCTION(0x2, "spi0", "cs1"),
+                MPP_FUNCTION(0x3, "spi1", "cs1"),
+                MPP_FUNCTION(0x5, "nand", "io2")),
+       MPP_MODE(1,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad3"),
+                MPP_FUNCTION(0x2, "spi0", "mosi"),
+                MPP_FUNCTION(0x3, "spi1", "mosi"),
+                MPP_FUNCTION(0x5, "nand", "io3")),
+       MPP_MODE(2,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad4"),
+                MPP_FUNCTION(0x2, "ptp", "eventreq"),
+                MPP_FUNCTION(0x3, "led", "c0"),
+                MPP_FUNCTION(0x4, "audio", "sdi"),
+                MPP_FUNCTION(0x5, "nand", "io4"),
+                MPP_FUNCTION(0x6, "spi1", "mosi")),
+       MPP_MODE(3,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad5"),
+                MPP_FUNCTION(0x2, "ptp", "triggen"),
+                MPP_FUNCTION(0x3, "led", "p3"),
+                MPP_FUNCTION(0x4, "audio", "mclk"),
+                MPP_FUNCTION(0x5, "nand", "io5"),
+                MPP_FUNCTION(0x6, "spi1", "miso")),
+       MPP_MODE(4,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad6"),
+                MPP_FUNCTION(0x2, "spi0", "miso"),
+                MPP_FUNCTION(0x3, "spi1", "miso"),
+                MPP_FUNCTION(0x5, "nand", "io6")),
+       MPP_MODE(5,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad7"),
+                MPP_FUNCTION(0x2, "spi0", "cs2"),
+                MPP_FUNCTION(0x3, "spi1", "cs2"),
+                MPP_FUNCTION(0x5, "nand", "io7"),
+                MPP_FUNCTION(0x6, "spi1", "miso")),
+       MPP_MODE(6,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad0"),
+                MPP_FUNCTION(0x3, "led", "p1"),
+                MPP_FUNCTION(0x4, "audio", "rclk"),
+                MPP_FUNCTION(0x5, "nand", "io0")),
+       MPP_MODE(7,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "ad1"),
+                MPP_FUNCTION(0x2, "ptp", "clk"),
+                MPP_FUNCTION(0x3, "led", "p2"),
+                MPP_FUNCTION(0x4, "audio", "extclk"),
+                MPP_FUNCTION(0x5, "nand", "io1")),
+       MPP_MODE(8,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev ", "bootcs"),
+                MPP_FUNCTION(0x2, "spi0", "cs0"),
+                MPP_FUNCTION(0x3, "spi1", "cs0"),
+                MPP_FUNCTION(0x5, "nand", "ce")),
+       MPP_MODE(9,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "nf", "wen"),
+                MPP_FUNCTION(0x2, "spi0", "sck"),
+                MPP_FUNCTION(0x3, "spi1", "sck"),
+                MPP_FUNCTION(0x5, "nand", "we")),
+       MPP_MODE(10,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "nf", "ren"),
+                MPP_FUNCTION(0x2, "dram", "vttctrl"),
+                MPP_FUNCTION(0x3, "led", "c1"),
+                MPP_FUNCTION(0x5, "nand", "re"),
+                MPP_FUNCTION(0x6, "spi1", "sck")),
+       MPP_MODE(11,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "a0"),
+                MPP_FUNCTION(0x3, "led", "c2"),
+                MPP_FUNCTION(0x4, "audio", "sdo"),
+                MPP_FUNCTION(0x5, "nand", "cle")),
+       MPP_MODE(12,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "a1"),
+                MPP_FUNCTION(0x4, "audio", "bclk"),
+                MPP_FUNCTION(0x5, "nand", "ale")),
+       MPP_MODE(13,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "dev", "readyn"),
+                MPP_FUNCTION(0x2, "pcie0", "rstoutn"),
+                MPP_FUNCTION(0x3, "pcie1", "rstoutn"),
+                MPP_FUNCTION(0x5, "nand", "rb"),
+                MPP_FUNCTION(0x6, "spi1", "mosi")),
+       MPP_MODE(14,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "i2c0", "sda"),
+                MPP_FUNCTION(0x3, "uart1", "txd")),
+       MPP_MODE(15,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "i2c0", "sck"),
+                MPP_FUNCTION(0x3, "uart1", "rxd")),
+       MPP_MODE(16,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "uart0", "txd")),
+       MPP_MODE(17,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "uart0", "rxd")),
+       MPP_MODE(18,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "intn")),
+       MPP_MODE(19,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "rstn")),
+       MPP_MODE(20,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "pclk")),
+       MPP_MODE(21,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "fsync")),
+       MPP_MODE(22,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "drx")),
+       MPP_MODE(23,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "tdm", "dtx")),
+       MPP_MODE(24,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p0"),
+                MPP_FUNCTION(0x2, "ge1", "rxd0"),
+                MPP_FUNCTION(0x3, "sd", "cmd"),
+                MPP_FUNCTION(0x4, "uart0", "rts"),
+                MPP_FUNCTION(0x5, "spi0", "cs0"),
+                MPP_FUNCTION(0x6, "dev", "cs1")),
+       MPP_MODE(25,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p2"),
+                MPP_FUNCTION(0x2, "ge1", "rxd1"),
+                MPP_FUNCTION(0x3, "sd", "d0"),
+                MPP_FUNCTION(0x4, "uart0", "cts"),
+                MPP_FUNCTION(0x5, "spi0", "mosi"),
+                MPP_FUNCTION(0x6, "dev", "cs2")),
+       MPP_MODE(26,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie0", "clkreq"),
+                MPP_FUNCTION(0x2, "ge1", "rxd2"),
+                MPP_FUNCTION(0x3, "sd", "d2"),
+                MPP_FUNCTION(0x4, "uart1", "rts"),
+                MPP_FUNCTION(0x5, "spi0", "cs1"),
+                MPP_FUNCTION(0x6, "led", "c1")),
+       MPP_MODE(27,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie1", "clkreq"),
+                MPP_FUNCTION(0x2, "ge1", "rxd3"),
+                MPP_FUNCTION(0x3, "sd", "d1"),
+                MPP_FUNCTION(0x4, "uart1", "cts"),
+                MPP_FUNCTION(0x5, "spi0", "miso"),
+                MPP_FUNCTION(0x6, "led", "c2")),
+       MPP_MODE(28,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p3"),
+                MPP_FUNCTION(0x2, "ge1", "txctl"),
+                MPP_FUNCTION(0x3, "sd", "clk"),
+                MPP_FUNCTION(0x5, "dram", "vttctrl")),
+       MPP_MODE(29,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie1", "clkreq"),
+                MPP_FUNCTION(0x2, "ge1", "rxclk"),
+                MPP_FUNCTION(0x3, "sd", "d3"),
+                MPP_FUNCTION(0x5, "spi0", "sck"),
+                MPP_FUNCTION(0x6, "pcie0", "rstoutn")),
+       MPP_MODE(30,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "txd0"),
+                MPP_FUNCTION(0x3, "spi1", "cs0"),
+                MPP_FUNCTION(0x5, "led", "p3"),
+                MPP_FUNCTION(0x6, "ptp", "eventreq")),
+       MPP_MODE(31,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "txd1"),
+                MPP_FUNCTION(0x3, "spi1", "mosi"),
+                MPP_FUNCTION(0x5, "led", "p0")),
+       MPP_MODE(32,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "txd2"),
+                MPP_FUNCTION(0x3, "spi1", "sck"),
+                MPP_FUNCTION(0x4, "ptp", "triggen"),
+                MPP_FUNCTION(0x5, "led", "c0")),
+       MPP_MODE(33,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "txd3"),
+                MPP_FUNCTION(0x3, "spi1", "miso"),
+                MPP_FUNCTION(0x5, "led", "p2")),
+       MPP_MODE(34,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "txclkout"),
+                MPP_FUNCTION(0x3, "spi1", "sck"),
+                MPP_FUNCTION(0x5, "led", "c1")),
+       MPP_MODE(35,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge1", "rxctl"),
+                MPP_FUNCTION(0x3, "spi1", "cs1"),
+                MPP_FUNCTION(0x4, "spi0", "cs2"),
+                MPP_FUNCTION(0x5, "led", "p1")),
+       MPP_MODE(36,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie0", "clkreq"),
+                MPP_FUNCTION(0x5, "led", "c2")),
+       MPP_MODE(37,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie0", "clkreq"),
+                MPP_FUNCTION(0x2, "tdm", "intn"),
+                MPP_FUNCTION(0x4, "ge", "mdc")),
+       MPP_MODE(38,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie1", "clkreq"),
+                MPP_FUNCTION(0x4, "ge", "mdio")),
+       MPP_MODE(39,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "ref", "clkout"),
+                MPP_FUNCTION(0x5, "led", "p3")),
+       MPP_MODE(40,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "uart1", "txd"),
+                MPP_FUNCTION(0x5, "led", "p0")),
+       MPP_MODE(41,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "uart1", "rxd"),
+                MPP_FUNCTION(0x5, "led", "p1")),
+       MPP_MODE(42,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x3, "spi1", "cs2"),
+                MPP_FUNCTION(0x4, "led", "c0"),
+                MPP_FUNCTION(0x6, "ptp", "clk")),
+       MPP_MODE(43,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "sata0", "prsnt"),
+                MPP_FUNCTION(0x4, "dram", "vttctrl"),
+                MPP_FUNCTION(0x5, "led", "c1")),
+       MPP_MODE(44,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "sata0", "prsnt")),
+       MPP_MODE(45,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "spi0", "cs2"),
+                MPP_FUNCTION(0x4, "pcie0", "rstoutn"),
+                MPP_FUNCTION(0x5, "led", "c2"),
+                MPP_FUNCTION(0x6, "spi1", "cs2")),
+       MPP_MODE(46,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p0"),
+                MPP_FUNCTION(0x2, "ge0", "txd0"),
+                MPP_FUNCTION(0x3, "ge1", "txd0"),
+                MPP_FUNCTION(0x6, "dev", "wen1")),
+       MPP_MODE(47,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p1"),
+                MPP_FUNCTION(0x2, "ge0", "txd1"),
+                MPP_FUNCTION(0x3, "ge1", "txd1"),
+                MPP_FUNCTION(0x5, "ptp", "triggen"),
+                MPP_FUNCTION(0x6, "dev", "ale0")),
+       MPP_MODE(48,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p2"),
+                MPP_FUNCTION(0x2, "ge0", "txd2"),
+                MPP_FUNCTION(0x3, "ge1", "txd2"),
+                MPP_FUNCTION(0x6, "dev", "ale1")),
+       MPP_MODE(49,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "p3"),
+                MPP_FUNCTION(0x2, "ge0", "txd3"),
+                MPP_FUNCTION(0x3, "ge1", "txd3"),
+                MPP_FUNCTION(0x6, "dev", "a2")),
+       MPP_MODE(50,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "c0"),
+                MPP_FUNCTION(0x2, "ge0", "rxd0"),
+                MPP_FUNCTION(0x3, "ge1", "rxd0"),
+                MPP_FUNCTION(0x5, "ptp", "eventreq"),
+                MPP_FUNCTION(0x6, "dev", "ad12")),
+       MPP_MODE(51,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "c1"),
+                MPP_FUNCTION(0x2, "ge0", "rxd1"),
+                MPP_FUNCTION(0x3, "ge1", "rxd1"),
+                MPP_FUNCTION(0x6, "dev", "ad8")),
+       MPP_MODE(52,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "led", "c2"),
+                MPP_FUNCTION(0x2, "ge0", "rxd2"),
+                MPP_FUNCTION(0x3, "ge1", "rxd2"),
+                MPP_FUNCTION(0x5, "i2c0", "sda"),
+                MPP_FUNCTION(0x6, "dev", "ad9")),
+       MPP_MODE(53,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie1", "rstoutn"),
+                MPP_FUNCTION(0x2, "ge0", "rxd3"),
+                MPP_FUNCTION(0x3, "ge1", "rxd3"),
+                MPP_FUNCTION(0x5, "i2c0", "sck"),
+                MPP_FUNCTION(0x6, "dev", "ad10")),
+       MPP_MODE(54,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "pcie0", "rstoutn"),
+                MPP_FUNCTION(0x2, "ge0", "rxctl"),
+                MPP_FUNCTION(0x3, "ge1", "rxctl"),
+                MPP_FUNCTION(0x6, "dev", "ad11")),
+       MPP_MODE(55,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge0", "rxclk"),
+                MPP_FUNCTION(0x3, "ge1", "rxclk"),
+                MPP_FUNCTION(0x6, "dev", "cs0")),
+       MPP_MODE(56,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge0", "txclkout"),
+                MPP_FUNCTION(0x3, "ge1", "txclkout"),
+                MPP_FUNCTION(0x6, "dev", "oe")),
+       MPP_MODE(57,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ge0", "txctl"),
+                MPP_FUNCTION(0x3, "ge1", "txctl"),
+                MPP_FUNCTION(0x6, "dev", "wen0")),
+       MPP_MODE(58,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "led", "c0")),
+       MPP_MODE(59,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x4, "led", "c1")),
+       MPP_MODE(60,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "uart1", "txd"),
+                MPP_FUNCTION(0x4, "led", "c2"),
+                MPP_FUNCTION(0x6, "dev", "ad13")),
+       MPP_MODE(61,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "i2c1", "sda"),
+                MPP_FUNCTION(0x2, "uart1", "rxd"),
+                MPP_FUNCTION(0x3, "spi1", "cs2"),
+                MPP_FUNCTION(0x4, "led", "p0"),
+                MPP_FUNCTION(0x6, "dev", "ad14")),
+       MPP_MODE(62,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "i2c1", "sck"),
+                MPP_FUNCTION(0x4, "led", "p1"),
+                MPP_FUNCTION(0x6, "dev", "ad15")),
+       MPP_MODE(63,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ptp", "triggen"),
+                MPP_FUNCTION(0x4, "led", "p2"),
+                MPP_FUNCTION(0x6, "dev", "burst")),
+       MPP_MODE(64,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "dram", "vttctrl"),
+                MPP_FUNCTION(0x4, "led", "p3")),
+       MPP_MODE(65,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x1, "sata1", "prsnt")),
+       MPP_MODE(66,
+                MPP_FUNCTION(0x0, "gpio", NULL),
+                MPP_FUNCTION(0x2, "ptp", "eventreq"),
+                MPP_FUNCTION(0x4, "spi1", "cs3"),
+                MPP_FUNCTION(0x5, "pcie0", "rstoutn"),
+                MPP_FUNCTION(0x6, "dev", "cs3")),
+};
+
+static struct mvebu_pinctrl_soc_info armada_375_pinctrl_info;
+
+static struct of_device_id armada_375_pinctrl_of_match[] = {
+       { .compatible = "marvell,mv88f6720-pinctrl" },
+       { },
+};
+
+static struct mvebu_mpp_ctrl mv88f6720_mpp_controls[] = {
+       MPP_FUNC_CTRL(0, 69, NULL, armada_375_mpp_ctrl),
+};
+
+static struct pinctrl_gpio_range mv88f6720_mpp_gpio_ranges[] = {
+       MPP_GPIO_RANGE(0,   0,  0, 32),
+       MPP_GPIO_RANGE(1,  32, 32, 32),
+       MPP_GPIO_RANGE(2,  64, 64,  3),
+};
+
+static int armada_375_pinctrl_probe(struct platform_device *pdev)
+{
+       struct mvebu_pinctrl_soc_info *soc = &armada_375_pinctrl_info;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
+
+       soc->variant = 0; /* no variants for Armada 375 */
+       soc->controls = mv88f6720_mpp_controls;
+       soc->ncontrols = ARRAY_SIZE(mv88f6720_mpp_controls);
+       soc->modes = mv88f6720_mpp_modes;
+       soc->nmodes = ARRAY_SIZE(mv88f6720_mpp_modes);
+       soc->gpioranges = mv88f6720_mpp_gpio_ranges;
+       soc->ngpioranges = ARRAY_SIZE(mv88f6720_mpp_gpio_ranges);
+
+       pdev->dev.platform_data = soc;
+
+       return mvebu_pinctrl_probe(pdev);
+}
+
+static int armada_375_pinctrl_remove(struct platform_device *pdev)
+{
+       return mvebu_pinctrl_remove(pdev);
+}
+
+static struct platform_driver armada_375_pinctrl_driver = {
+       .driver = {
+               .name = "armada-375-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(armada_375_pinctrl_of_match),
+       },
+       .probe = armada_375_pinctrl_probe,
+       .remove = armada_375_pinctrl_remove,
+};
+
+module_platform_driver(armada_375_pinctrl_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Armada 375 pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c
new file mode 100644 (file)
index 0000000..1049f82
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * Marvell Armada 380/385 pinctrl driver based on mvebu pinctrl core
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-mvebu.h"
+
+static void __iomem *mpp_base;
+
+static int armada_38x_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int armada_38x_mpp_ctrl_set(unsigned pid, unsigned long config)
+{
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
+enum {
+       V_88F6810 = BIT(0),
+       V_88F6820 = BIT(1),
+       V_88F6828 = BIT(2),
+       V_88F6810_PLUS = (V_88F6810 | V_88F6820 | V_88F6828),
+       V_88F6820_PLUS = (V_88F6820 | V_88F6828),
+};
+
+static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
+       MPP_MODE(0,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua0",   "rxd",        V_88F6810_PLUS)),
+       MPP_MODE(1,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua0",   "txd",        V_88F6810_PLUS)),
+       MPP_MODE(2,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "i2c0",  "sck",        V_88F6810_PLUS)),
+       MPP_MODE(3,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "i2c0",  "sda",        V_88F6810_PLUS)),
+       MPP_MODE(4,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge",    "mdc",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ua1",   "txd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS)),
+       MPP_MODE(5,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge",    "mdio",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ua1",   "rxd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS)),
+       MPP_MODE(6,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txclkout",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge0",   "crs",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "cs3",        V_88F6810_PLUS)),
+       MPP_MODE(7,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txd0",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad9",        V_88F6810_PLUS)),
+       MPP_MODE(8,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txd1",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad10",       V_88F6810_PLUS)),
+       MPP_MODE(9,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txd2",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad11",       V_88F6810_PLUS)),
+       MPP_MODE(10,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txd3",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad12",       V_88F6810_PLUS)),
+       MPP_MODE(11,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txctl",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad13",       V_88F6810_PLUS)),
+       MPP_MODE(12,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxd0",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "cs1",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad14",       V_88F6810_PLUS)),
+       MPP_MODE(13,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxd1",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie0", "clkreq",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "clkreq",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "cs2",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad15",       V_88F6810_PLUS)),
+       MPP_MODE(14,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxd2",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "m",     "vtt_ctrl",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "cs3",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "wen1",       V_88F6810_PLUS)),
+       MPP_MODE(15,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxd3",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge",    "mdc slave",  V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "mosi",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "pcie1", "rstout",     V_88F6820_PLUS)),
+       MPP_MODE(16,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxctl",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge",    "mdio slave", V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "m",     "decc_err",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "miso",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "pcie0", "clkreq",     V_88F6810_PLUS)),
+       MPP_MODE(17,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxclk",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua1",   "rxd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sata1", "prsnt",      V_88F6810_PLUS)),
+       MPP_MODE(18,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "rxerr",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ptp",   "trig_gen",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua1",   "txd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi0",  "cs0",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "pcie1", "rstout",     V_88F6820_PLUS)),
+       MPP_MODE(19,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "col",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ptp",   "event_req",  V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie0", "clkreq",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sata1", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "ua0",   "cts",        V_88F6810_PLUS)),
+       MPP_MODE(20,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ge0",   "txclk",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "ua0",   "rts",        V_88F6810_PLUS)),
+       MPP_MODE(21,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "cs1",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxd0",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "cmd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "bootcs",     V_88F6810_PLUS)),
+       MPP_MODE(22,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "mosi",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad0",        V_88F6810_PLUS)),
+       MPP_MODE(23,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad2",        V_88F6810_PLUS)),
+       MPP_MODE(24,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "miso",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ua0",   "cts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua1",   "rxd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d4",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ready",      V_88F6810_PLUS)),
+       MPP_MODE(25,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "cs0",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ua0",   "rts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua1",   "txd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d5",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "cs0",        V_88F6810_PLUS)),
+       MPP_MODE(26,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "cs2",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "i2c1",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d6",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "cs1",        V_88F6810_PLUS)),
+       MPP_MODE(27,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "spi0",  "cs3",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txclkout",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "i2c1",  "sda",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d7",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "cs2",        V_88F6810_PLUS)),
+       MPP_MODE(28,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txd0",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "clk",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad5",        V_88F6810_PLUS)),
+       MPP_MODE(29,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txd1",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ale0",       V_88F6810_PLUS)),
+       MPP_MODE(30,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txd2",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "oen",        V_88F6810_PLUS)),
+       MPP_MODE(31,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txd3",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ale1",       V_88F6810_PLUS)),
+       MPP_MODE(32,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "txctl",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "wen0",       V_88F6810_PLUS)),
+       MPP_MODE(33,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "m",     "decc_err",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad3",        V_88F6810_PLUS)),
+       MPP_MODE(34,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad1",        V_88F6810_PLUS)),
+       MPP_MODE(35,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ref",   "clk_out1",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "a1",         V_88F6810_PLUS)),
+       MPP_MODE(36,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ptp",   "trig_gen",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "a0",         V_88F6810_PLUS)),
+       MPP_MODE(37,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ptp",   "clk",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxclk",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d3",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad8",        V_88F6810_PLUS)),
+       MPP_MODE(38,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ptp",   "event_req",  V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxd1",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ref",   "clk_out0",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d0",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad4",        V_88F6810_PLUS)),
+       MPP_MODE(39,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "i2c1",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxd2",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d1",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "a2",         V_88F6810_PLUS)),
+       MPP_MODE(40,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "i2c1",  "sda",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxd3",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "sd0",   "d2",         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad6",        V_88F6810_PLUS)),
+       MPP_MODE(41,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua1",   "rxd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge1",   "rxctl",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "cs3",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "burst/last", V_88F6810_PLUS)),
+       MPP_MODE(42,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua1",   "txd",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "ad7",        V_88F6810_PLUS)),
+       MPP_MODE(43,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "pcie0", "clkreq",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "m",     "vtt_ctrl",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "m",     "decc_err",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "dev",   "clkout",     V_88F6810_PLUS)),
+       MPP_MODE(44,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "sata2", "prsnt",      V_88F6828),
+                MPP_VAR_FUNCTION(4, "sata3", "prsnt",      V_88F6828),
+                MPP_VAR_FUNCTION(5, "pcie0", "rstout",     V_88F6810_PLUS)),
+       MPP_MODE(45,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ref",   "clk_out0",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "pcie2", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "pcie3", "rstout",     V_88F6810_PLUS)),
+       MPP_MODE(46,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ref",   "clk_out1",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "pcie2", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "pcie3", "rstout",     V_88F6810_PLUS)),
+       MPP_MODE(47,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "sata2", "prsnt",      V_88F6828),
+                MPP_VAR_FUNCTION(4, "spi1",  "cs2",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sata3", "prsnt",      V_88F6828)),
+       MPP_MODE(48,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "m",     "vtt_ctrl",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "tdm2c", "pclk",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "mclk",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d4",         V_88F6810_PLUS)),
+       MPP_MODE(49,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata2", "prsnt",      V_88F6828),
+                MPP_VAR_FUNCTION(2, "sata3", "prsnt",      V_88F6828),
+                MPP_VAR_FUNCTION(3, "tdm2c", "fsync",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "lrclk",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d5",         V_88F6810_PLUS)),
+       MPP_MODE(50,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(3, "tdm2c", "drx",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "extclk",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "cmd",        V_88F6810_PLUS)),
+       MPP_MODE(51,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "tdm2c", "dtx",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "sdo",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "m",     "decc_err",   V_88F6810_PLUS)),
+       MPP_MODE(52,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(3, "tdm2c", "intn",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "sdi",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d6",         V_88F6810_PLUS)),
+       MPP_MODE(53,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata1", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "tdm2c", "rstn",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "audio", "bclk",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d7",         V_88F6810_PLUS)),
+       MPP_MODE(54,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d3",         V_88F6810_PLUS)),
+       MPP_MODE(55,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua1",   "cts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge",    "mdio",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "clkreq",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "cs1",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d0",         V_88F6810_PLUS)),
+       MPP_MODE(56,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "ua1",   "rts",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "ge",    "mdc",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "m",     "decc_err",   V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "mosi",       V_88F6810_PLUS)),
+       MPP_MODE(57,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "clk",        V_88F6810_PLUS)),
+       MPP_MODE(58,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "pcie1", "clkreq",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(2, "i2c1",  "sck",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie2", "clkreq",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "miso",       V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d1",         V_88F6810_PLUS)),
+       MPP_MODE(59,
+                MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(2, "i2c1",  "sda",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(3, "pcie1", "rstout",     V_88F6820_PLUS),
+                MPP_VAR_FUNCTION(4, "spi1",  "cs0",        V_88F6810_PLUS),
+                MPP_VAR_FUNCTION(5, "sd0",   "d2",         V_88F6810_PLUS)),
+};
+
+static struct mvebu_pinctrl_soc_info armada_38x_pinctrl_info;
+
+static struct of_device_id armada_38x_pinctrl_of_match[] = {
+       {
+               .compatible = "marvell,mv88f6810-pinctrl",
+               .data       = (void *) V_88F6810,
+       },
+       {
+               .compatible = "marvell,mv88f6820-pinctrl",
+               .data       = (void *) V_88F6820,
+       },
+       {
+               .compatible = "marvell,mv88f6828-pinctrl",
+               .data       = (void *) V_88F6828,
+       },
+       { },
+};
+
+static struct mvebu_mpp_ctrl armada_38x_mpp_controls[] = {
+       MPP_FUNC_CTRL(0, 59, NULL, armada_38x_mpp_ctrl),
+};
+
+static struct pinctrl_gpio_range armada_38x_mpp_gpio_ranges[] = {
+       MPP_GPIO_RANGE(0,   0,  0, 32),
+       MPP_GPIO_RANGE(1,  32, 32, 27),
+};
+
+static int armada_38x_pinctrl_probe(struct platform_device *pdev)
+{
+       struct mvebu_pinctrl_soc_info *soc = &armada_38x_pinctrl_info;
+       const struct of_device_id *match =
+               of_match_device(armada_38x_pinctrl_of_match, &pdev->dev);
+       struct resource *res;
+
+       if (!match)
+               return -ENODEV;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
+
+       soc->variant = (unsigned) match->data & 0xff;
+       soc->controls = armada_38x_mpp_controls;
+       soc->ncontrols = ARRAY_SIZE(armada_38x_mpp_controls);
+       soc->gpioranges = armada_38x_mpp_gpio_ranges;
+       soc->ngpioranges = ARRAY_SIZE(armada_38x_mpp_gpio_ranges);
+       soc->modes = armada_38x_mpp_modes;
+       soc->nmodes = armada_38x_mpp_controls[0].npins;
+
+       pdev->dev.platform_data = soc;
+
+       return mvebu_pinctrl_probe(pdev);
+}
+
+static int armada_38x_pinctrl_remove(struct platform_device *pdev)
+{
+       return mvebu_pinctrl_remove(pdev);
+}
+
+static struct platform_driver armada_38x_pinctrl_driver = {
+       .driver = {
+               .name = "armada-38x-pinctrl",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(armada_38x_pinctrl_of_match),
+       },
+       .probe = armada_38x_pinctrl_probe,
+       .remove = armada_38x_pinctrl_remove,
+};
+
+module_platform_driver(armada_38x_pinctrl_driver);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Armada 38x pinctrl driver");
+MODULE_LICENSE("GPL v2");
index 843a51f9d129c2d1ac6c95c202a06b07bcd24c06..de311129f7a020473acc3b46ee9ede902df86c9d 100644 (file)
 
 #include "pinctrl-mvebu.h"
 
+static void __iomem *mpp_base;
+
+static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int armada_xp_mpp_ctrl_set(unsigned pid, unsigned long config)
+{
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
 enum armada_xp_variant {
        V_MV78230       = BIT(0),
        V_MV78260       = BIT(1),
@@ -366,7 +378,7 @@ static struct of_device_id armada_xp_pinctrl_of_match[] = {
 };
 
 static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
-       MPP_REG_CTRL(0, 48),
+       MPP_FUNC_CTRL(0, 48, NULL, armada_xp_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
@@ -375,7 +387,7 @@ static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
 };
 
 static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
-       MPP_REG_CTRL(0, 66),
+       MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
@@ -385,7 +397,7 @@ static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
 };
 
 static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
-       MPP_REG_CTRL(0, 66),
+       MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
@@ -399,10 +411,16 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
        struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
        const struct of_device_id *match =
                of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
+       struct resource *res;
 
        if (!match)
                return -ENODEV;
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
+
        soc->variant = (unsigned) match->data & 0xff;
 
        switch (soc->variant) {
index 47268393af34689832fd189bde3c9da27eb6c090..9e7ff651c018dff43704b8787e958f8d4dada90b 100644 (file)
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/regmap.h>
 
 #include "pinctrl-mvebu.h"
 
-#define DOVE_SB_REGS_VIRT_BASE         IOMEM(0xfde00000)
-#define DOVE_MPP_VIRT_BASE             (DOVE_SB_REGS_VIRT_BASE + 0xd0200)
-#define DOVE_PMU_MPP_GENERAL_CTRL      (DOVE_MPP_VIRT_BASE + 0x10)
-#define  DOVE_AU0_AC97_SEL             BIT(16)
-#define DOVE_PMU_SIGNAL_SELECT_0       (DOVE_SB_REGS_VIRT_BASE + 0xd802C)
-#define DOVE_PMU_SIGNAL_SELECT_1       (DOVE_SB_REGS_VIRT_BASE + 0xd8030)
-#define DOVE_GLOBAL_CONFIG_1           (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
-#define DOVE_GLOBAL_CONFIG_1           (DOVE_SB_REGS_VIRT_BASE + 0xe802C)
-#define  DOVE_TWSI_ENABLE_OPTION1      BIT(7)
-#define DOVE_GLOBAL_CONFIG_2           (DOVE_SB_REGS_VIRT_BASE + 0xe8030)
-#define  DOVE_TWSI_ENABLE_OPTION2      BIT(20)
-#define  DOVE_TWSI_ENABLE_OPTION3      BIT(21)
-#define  DOVE_TWSI_OPTION3_GPIO                BIT(22)
-#define DOVE_SSP_CTRL_STATUS_1         (DOVE_SB_REGS_VIRT_BASE + 0xe8034)
-#define  DOVE_SSP_ON_AU1               BIT(0)
-#define DOVE_MPP_GENERAL_VIRT_BASE     (DOVE_SB_REGS_VIRT_BASE + 0xe803c)
-#define  DOVE_AU1_SPDIFO_GPIO_EN       BIT(1)
-#define  DOVE_NAND_GPIO_EN             BIT(0)
-#define DOVE_GPIO_LO_VIRT_BASE         (DOVE_SB_REGS_VIRT_BASE + 0xd0400)
-#define DOVE_MPP_CTRL4_VIRT_BASE       (DOVE_GPIO_LO_VIRT_BASE + 0x40)
-#define  DOVE_SPI_GPIO_SEL             BIT(5)
-#define  DOVE_UART1_GPIO_SEL           BIT(4)
-#define  DOVE_AU1_GPIO_SEL             BIT(3)
-#define  DOVE_CAM_GPIO_SEL             BIT(2)
-#define  DOVE_SD1_GPIO_SEL             BIT(1)
-#define  DOVE_SD0_GPIO_SEL             BIT(0)
-
-#define MPPS_PER_REG   8
-#define MPP_BITS       4
-#define MPP_MASK       0xf
+/* Internal registers can be configured at any 1 MiB aligned address */
+#define INT_REGS_MASK          ~(SZ_1M - 1)
+#define MPP4_REGS_OFFS         0xd0440
+#define PMU_REGS_OFFS          0xd802c
+#define GC_REGS_OFFS           0xe802c
+
+/* MPP Base registers */
+#define PMU_MPP_GENERAL_CTRL   0x10
+#define  AU0_AC97_SEL          BIT(16)
+
+/* MPP Control 4 register */
+#define SPI_GPIO_SEL           BIT(5)
+#define UART1_GPIO_SEL         BIT(4)
+#define AU1_GPIO_SEL           BIT(3)
+#define CAM_GPIO_SEL           BIT(2)
+#define SD1_GPIO_SEL           BIT(1)
+#define SD0_GPIO_SEL           BIT(0)
+
+/* PMU Signal Select registers */
+#define PMU_SIGNAL_SELECT_0    0x00
+#define PMU_SIGNAL_SELECT_1    0x04
+
+/* Global Config regmap registers */
+#define GLOBAL_CONFIG_1                0x00
+#define  TWSI_ENABLE_OPTION1   BIT(7)
+#define GLOBAL_CONFIG_2                0x04
+#define  TWSI_ENABLE_OPTION2   BIT(20)
+#define  TWSI_ENABLE_OPTION3   BIT(21)
+#define  TWSI_OPTION3_GPIO     BIT(22)
+#define SSP_CTRL_STATUS_1      0x08
+#define  SSP_ON_AU1            BIT(0)
+#define MPP_GENERAL_CONFIG     0x10
+#define  AU1_SPDIFO_GPIO_EN    BIT(1)
+#define  NAND_GPIO_EN          BIT(0)
 
 #define CONFIG_PMU     BIT(4)
 
-static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                                unsigned long *config)
+static void __iomem *mpp_base;
+static void __iomem *mpp4_base;
+static void __iomem *pmu_base;
+static struct regmap *gconfmap;
+
+static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int dove_mpp_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
-       unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
-       unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
+static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
        unsigned long func;
 
-       if (pmu & (1 << ctrl->pid)) {
-               func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
-               *config = (func >> shift) & MPP_MASK;
-               *config |= CONFIG_PMU;
-       } else {
-               func = readl(DOVE_MPP_VIRT_BASE + off);
-               *config = (func >> shift) & MPP_MASK;
-       }
+       if ((pmu & BIT(pid)) == 0)
+               return default_mpp_ctrl_get(mpp_base, pid, config);
+
+       func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
+       *config = (func >> shift) & MVEBU_MPP_MASK;
+       *config |= CONFIG_PMU;
+
        return 0;
 }
 
-static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                                unsigned long config)
+static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
-       unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
-       unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+       unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
        unsigned long func;
 
-       if (config & CONFIG_PMU) {
-               writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
-               func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
-               func &= ~(MPP_MASK << shift);
-               func |= (config & MPP_MASK) << shift;
-               writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
-       } else {
-               writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
-               func = readl(DOVE_MPP_VIRT_BASE + off);
-               func &= ~(MPP_MASK << shift);
-               func |= (config & MPP_MASK) << shift;
-               writel(func, DOVE_MPP_VIRT_BASE + off);
+       if ((config & CONFIG_PMU) == 0) {
+               writel(pmu & ~BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
+               return default_mpp_ctrl_set(mpp_base, pid, config);
        }
+
+       writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
+       func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
+       func &= ~(MVEBU_MPP_MASK << shift);
+       func |= (config & MVEBU_MPP_MASK) << shift;
+       writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);
+
        return 0;
 }
 
-static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                             unsigned long *config)
+static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
 {
-       unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+       unsigned long mpp4 = readl(mpp4_base);
        unsigned long mask;
 
-       switch (ctrl->pid) {
+       switch (pid) {
        case 24: /* mpp_camera */
-               mask = DOVE_CAM_GPIO_SEL;
+               mask = CAM_GPIO_SEL;
                break;
        case 40: /* mpp_sdio0 */
-               mask = DOVE_SD0_GPIO_SEL;
+               mask = SD0_GPIO_SEL;
                break;
        case 46: /* mpp_sdio1 */
-               mask = DOVE_SD1_GPIO_SEL;
+               mask = SD1_GPIO_SEL;
                break;
        case 58: /* mpp_spi0 */
-               mask = DOVE_SPI_GPIO_SEL;
+               mask = SPI_GPIO_SEL;
                break;
        case 62: /* mpp_uart1 */
-               mask = DOVE_UART1_GPIO_SEL;
+               mask = UART1_GPIO_SEL;
                break;
        default:
                return -EINVAL;
@@ -129,27 +144,26 @@ static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
        return 0;
 }
 
-static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                             unsigned long config)
+static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+       unsigned long mpp4 = readl(mpp4_base);
        unsigned long mask;
 
-       switch (ctrl->pid) {
+       switch (pid) {
        case 24: /* mpp_camera */
-               mask = DOVE_CAM_GPIO_SEL;
+               mask = CAM_GPIO_SEL;
                break;
        case 40: /* mpp_sdio0 */
-               mask = DOVE_SD0_GPIO_SEL;
+               mask = SD0_GPIO_SEL;
                break;
        case 46: /* mpp_sdio1 */
-               mask = DOVE_SD1_GPIO_SEL;
+               mask = SD1_GPIO_SEL;
                break;
        case 58: /* mpp_spi0 */
-               mask = DOVE_SPI_GPIO_SEL;
+               mask = SPI_GPIO_SEL;
                break;
        case 62: /* mpp_uart1 */
-               mask = DOVE_UART1_GPIO_SEL;
+               mask = UART1_GPIO_SEL;
                break;
        default:
                return -EINVAL;
@@ -159,74 +173,69 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
        if (config)
                mpp4 |= mask;
 
-       writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
+       writel(mpp4, mpp4_base);
 
        return 0;
 }
 
-static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                             unsigned long *config)
+static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
 {
-       unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+       unsigned int gmpp;
 
-       *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0);
+       regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
+       *config = ((gmpp & NAND_GPIO_EN) != 0);
 
        return 0;
 }
 
-static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                             unsigned long config)
+static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
-
-       gmpp &= ~DOVE_NAND_GPIO_EN;
-       if (config)
-               gmpp |= DOVE_NAND_GPIO_EN;
-
-       writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
-
+       regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
+                          NAND_GPIO_EN,
+                          (config) ? NAND_GPIO_EN : 0);
        return 0;
 }
 
-static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                               unsigned long *config)
+static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
 {
-       unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
 
-       *config = ((pmu & DOVE_AU0_AC97_SEL) != 0);
+       *config = ((pmu & AU0_AC97_SEL) != 0);
 
        return 0;
 }
 
-static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                               unsigned long config)
+static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
+       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
 
-       pmu &= ~DOVE_AU0_AC97_SEL;
+       pmu &= ~AU0_AC97_SEL;
        if (config)
-               pmu |= DOVE_AU0_AC97_SEL;
-       writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL);
+               pmu |= AU0_AC97_SEL;
+       writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL);
 
        return 0;
 }
 
-static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                               unsigned long *config)
+static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
 {
-       unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
-       unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
-       unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
-       unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+       unsigned int mpp4 = readl(mpp4_base);
+       unsigned int sspc1;
+       unsigned int gmpp;
+       unsigned int gcfg2;
+
+       regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);
+       regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
+       regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
 
        *config = 0;
-       if (mpp4 & DOVE_AU1_GPIO_SEL)
+       if (mpp4 & AU1_GPIO_SEL)
                *config |= BIT(3);
-       if (sspc1 & DOVE_SSP_ON_AU1)
+       if (sspc1 & SSP_ON_AU1)
                *config |= BIT(2);
-       if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN)
+       if (gmpp & AU1_SPDIFO_GPIO_EN)
                *config |= BIT(1);
-       if (gcfg2 & DOVE_TWSI_OPTION3_GPIO)
+       if (gcfg2 & TWSI_OPTION3_GPIO)
                *config |= BIT(0);
 
        /* SSP/TWSI only if I2S1 not set*/
@@ -238,35 +247,24 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
        return 0;
 }
 
-static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                               unsigned long config)
+static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
-       unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
-       unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
-       unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+       unsigned int mpp4 = readl(mpp4_base);
 
-       /*
-        * clear all audio1 related bits before configure
-        */
-       gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO;
-       gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN;
-       sspc1 &= ~DOVE_SSP_ON_AU1;
-       mpp4 &= ~DOVE_AU1_GPIO_SEL;
-
-       if (config & BIT(0))
-               gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
-       if (config & BIT(1))
-               gmpp |= DOVE_AU1_SPDIFO_GPIO_EN;
-       if (config & BIT(2))
-               sspc1 |= DOVE_SSP_ON_AU1;
+       mpp4 &= ~AU1_GPIO_SEL;
        if (config & BIT(3))
-               mpp4 |= DOVE_AU1_GPIO_SEL;
-
-       writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE);
-       writel(sspc1, DOVE_SSP_CTRL_STATUS_1);
-       writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE);
-       writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+               mpp4 |= AU1_GPIO_SEL;
+       writel(mpp4, mpp4_base);
+
+       regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,
+                          SSP_ON_AU1,
+                          (config & BIT(2)) ? SSP_ON_AU1 : 0);
+       regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
+                          AU1_SPDIFO_GPIO_EN,
+                          (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);
+       regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
+                          TWSI_OPTION3_GPIO,
+                          (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);
 
        return 0;
 }
@@ -276,11 +274,11 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
  * break other functions. If you require all mpps as gpio
  * enforce gpio setting by pinctrl mapping.
  */
-static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
+static int dove_audio1_ctrl_gpio_req(unsigned pid)
 {
        unsigned long config;
 
-       dove_audio1_ctrl_get(ctrl, &config);
+       dove_audio1_ctrl_get(pid, &config);
 
        switch (config) {
        case 0x02: /* i2s1 : gpio[56:57] */
@@ -303,76 +301,62 @@ static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
 }
 
 /* mpp[52:57] has gpio pins capable of in and out */
-static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
-                               bool input)
+static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
 {
        if (pid < 52 || pid > 57)
                return -ENOTSUPP;
        return 0;
 }
 
-static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
-                             unsigned long *config)
+static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
 {
-       unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
-       unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
+       unsigned int gcfg1;
+       unsigned int gcfg2;
+
+       regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);
+       regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
 
        *config = 0;
-       if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1)
+       if (gcfg1 & TWSI_ENABLE_OPTION1)
                *config = 1;
-       else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2)
+       else if (gcfg2 & TWSI_ENABLE_OPTION2)
                *config = 2;
-       else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3)
+       else if (gcfg2 & TWSI_ENABLE_OPTION3)
                *config = 3;
 
        return 0;
 }
 
-static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
-                               unsigned long config)
+static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
 {
-       unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
-       unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
-
-       gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1;
-       gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION3);
+       unsigned int gcfg1 = 0;
+       unsigned int gcfg2 = 0;
 
        switch (config) {
        case 1:
-               gcfg1 |= DOVE_TWSI_ENABLE_OPTION1;
+               gcfg1 TWSI_ENABLE_OPTION1;
                break;
        case 2:
-               gcfg2 |= DOVE_TWSI_ENABLE_OPTION2;
+               gcfg2 TWSI_ENABLE_OPTION2;
                break;
        case 3:
-               gcfg2 |= DOVE_TWSI_ENABLE_OPTION3;
+               gcfg2 TWSI_ENABLE_OPTION3;
                break;
        }
 
-       writel(gcfg1, DOVE_GLOBAL_CONFIG_1);
-       writel(gcfg2, DOVE_GLOBAL_CONFIG_2);
+       regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,
+                          TWSI_ENABLE_OPTION1,
+                          gcfg1);
+       regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
+                          TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,
+                          gcfg2);
 
        return 0;
 }
 
 static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
-       MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
-       MPP_REG_CTRL(16, 23),
+       MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
+       MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
        MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
        MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
        MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
@@ -772,8 +756,17 @@ static struct of_device_id dove_pinctrl_of_match[] = {
        { }
 };
 
+static struct regmap_config gc_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = 5,
+};
+
 static int dove_pinctrl_probe(struct platform_device *pdev)
 {
+       struct resource *res, *mpp_res;
+       struct resource fb_res;
        const struct of_device_id *match =
                of_match_device(dove_pinctrl_of_match, &pdev->dev);
        pdev->dev.platform_data = (void *)match->data;
@@ -789,6 +782,58 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
        }
        clk_prepare_enable(clk);
 
+       mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, mpp_res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
+
+       /* prepare fallback resource */
+       memcpy(&fb_res, mpp_res, sizeof(struct resource));
+       fb_res.start = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res) {
+               dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n");
+               adjust_resource(&fb_res,
+                       (mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4);
+               res = &fb_res;
+       }
+
+       mpp4_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp4_base))
+               return PTR_ERR(mpp4_base);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+       if (!res) {
+               dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n");
+               adjust_resource(&fb_res,
+                       (mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8);
+               res = &fb_res;
+       }
+
+       pmu_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(pmu_base))
+               return PTR_ERR(pmu_base);
+
+       gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");
+       if (IS_ERR(gconfmap)) {
+               void __iomem *gc_base;
+
+               dev_warn(&pdev->dev, "falling back to hardcoded global registers\n");
+               adjust_resource(&fb_res,
+                       (mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);
+               gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);
+               if (IS_ERR(gc_base))
+                       return PTR_ERR(gc_base);
+               gconfmap = devm_regmap_init_mmio(&pdev->dev,
+                                                gc_base, &gc_regmap_config);
+               if (IS_ERR(gconfmap))
+                       return PTR_ERR(gconfmap);
+       }
+
+       /* Warn on any missing DT resource */
+       WARN(fb_res.start, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");
+
        return mvebu_pinctrl_probe(pdev);
 }
 
index 6b504b5935a5ec75ecff507a0717e82af4b72982..0d0211a1a0b005659a4ddbe557c46fd8dbe1d521 100644 (file)
 
 #include "pinctrl-mvebu.h"
 
+static void __iomem *mpp_base;
+
+static int kirkwood_mpp_ctrl_get(unsigned pid, unsigned long *config)
+{
+       return default_mpp_ctrl_get(mpp_base, pid, config);
+}
+
+static int kirkwood_mpp_ctrl_set(unsigned pid, unsigned long config)
+{
+       return default_mpp_ctrl_set(mpp_base, pid, config);
+}
+
 #define V(f6180, f6190, f6192, f6281, f6282, dx4122)   \
        ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) |   \
         (f6281 << 3) | (f6282 << 4) | (dx4122 << 5))
@@ -359,7 +371,7 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
 };
 
 static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
-       MPP_REG_CTRL(0, 29),
+       MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
@@ -367,7 +379,7 @@ static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
 };
 
 static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
-       MPP_REG_CTRL(0, 35),
+       MPP_FUNC_CTRL(0, 35, NULL, kirkwood_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
@@ -376,7 +388,7 @@ static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
 };
 
 static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
-       MPP_REG_CTRL(0, 49),
+       MPP_FUNC_CTRL(0, 49, NULL, kirkwood_mpp_ctrl),
 };
 
 static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
@@ -456,9 +468,16 @@ static struct of_device_id kirkwood_pinctrl_of_match[] = {
 
 static int kirkwood_pinctrl_probe(struct platform_device *pdev)
 {
+       struct resource *res;
        const struct of_device_id *match =
                of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
        pdev->dev.platform_data = (void *)match->data;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mpp_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mpp_base))
+               return PTR_ERR(mpp_base);
+
        return mvebu_pinctrl_probe(pdev);
 }
 
index 0fd1ad31fbf9aa719d19dffb7f18cc61194d2984..9908374f8f9207d0242b5fe1e081d2c066be0de3 100644 (file)
@@ -50,7 +50,6 @@ struct mvebu_pinctrl {
        struct device *dev;
        struct pinctrl_dev *pctldev;
        struct pinctrl_desc desc;
-       void __iomem *base;
        struct mvebu_pinctrl_group *groups;
        unsigned num_groups;
        struct mvebu_pinctrl_function *functions;
@@ -138,43 +137,6 @@ static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
        return NULL;
 }
 
-/*
- * Common mpp pin configuration registers on MVEBU are
- * registers of eight 4-bit values for each mpp setting.
- * Register offset and bit mask are calculated accordingly below.
- */
-static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
-                               struct mvebu_pinctrl_group *grp,
-                               unsigned long *config)
-{
-       unsigned pin = grp->gid;
-       unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
-       unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
-
-       *config = readl(pctl->base + off);
-       *config >>= shift;
-       *config &= MPP_MASK;
-
-       return 0;
-}
-
-static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
-                               struct mvebu_pinctrl_group *grp,
-                               unsigned long config)
-{
-       unsigned pin = grp->gid;
-       unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
-       unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
-       unsigned long reg;
-
-       reg = readl(pctl->base + off);
-       reg &= ~(MPP_MASK << shift);
-       reg |= (config << shift);
-       writel(reg, pctl->base + off);
-
-       return 0;
-}
-
 static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
                                unsigned gid, unsigned long *config)
 {
@@ -184,10 +146,7 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
        if (!grp->ctrl)
                return -EINVAL;
 
-       if (grp->ctrl->mpp_get)
-               return grp->ctrl->mpp_get(grp->ctrl, config);
-
-       return mvebu_common_mpp_get(pctl, grp, config);
+       return grp->ctrl->mpp_get(grp->pins[0], config);
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
@@ -202,11 +161,7 @@ static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
                return -EINVAL;
 
        for (i = 0; i < num_configs; i++) {
-               if (grp->ctrl->mpp_set)
-                       ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
-               else
-                       ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
-
+               ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);
                if (ret)
                        return ret;
        } /* for each config */
@@ -347,7 +302,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
                return -EINVAL;
 
        if (grp->ctrl->mpp_gpio_req)
-               return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
+               return grp->ctrl->mpp_gpio_req(offset);
 
        setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
        if (!setting)
@@ -370,7 +325,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
                return -EINVAL;
 
        if (grp->ctrl->mpp_gpio_dir)
-               return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
+               return grp->ctrl->mpp_gpio_dir(offset, input);
 
        setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
        if (!setting)
@@ -593,11 +548,12 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
 int mvebu_pinctrl_probe(struct platform_device *pdev)
 {
        struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
-       struct resource *res;
        struct mvebu_pinctrl *pctl;
-       void __iomem *base;
        struct pinctrl_pin_desc *pdesc;
        unsigned gid, n, k;
+       unsigned size, noname = 0;
+       char *noname_buf;
+       void *p;
        int ret;
 
        if (!soc || !soc->controls || !soc->modes) {
@@ -605,11 +561,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(base))
-               return PTR_ERR(base);
-
        pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
                        GFP_KERNEL);
        if (!pctl) {
@@ -623,7 +574,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
        pctl->desc.pmxops = &mvebu_pinmux_ops;
        pctl->desc.confops = &mvebu_pinconf_ops;
        pctl->variant = soc->variant;
-       pctl->base = base;
        pctl->dev = &pdev->dev;
        platform_set_drvdata(pdev, pctl);
 
@@ -633,33 +583,23 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
        pctl->desc.npins = 0;
        for (n = 0; n < soc->ncontrols; n++) {
                struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
-               char *names;
 
                pctl->desc.npins += ctrl->npins;
-               /* initial control pins */
+               /* initialize control's pins[] array */
                for (k = 0; k < ctrl->npins; k++)
                        ctrl->pins[k] = ctrl->pid + k;
 
-               /* special soc specific control */
-               if (ctrl->mpp_get || ctrl->mpp_set) {
-                       if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
-                               dev_err(&pdev->dev, "wrong soc control info\n");
-                               return -EINVAL;
-                       }
+               /*
+                * We allow to pass controls with NULL name that we treat
+                * as a range of one-pin groups with generic mvebu register
+                * controls.
+                */
+               if (!ctrl->name) {
+                       pctl->num_groups += ctrl->npins;
+                       noname += ctrl->npins;
+               } else {
                        pctl->num_groups += 1;
-                       continue;
                }
-
-               /* generic mvebu register control */
-               names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
-               if (!names) {
-                       dev_err(&pdev->dev, "failed to alloc mpp names\n");
-                       return -ENOMEM;
-               }
-               for (k = 0; k < ctrl->npins; k++)
-                       sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
-               ctrl->name = names;
-               pctl->num_groups += ctrl->npins;
        }
 
        pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
@@ -673,12 +613,17 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
                pdesc[n].number = n;
        pctl->desc.pins = pdesc;
 
-       pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
-                            sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
-       if (!pctl->groups) {
-               dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
+       /*
+        * allocate groups and name buffers for unnamed groups.
+        */
+       size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
+       p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+       if (!p) {
+               dev_err(&pdev->dev, "failed to alloc group data\n");
                return -ENOMEM;
        }
+       pctl->groups = p;
+       noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
 
        /* assign mpp controls to groups */
        gid = 0;
@@ -690,17 +635,26 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
                pctl->groups[gid].pins = ctrl->pins;
                pctl->groups[gid].npins = ctrl->npins;
 
-               /* generic mvebu register control maps to a number of groups */
-               if (!ctrl->mpp_get && !ctrl->mpp_set) {
+               /*
+                * We treat unnamed controls as a range of one-pin groups
+                * with generic mvebu register controls. Use one group for
+                * each in this range and assign a default group name.
+                */
+               if (!ctrl->name) {
+                       pctl->groups[gid].name = noname_buf;
                        pctl->groups[gid].npins = 1;
+                       sprintf(noname_buf, "mpp%d", ctrl->pid+0);
+                       noname_buf += 8;
 
                        for (k = 1; k < ctrl->npins; k++) {
                                gid++;
                                pctl->groups[gid].gid = gid;
                                pctl->groups[gid].ctrl = ctrl;
-                               pctl->groups[gid].name = &ctrl->name[8*k];
+                               pctl->groups[gid].name = noname_buf;
                                pctl->groups[gid].pins = &ctrl->pins[k];
                                pctl->groups[gid].npins = 1;
+                               sprintf(noname_buf, "mpp%d", ctrl->pid+k);
+                               noname_buf += 8;
                        }
                }
                gid++;
index 90bd3beee860a10dfa0b085d5d9bbb7261cae1ab..65a98e6f72657a3277154bcbe8e8adee82cde20f 100644 (file)
  * between two or more different settings, e.g. assign mpp pin 13 to
  * uart1 or sata.
  *
- * If optional mpp_get/_set functions are set these are used to get/set
- * a specific mode. Otherwise it is assumed that the mpp control is based
- * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir
- * functions can be used to allow pin settings with varying gpio pins.
+ * The mpp_get/_set functions are mandatory and are used to get/set a
+ * specific mode. The optional mpp_gpio_req/_dir functions can be used
+ * to allow pin settings with varying gpio pins.
  */
 struct mvebu_mpp_ctrl {
        const char *name;
        u8 pid;
        u8 npins;
        unsigned *pins;
-       int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);
-       int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);
-       int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);
-       int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);
+       int (*mpp_get)(unsigned pid, unsigned long *config);
+       int (*mpp_set)(unsigned pid, unsigned long config);
+       int (*mpp_gpio_req)(unsigned pid);
+       int (*mpp_gpio_dir)(unsigned pid, bool input);
 };
 
 /**
@@ -114,18 +113,6 @@ struct mvebu_pinctrl_soc_info {
        int ngpioranges;
 };
 
-#define MPP_REG_CTRL(_idl, _idh)                               \
-       {                                                       \
-               .name = NULL,                                   \
-               .pid = _idl,                                    \
-               .npins = _idh - _idl + 1,                       \
-               .pins = (unsigned[_idh - _idl + 1]) { },        \
-               .mpp_get = NULL,                                \
-               .mpp_set = NULL,                                \
-               .mpp_gpio_req = NULL,                           \
-               .mpp_gpio_dir = NULL,                           \
-       }
-
 #define MPP_FUNC_CTRL(_idl, _idh, _name, _func)                        \
        {                                                       \
                .name = _name,                                  \
@@ -186,6 +173,34 @@ struct mvebu_pinctrl_soc_info {
                .npins = _npins,                                \
        }
 
+#define MVEBU_MPPS_PER_REG     8
+#define MVEBU_MPP_BITS         4
+#define MVEBU_MPP_MASK         0xf
+
+static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid,
+                                      unsigned long *config)
+{
+       unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+
+       *config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;
+
+       return 0;
+}
+
+static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid,
+                                      unsigned long config)
+{
+       unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
+       unsigned long reg;
+
+       reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);
+       writel(reg | (config << shift), base + off);
+
+       return 0;
+}
+
 int mvebu_pinctrl_probe(struct platform_device *pdev);
 int mvebu_pinctrl_remove(struct platform_device *pdev);