summaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2022-02-25 17:21:48 +0300
committerArnd Bergmann <arnd@arndb.de>2022-02-25 17:21:48 +0300
commit4d9b86eb38af20747229b1247ff950572128f3d4 (patch)
treea87830279b5021b8ef8106ac022b520ad89f6460 /drivers/pinctrl
parentab2dad6f9e7462078d2401d8ffcb17031ead70a2 (diff)
parent41bd4354a1513afa4a9dd9940d8cd790fbd00e68 (diff)
downloadlinux-4d9b86eb38af20747229b1247ff950572128f3d4.tar.xz
Merge tag 'samsung-dt-pinctrl-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into arm/dt
Samsung pinctrl DTS and driver changes for v5.18 Conversion of Samsung pinctrl bindings to dtschema followed up with alignment of DTS files to the dtschema. The entire work consists of three parts but everything should be merged at once to avoid dtschema check errors: 1. Samsung pinctrl driver change necessary to accept new DTS (driver depends on node names and this has to be adjusted because of dtschema). 2. Conversion to dtschema which brings requirement of different naming of the GPIO nodes. 3. DTS commits depending on driver (1) above, which convert all GPIO pin bank names to new naming, required by dtschema. This also includes few cleanups around DTS which are here to avoid any merge conflicts. The Samsung pinctrl driver changes are backwards compatible. However the DTS changes (renaming nodes) could cause problems in out-of-tree or other project implementations of the driver. * tag 'samsung-dt-pinctrl-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: (28 commits) arm64: dts: exynos: use dedicated wake-up pinctrl compatible in ExynosAutov9 ARM: dts: s5pv210: align pinctrl with dtschema ARM: dts: s3c64xx: align pinctrl with dtschema ARM: dts: s3c24xx: align pinctrl with dtschema arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9 arm64: dts: exynos: align pinctrl with dtschema in Exynos7 arm64: dts: exynos: align pinctrl with dtschema in Exynos5433 ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800 ARM: dts: exynos: align pinctrl with dtschema in Exynos5410 ARM: dts: exynos: align pinctrl with dtschema in Exynos5260 ARM: dts: exynos: align pinctrl with dtschema in Exynos5250 ARM: dts: exynos: align pinctrl with dtschema in Exynos4412 ARM: dts: exynos: align pinctrl with dtschema in Exynos4210 ARM: dts: exynos: align pinctrl with dtschema in Exynos3250 ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi ARM: dts: exynos: override pins by label in Peach Pi ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit ARM: dts: exynos: override pins by label in Peach Pit ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU ... Link: https://lore.kernel.org/r/20220129115352.13274-1-krzysztof.kozlowski@canonical.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos-arm64.c2
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c4
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c87
3 files changed, 72 insertions, 21 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 2e490e7696f4..4102ce955bd7 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -585,13 +585,11 @@ static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
/* pin-controller instance 0 ALIVE data */
.pin_banks = exynos850_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos850_pin_banks0),
- .eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 1 CMGP data */
.pin_banks = exynos850_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos850_pin_banks1),
- .eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
}, {
/* pin-controller instance 2 AUD data */
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 0489c899b401..a158d587814e 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -465,6 +465,10 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
.data = &exynos4210_wkup_irq_chip },
{ .compatible = "samsung,exynos7-wakeup-eint",
.data = &exynos7_wkup_irq_chip },
+ { .compatible = "samsung,exynos850-wakeup-eint",
+ .data = &exynos7_wkup_irq_chip },
+ { .compatible = "samsung,exynosautov9-wakeup-eint",
+ .data = &exynos7_wkup_irq_chip },
{ }
};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 0f6e9305fec5..568b6e65dfed 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1002,13 +1002,66 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
return &(of_data->ctrl[id]);
}
+static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
+{
+ struct samsung_pin_bank *bank;
+ unsigned int i;
+
+ bank = d->pin_banks;
+ for (i = 0; i < d->nr_banks; ++i, ++bank)
+ of_node_put(bank->of_node);
+}
+
+/*
+ * Iterate over all driver pin banks to find one matching the name of node,
+ * skipping optional "-gpio" node suffix. When found, assign node to the bank.
+ */
+static void samsung_banks_of_node_get(struct device *dev,
+ struct samsung_pinctrl_drv_data *d,
+ struct device_node *node)
+{
+ const char *suffix = "-gpio-bank";
+ struct samsung_pin_bank *bank;
+ struct device_node *child;
+ /* Pin bank names are up to 4 characters */
+ char node_name[20];
+ unsigned int i;
+ size_t len;
+
+ bank = d->pin_banks;
+ for (i = 0; i < d->nr_banks; ++i, ++bank) {
+ strscpy(node_name, bank->name, sizeof(node_name));
+ len = strlcat(node_name, suffix, sizeof(node_name));
+ if (len >= sizeof(node_name)) {
+ dev_err(dev, "Too long pin bank name '%s', ignoring\n",
+ bank->name);
+ continue;
+ }
+
+ for_each_child_of_node(node, child) {
+ if (!of_find_property(child, "gpio-controller", NULL))
+ continue;
+ if (of_node_name_eq(child, node_name))
+ break;
+ else if (of_node_name_eq(child, bank->name))
+ break;
+ }
+
+ if (child)
+ bank->of_node = child;
+ else
+ dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
+ bank->name);
+ /* child reference dropped in samsung_drop_banks_of_node() */
+ }
+}
+
/* retrieve the soc specific data */
static const struct samsung_pin_ctrl *
samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
- struct device_node *np;
const struct samsung_pin_bank_data *bdata;
const struct samsung_pin_ctrl *ctrl;
struct samsung_pin_bank *bank;
@@ -1072,17 +1125,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
*/
d->virt_base = virt_base[0];
- for_each_child_of_node(node, np) {
- if (!of_find_property(np, "gpio-controller", NULL))
- continue;
- bank = d->pin_banks;
- for (i = 0; i < d->nr_banks; ++i, ++bank) {
- if (of_node_name_eq(np, bank->name)) {
- bank->of_node = np;
- break;
- }
- }
- }
+ samsung_banks_of_node_get(&pdev->dev, d, node);
d->pin_base = pin_base;
pin_base += d->nr_pins;
@@ -1117,19 +1160,19 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
if (ctrl->retention_data) {
drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,
ctrl->retention_data);
- if (IS_ERR(drvdata->retention_ctrl))
- return PTR_ERR(drvdata->retention_ctrl);
+ if (IS_ERR(drvdata->retention_ctrl)) {
+ ret = PTR_ERR(drvdata->retention_ctrl);
+ goto err_put_banks;
+ }
}
ret = samsung_pinctrl_register(pdev, drvdata);
if (ret)
- return ret;
+ goto err_put_banks;
ret = samsung_gpiolib_register(pdev, drvdata);
- if (ret) {
- samsung_pinctrl_unregister(pdev, drvdata);
- return ret;
- }
+ if (ret)
+ goto err_unregister;
if (ctrl->eint_gpio_init)
ctrl->eint_gpio_init(drvdata);
@@ -1139,6 +1182,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drvdata);
return 0;
+
+err_unregister:
+ samsung_pinctrl_unregister(pdev, drvdata);
+err_put_banks:
+ samsung_banks_of_node_put(drvdata);
+ return ret;
}
/*