Commit fbfc5fc3 authored by Linus Walleij's avatar Linus Walleij

Merge tag 'samsung-pinctrl-5.18-2' of...

Merge tag 'samsung-pinctrl-5.18-2' of https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung into devel

Samsung pinctrl drivers changes for v5.18

1. Fix OF reference leak in pinctrl driver probe error path.
2. Correct list of handlers for Exynos850 ALIVE and CMGP pin banks.
3. Accept devicetrees with GPIO pin bank definitions named with a
   "-gpio-bank" suffix.  This is necessary for later Samsung pinctrl
   bindings dtschema.
4. Convert Samsung pinctrl bindings to dtschema.
5. Add support for Exynos850 and ExynosAutov9 wake-up interrupts.
6. Add support for Tesla FSD SoC.
parents c981a789 3652dc07
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-gpio-bank.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung S3C/S5P/Exynos SoC pin controller - gpio bank
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
- Tomasz Figa <tomasz.figa@gmail.com>
description: |
This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
controller.
GPIO bank description for Samsung S3C/S5P/Exynos SoC pin controller.
See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
additional information and example.
properties:
'#gpio-cells':
const: 2
gpio-controller: true
'#interrupt-cells':
description:
For GPIO banks supporting external GPIO interrupts or external wake-up
interrupts.
const: 2
interrupt-controller:
description:
For GPIO banks supporting external GPIO interrupts or external wake-up
interrupts.
interrupts:
description:
For GPIO banks supporting direct external wake-up interrupts (without
multiplexing). Number of interrupts must match number of wake-up capable
pins of this bank.
minItems: 1
maxItems: 8
required:
- '#gpio-cells'
- gpio-controller
additionalProperties: false
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-pins-cfg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung S3C/S5P/Exynos SoC pin controller - pins configuration
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
- Tomasz Figa <tomasz.figa@gmail.com>
description: |
This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
controller.
Pins configuration for Samsung S3C/S5P/Exynos SoC pin controller.
The values used for config properties should be derived from the hardware
manual and these values are programmed as-is into the pin pull up/down and
driver strength register of the pin-controller.
See also include/dt-bindings/pinctrl/samsung.h with useful constants.
See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
additional information and example.
properties:
samsung,pins:
description: |
List of pins to configure. For initial and sleep states, the maximum
number is one pin. In other cases there is no upper limit.
The pins should use lowercase names matching hardware manual, e.g. for
GPA0 bank: gpa0-0, gpa0-1, gpa0-2.
$ref: /schemas/types.yaml#/definitions/string-array
samsung,pin-function:
description: |
The pin function selection that should be applied on the pins listed in the
child node is specified using the "samsung,pin-function" property. The value
of this property that should be applied to each of the pins listed in the
"samsung,pins" property should be picked from the hardware manual of the SoC
for the specified pin group. This property is optional in the child node if
no specific function selection is desired for the pins listed in the child
node. The value of this property is used as-is to program the pin-controller
function selector register of the pin-bank.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 15
samsung,pin-drv:
description: Drive strength configuration.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 15
samsung,pin-pud:
description: Pull up/down configuration.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
samsung,pin-val:
description: Initial value of pin output buffer.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
samsung,pin-con-pdn:
description: Function in power down mode.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
samsung,pin-pud-pdn:
description: Pull up/down configuration in power down mode.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
required:
- samsung,pins
additionalProperties: false
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung S3C/S5P/Exynos SoC pin controller - wake-up interrupt controller
maintainers:
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
- Tomasz Figa <tomasz.figa@gmail.com>
description: |
This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
controller.
External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
For S3C24xx, S3C64xx, S5PV210 and Exynos4210 compatible wake-up interrupt
controllers, only one pin-controller device node can include external wake-up
interrupts child node (in other words, only one External wake-up interrupts
pin-controller is supported).
For newer controllers, multiple pin-controller device node can include
external wake-up interrupts child node.
See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
additional information and example.
properties:
compatible:
enum:
- samsung,s3c2410-wakeup-eint
- samsung,s3c2412-wakeup-eint
- samsung,s3c64xx-wakeup-eint
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos7-wakeup-eint
- samsung,exynos850-wakeup-eint
- samsung,exynosautov9-wakeup-eint
interrupts:
description:
Interrupt used by multiplexed external wake-up interrupts.
minItems: 1
maxItems: 6
required:
- compatible
allOf:
- if:
properties:
compatible:
contains:
enum:
- samsung,s3c2410-wakeup-eint
- samsung,s3c2412-wakeup-eint
then:
properties:
interrupts:
minItems: 6
maxItems: 6
required:
- interrupts
- if:
properties:
compatible:
contains:
const: samsung,s3c64xx-wakeup-eint
then:
properties:
interrupts:
minItems: 4
maxItems: 4
required:
- interrupts
- if:
properties:
compatible:
contains:
enum:
- samsung,s5pv210-wakeup-eint
- samsung,exynos4210-wakeup-eint
- samsung,exynos7-wakeup-eint
then:
properties:
interrupts:
minItems: 1
maxItems: 1
required:
- interrupts
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos850-wakeup-eint
- samsung,exynosautov9-wakeup-eint
then:
properties:
interrupts: false
additionalProperties: false
This diff is collapsed.
......@@ -15293,7 +15293,7 @@ L: linux-samsung-soc@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
F: Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
F: drivers/pinctrl/samsung/
F: include/dt-bindings/pinctrl/samsung.h
......
......@@ -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 */
......@@ -727,3 +725,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
.ctrl = exynosautov9_pin_ctrl,
.num_ctrl = ARRAY_SIZE(exynosautov9_pin_ctrl),
};
/*
* Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
* gpio/pin-mux/pinconfig controllers.
*/
/* pin banks of FSD pin-controller 0 (FSYS) */
static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
};
/* pin banks of FSD pin-controller 1 (PERIC) */
static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
};
/* pin banks of FSD pin-controller 2 (PMU) */
static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
};
const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
{
/* pin-controller instance 0 FSYS0 data */
.pin_banks = fsd_pin_banks0,
.nr_banks = ARRAY_SIZE(fsd_pin_banks0),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 1 PERIC data */
.pin_banks = fsd_pin_banks1,
.nr_banks = ARRAY_SIZE(fsd_pin_banks1),
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
}, {
/* pin-controller instance 2 PMU data */
.pin_banks = fsd_pin_banks2,
.nr_banks = ARRAY_SIZE(fsd_pin_banks2),
},
};
const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
.ctrl = fsd_pin_ctrl,
.num_ctrl = ARRAY_SIZE(fsd_pin_ctrl),
};
......@@ -344,7 +344,8 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
pr_info("wake %s for irq %u (%s-%lu)\n", on ? "enabled" : "disabled",
irqd->irq, bank->name, irqd->hwirq);
if (!on)
*our_chip->eint_wake_mask_value |= bit;
......@@ -465,6 +466,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 },
{ }
};
......
......@@ -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;
}
/*
......@@ -1271,6 +1320,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
.data = &exynos850_of_data },
{ .compatible = "samsung,exynosautov9-pinctrl",
.data = &exynosautov9_of_data },
{ .compatible = "tesla,fsd-pinctrl",
.data = &fsd_of_data },
#endif
#ifdef CONFIG_PINCTRL_S3C64XX
{ .compatible = "samsung,s3c64xx-pinctrl",
......
......@@ -342,6 +342,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
extern const struct samsung_pinctrl_of_match_data fsd_of_data;
extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment