]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/pinctrl/mvebu/pinctrl-dove.c
Merge branches 'for-4.11/upstream-fixes', 'for-4.12/accutouch', 'for-4.12/cp2112...
[mirror_ubuntu-artful-kernel.git] / drivers / pinctrl / mvebu / pinctrl-dove.c
index f93ae0dcef9caabdfdeb5635401f233c2b108bb3..8472f61f2bbe73a35e3410eed9a6999d15c19794 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 
 #define CONFIG_PMU     BIT(4)
 
-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)
-{
-       return default_mpp_ctrl_set(mpp_base, pid, config);
-}
-
-static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
+                                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 pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
        unsigned long func;
 
        if ((pmu & BIT(pid)) == 0)
-               return default_mpp_ctrl_get(mpp_base, pid, config);
+               return mvebu_mmio_mpp_ctrl_get(data, pid, config);
 
        func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
        *config = (func >> shift) & MVEBU_MPP_MASK;
@@ -93,19 +82,20 @@ static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
        return 0;
 }
 
-static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
+static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
+                                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 pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
        unsigned long func;
 
        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), data->base + PMU_MPP_GENERAL_CTRL);
+               return mvebu_mmio_mpp_ctrl_set(data, pid, config);
        }
 
-       writel(pmu | BIT(pid), mpp_base + PMU_MPP_GENERAL_CTRL);
+       writel(pmu | BIT(pid), data->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;
@@ -114,7 +104,8 @@ static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
        return 0;
 }
 
-static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long *config)
 {
        unsigned long mpp4 = readl(mpp4_base);
        unsigned long mask;
@@ -144,7 +135,8 @@ static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
        return 0;
 }
 
-static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
+static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long config)
 {
        unsigned long mpp4 = readl(mpp4_base);
        unsigned long mask;
@@ -178,7 +170,8 @@ static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
        return 0;
 }
 
-static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long *config)
 {
        unsigned int gmpp;
 
@@ -188,7 +181,8 @@ static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
        return 0;
 }
 
-static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
+static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long config)
 {
        regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
                           NAND_GPIO_EN,
@@ -196,28 +190,31 @@ static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
        return 0;
 }
 
-static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                               unsigned long *config)
 {
-       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
+       unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
 
        *config = ((pmu & AU0_AC97_SEL) != 0);
 
        return 0;
 }
 
-static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
+static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                               unsigned long config)
 {
-       unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
+       unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
 
        pmu &= ~AU0_AC97_SEL;
        if (config)
                pmu |= AU0_AC97_SEL;
-       writel(pmu, mpp_base + PMU_MPP_GENERAL_CTRL);
+       writel(pmu, data->base + PMU_MPP_GENERAL_CTRL);
 
        return 0;
 }
 
-static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                               unsigned long *config)
 {
        unsigned int mpp4 = readl(mpp4_base);
        unsigned int sspc1;
@@ -247,7 +244,8 @@ static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
        return 0;
 }
 
-static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
+static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                               unsigned long config)
 {
        unsigned int mpp4 = readl(mpp4_base);
 
@@ -274,11 +272,12 @@ static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
  * break other functions. If you require all mpps as gpio
  * enforce gpio setting by pinctrl mapping.
  */
-static int dove_audio1_ctrl_gpio_req(unsigned pid)
+static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl_data *data,
+                                    unsigned pid)
 {
        unsigned long config;
 
-       dove_audio1_ctrl_get(pid, &config);
+       dove_audio1_ctrl_get(data, pid, &config);
 
        switch (config) {
        case 0x02: /* i2s1 : gpio[56:57] */
@@ -301,14 +300,16 @@ static int dove_audio1_ctrl_gpio_req(unsigned pid)
 }
 
 /* mpp[52:57] has gpio pins capable of in and out */
-static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
+static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl_data *data,
+                                    unsigned pid, bool input)
 {
        if (pid < 52 || pid > 57)
                return -ENOTSUPP;
        return 0;
 }
 
-static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
+static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long *config)
 {
        unsigned int gcfg1;
        unsigned int gcfg2;
@@ -327,7 +328,8 @@ static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
        return 0;
 }
 
-static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
+static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
+                             unsigned long config)
 {
        unsigned int gcfg1 = 0;
        unsigned int gcfg2 = 0;
@@ -354,9 +356,9 @@ static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
        return 0;
 }
 
-static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
+static const struct mvebu_mpp_ctrl dove_mpp_controls[] = {
        MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
-       MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
+       MPP_FUNC_CTRL(16, 23, NULL, mvebu_mmio_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),
@@ -769,6 +771,10 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
        struct resource fb_res;
        const struct of_device_id *match =
                of_match_device(dove_pinctrl_of_match, &pdev->dev);
+       struct mvebu_mpp_ctrl_data *mpp_data;
+       void __iomem *base;
+       int i;
+
        pdev->dev.platform_data = (void *)match->data;
 
        /*
@@ -783,9 +789,18 @@ 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);
+       base = devm_ioremap_resource(&pdev->dev, mpp_res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       mpp_data = devm_kcalloc(&pdev->dev, dove_pinctrl_info.ncontrols,
+                               sizeof(*mpp_data), GFP_KERNEL);
+       if (!mpp_data)
+               return -ENOMEM;
+
+       dove_pinctrl_info.control_data = mpp_data;
+       for (i = 0; i < ARRAY_SIZE(dove_mpp_controls); i++)
+               mpp_data[i].base = base;
 
        /* prepare fallback resource */
        memcpy(&fb_res, mpp_res, sizeof(struct resource));
@@ -838,24 +853,12 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
        return mvebu_pinctrl_probe(pdev);
 }
 
-static int dove_pinctrl_remove(struct platform_device *pdev)
-{
-       if (!IS_ERR(clk))
-               clk_disable_unprepare(clk);
-       return 0;
-}
-
 static struct platform_driver dove_pinctrl_driver = {
        .driver = {
                .name = "dove-pinctrl",
+               .suppress_bind_attrs = true,
                .of_match_table = dove_pinctrl_of_match,
        },
        .probe = dove_pinctrl_probe,
-       .remove = dove_pinctrl_remove,
 };
-
-module_platform_driver(dove_pinctrl_driver);
-
-MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>");
-MODULE_DESCRIPTION("Marvell Dove pinctrl driver");
-MODULE_LICENSE("GPL v2");
+builtin_platform_driver(dove_pinctrl_driver);