diff options
Diffstat (limited to 'drivers/pinctrl/mvebu/pinctrl-dove.c')
-rw-r--r-- | drivers/pinctrl/mvebu/pinctrl-dove.c | 113 |
1 files changed, 58 insertions, 55 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index f93ae0dcef9c..8472f61f2bbe 100644 --- a/drivers/pinctrl/mvebu/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -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> @@ -61,30 +60,20 @@ #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); |