Skip to content

Commit

Permalink
Merge tag 'samsung-pinctrl-4.12' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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.
  • Loading branch information
Linus Walleij committed Apr 10, 2017
2 parents ba9e7f2 + f69ae4f commit 8d4264d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 25 deletions.
63 changes: 63 additions & 0 deletions drivers/pinctrl/samsung/pinctrl-exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand Down Expand Up @@ -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.
Expand All @@ -1559,69 +1612,79 @@ 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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks1),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks2),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks3),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks4),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks5),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks6),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks7),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks8),
.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,
.nr_banks = ARRAY_SIZE(exynos5433_pin_banks9),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
.retention_data = &exynos5433_retention_data,
},
};

Expand Down
45 changes: 20 additions & 25 deletions drivers/pinctrl/samsung/pinctrl-samsung.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 8d4264d

Please sign in to comment.