diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2017-04-10 09:35:30 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-04-10 09:35:30 +0200 |
commit | 8d4264d86c1a31d7e0efd3e4c3e08bc91dbdb48c (patch) | |
tree | 54f74ed92952148c9923d70471e7cbc62b9e57d6 /drivers/pinctrl | |
parent | ba9e7f2794d8158c93aacd279830a6f1f98b19b0 (diff) | |
parent | f69ae4f58a198ad15b0422637434d2bcf6fc2e2a (diff) | |
download | linux-8d4264d86c1a31d7e0efd3e4c3e08bc91dbdb48c.tar.bz2 |
Merge tag 'samsung-pinctrl-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung into devel
Samsung pinctrl drivers update for v4.12:
1. Add support for pad retention control through pinctrl drivers which
moves us forward to better runtime PM of pinctrl, clocks, power domains
and other devices.
2. Fix GPIO hogs by registering pinctrl before registering gpiolib.
3. Use devm-like interface.
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/samsung/pinctrl-exynos.c | 63 | ||||
-rw-r--r-- | drivers/pinctrl/samsung/pinctrl-samsung.c | 45 |
2 files changed, 83 insertions, 25 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index f9b49967f512..c0dfd31c0fa2 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -777,6 +777,7 @@ exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata, { struct samsung_retention_ctrl *ctrl; struct regmap *pmu_regs; + int i; ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL); if (!ctrl) @@ -794,6 +795,10 @@ exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata, ctrl->enable = exynos_retention_enable; ctrl->disable = exynos_retention_disable; + /* Ensure that retention is disabled on driver init */ + for (i = 0; i < ctrl->nr_regs; i++) + regmap_write(pmu_regs, ctrl->regs[i], ctrl->value); + return ctrl; } @@ -1546,6 +1551,54 @@ static const struct samsung_pin_bank_data exynos5433_pin_banks9[] __initconst = EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00), }; +/* PMU pin retention groups registers for Exynos5433 (without audio & fsys) */ +static const u32 exynos5433_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_TOP_OPTION, + EXYNOS5433_PAD_RETENTION_UART_OPTION, + EXYNOS5433_PAD_RETENTION_EBIA_OPTION, + EXYNOS5433_PAD_RETENTION_EBIB_OPTION, + EXYNOS5433_PAD_RETENTION_SPI_OPTION, + EXYNOS5433_PAD_RETENTION_MIF_OPTION, + EXYNOS5433_PAD_RETENTION_USBXTI_OPTION, + EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION, + EXYNOS5433_PAD_RETENTION_UFS_OPTION, + EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION, +}; + +static const struct samsung_retention_data exynos5433_retention_data __initconst = { + .regs = exynos5433_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .refcnt = &exynos_shared_retention_refcnt, + .init = exynos_retention_init, +}; + +/* PMU retention control for audio pins can be tied to audio pin bank */ +static const u32 exynos5433_audio_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_AUD_OPTION, +}; + +static const struct samsung_retention_data exynos5433_audio_retention_data __initconst = { + .regs = exynos5433_audio_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_audio_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init = exynos_retention_init, +}; + +/* PMU retention control for mmc pins can be tied to fsys pin bank */ +static const u32 exynos5433_fsys_retention_regs[] = { + EXYNOS5433_PAD_RETENTION_MMC0_OPTION, + EXYNOS5433_PAD_RETENTION_MMC1_OPTION, + EXYNOS5433_PAD_RETENTION_MMC2_OPTION, +}; + +static const struct samsung_retention_data exynos5433_fsys_retention_data __initconst = { + .regs = exynos5433_fsys_retention_regs, + .nr_regs = ARRAY_SIZE(exynos5433_fsys_retention_regs), + .value = EXYNOS_WAKEUP_FROM_LOWPWR, + .init = exynos_retention_init, +}; + /* * Samsung pinctrl driver data for Exynos5433 SoC. Exynos5433 SoC includes * ten gpio/pin-mux/pinconfig controllers. @@ -1559,6 +1612,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, .nr_ext_resources = 1, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 1 data */ .pin_banks = exynos5433_pin_banks1, @@ -1566,6 +1620,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_audio_retention_data, }, { /* pin-controller instance 2 data */ .pin_banks = exynos5433_pin_banks2, @@ -1573,6 +1628,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 3 data */ .pin_banks = exynos5433_pin_banks3, @@ -1580,6 +1636,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 4 data */ .pin_banks = exynos5433_pin_banks4, @@ -1587,6 +1644,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 5 data */ .pin_banks = exynos5433_pin_banks5, @@ -1594,6 +1652,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_fsys_retention_data, }, { /* pin-controller instance 6 data */ .pin_banks = exynos5433_pin_banks6, @@ -1601,6 +1660,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 7 data */ .pin_banks = exynos5433_pin_banks7, @@ -1608,6 +1668,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 8 data */ .pin_banks = exynos5433_pin_banks8, @@ -1615,6 +1676,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, { /* pin-controller instance 9 data */ .pin_banks = exynos5433_pin_banks9, @@ -1622,6 +1684,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] __initconst = { .eint_gpio_init = exynos_eint_gpio_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .retention_data = &exynos5433_retention_data, }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 0d2989d98bc3..b618dae84cec 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -882,7 +882,7 @@ static int samsung_pinctrl_register(struct platform_device *pdev, pin_bank->grange.id = bank; pin_bank->grange.pin_base = drvdata->pin_base + pin_bank->pin_base; - pin_bank->grange.base = pin_bank->gpio_chip.base; + pin_bank->grange.base = pin_bank->grange.pin_base; pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; pin_bank->grange.gc = &pin_bank->gpio_chip; pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); @@ -891,6 +891,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev, return 0; } +/* unregister the pinctrl interface with the pinctrl subsystem */ +static int samsung_pinctrl_unregister(struct platform_device *pdev, + struct samsung_pinctrl_drv_data *drvdata) +{ + struct samsung_pin_bank *bank = drvdata->pin_banks; + int i; + + for (i = 0; i < drvdata->nr_banks; ++i, ++bank) + pinctrl_remove_gpio_range(drvdata->pctl_dev, &bank->grange); + + return 0; +} + static const struct gpio_chip samsung_gpiolib_chip = { .request = gpiochip_generic_request, .free = gpiochip_generic_free, @@ -915,39 +928,21 @@ static int samsung_gpiolib_register(struct platform_device *pdev, bank->gpio_chip = samsung_gpiolib_chip; gc = &bank->gpio_chip; - gc->base = drvdata->pin_base + bank->pin_base; + gc->base = bank->grange.base; gc->ngpio = bank->nr_pins; gc->parent = &pdev->dev; gc->of_node = bank->of_node; gc->label = bank->name; - ret = gpiochip_add_data(gc, bank); + ret = devm_gpiochip_add_data(&pdev->dev, gc, bank); if (ret) { dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n", gc->label, ret); - goto fail; + return ret; } } return 0; - -fail: - for (--i, --bank; i >= 0; --i, --bank) - gpiochip_remove(&bank->gpio_chip); - return ret; -} - -/* unregister the gpiolib interface with the gpiolib subsystem */ -static int samsung_gpiolib_unregister(struct platform_device *pdev, - struct samsung_pinctrl_drv_data *drvdata) -{ - struct samsung_pin_bank *bank = drvdata->pin_banks; - int i; - - for (i = 0; i < drvdata->nr_banks; ++i, ++bank) - gpiochip_remove(&bank->gpio_chip); - - return 0; } /* retrieve the soc specific data */ @@ -1060,13 +1055,13 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) return PTR_ERR(drvdata->retention_ctrl); } - ret = samsung_gpiolib_register(pdev, drvdata); + ret = samsung_pinctrl_register(pdev, drvdata); if (ret) return ret; - ret = samsung_pinctrl_register(pdev, drvdata); + ret = samsung_gpiolib_register(pdev, drvdata); if (ret) { - samsung_gpiolib_unregister(pdev, drvdata); + samsung_pinctrl_unregister(pdev, drvdata); return ret; } |