summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/stm32/pinctrl-stm32.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/stm32/pinctrl-stm32.c')
-rw-r--r--drivers/pinctrl/stm32/pinctrl-stm32.c274
1 files changed, 165 insertions, 109 deletions
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c
index f7c9459f6628..57a33fb0f2d7 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32.c
@@ -24,6 +24,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -43,6 +44,7 @@
#define STM32_GPIO_LCKR 0x1c
#define STM32_GPIO_AFRL 0x20
#define STM32_GPIO_AFRH 0x24
+#define STM32_GPIO_SECCFGR 0x30
/* custom bitfield to backup pin status */
#define STM32_GPIO_BKP_MODE_SHIFT 0
@@ -94,6 +96,7 @@ struct stm32_gpio_bank {
u32 bank_ioport_nr;
u32 pin_backup[STM32_GPIO_PINS_PER_BANK];
u8 irq_type[STM32_GPIO_PINS_PER_BANK];
+ bool secure_control;
};
struct stm32_pinctrl {
@@ -197,11 +200,7 @@ static inline void __stm32_gpio_set(struct stm32_gpio_bank *bank,
if (!value)
offset += STM32_GPIO_PINS_PER_BANK;
- clk_enable(bank->clk);
-
writel_relaxed(BIT(offset), bank->base + STM32_GPIO_BSRR);
-
- clk_disable(bank->clk);
}
static int stm32_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -225,25 +224,11 @@ static void stm32_gpio_free(struct gpio_chip *chip, unsigned offset)
pinctrl_gpio_free(chip->base + offset);
}
-static int stm32_gpio_get_noclk(struct gpio_chip *chip, unsigned int offset)
-{
- struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
-
- return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
-}
-
static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
- int ret;
-
- clk_enable(bank->clk);
-
- ret = stm32_gpio_get_noclk(chip, offset);
-
- clk_disable(bank->clk);
- return ret;
+ return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
}
static void stm32_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -301,6 +286,33 @@ static int stm32_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
return ret;
}
+static int stm32_gpio_init_valid_mask(struct gpio_chip *chip,
+ unsigned long *valid_mask,
+ unsigned int ngpios)
+{
+ struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
+ struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
+ unsigned int i;
+ u32 sec;
+
+ /* All gpio are valid per default */
+ bitmap_fill(valid_mask, ngpios);
+
+ if (bank->secure_control) {
+ /* Tag secured pins as invalid */
+ sec = readl_relaxed(bank->base + STM32_GPIO_SECCFGR);
+
+ for (i = 0; i < ngpios; i++) {
+ if (sec & BIT(i)) {
+ clear_bit(i, valid_mask);
+ dev_dbg(pctl->dev, "No access to gpio %d - %d\n", bank->bank_nr, i);
+ }
+ }
+ }
+
+ return 0;
+}
+
static const struct gpio_chip stm32_gpio_template = {
.request = stm32_gpio_request,
.free = stm32_gpio_free,
@@ -311,6 +323,7 @@ static const struct gpio_chip stm32_gpio_template = {
.to_irq = stm32_gpio_to_irq,
.get_direction = stm32_gpio_get_direction,
.set_config = gpiochip_generic_config,
+ .init_valid_mask = stm32_gpio_init_valid_mask,
};
static void stm32_gpio_irq_trigger(struct irq_data *d)
@@ -323,7 +336,7 @@ static void stm32_gpio_irq_trigger(struct irq_data *d)
return;
/* If level interrupt type then retrig */
- level = stm32_gpio_get_noclk(&bank->gpio_chip, d->hwirq);
+ level = stm32_gpio_get(&bank->gpio_chip, d->hwirq);
if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) ||
(level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH))
irq_chip_retrigger_hierarchy(d);
@@ -365,7 +378,6 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = irq_data->domain->host_data;
struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
- unsigned long flags;
int ret;
ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq);
@@ -379,10 +391,6 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
return ret;
}
- flags = irqd_get_trigger_type(irq_data);
- if (flags & IRQ_TYPE_LEVEL_MASK)
- clk_enable(bank->clk);
-
return 0;
}
@@ -390,9 +398,6 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data)
{
struct stm32_gpio_bank *bank = irq_data->domain->host_data;
- if (bank->irq_type[irq_data->hwirq] & IRQ_TYPE_LEVEL_MASK)
- clk_disable(bank->clk);
-
gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq);
}
@@ -533,7 +538,7 @@ stm32_pctrl_find_group_by_pin(struct stm32_pinctrl *pctl, u32 pin)
static bool stm32_pctrl_is_function_valid(struct stm32_pinctrl *pctl,
u32 pin_num, u32 fnum)
{
- int i;
+ int i, k;
for (i = 0; i < pctl->npins; i++) {
const struct stm32_desc_pin *pin = pctl->pins + i;
@@ -542,7 +547,7 @@ static bool stm32_pctrl_is_function_valid(struct stm32_pinctrl *pctl,
if (pin->pin.number != pin_num)
continue;
- while (func && func->name) {
+ for (k = 0; k < STM32_CONFIG_NUM; k++) {
if (func->num == fnum)
return true;
func++;
@@ -769,7 +774,6 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank,
unsigned long flags;
int err = 0;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
if (pctl->hwlock) {
@@ -798,7 +802,6 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank,
unlock:
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return err;
}
@@ -811,7 +814,6 @@ void stm32_pmx_get_mode(struct stm32_gpio_bank *bank, int pin, u32 *mode,
int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4;
unsigned long flags;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = readl_relaxed(bank->base + alt_offset);
@@ -823,7 +825,6 @@ void stm32_pmx_get_mode(struct stm32_gpio_bank *bank, int pin, u32 *mode,
*mode = val >> (pin * 2);
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
}
static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev,
@@ -867,12 +868,32 @@ static int stm32_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
return stm32_pmx_set_mode(bank, pin, !input, 0);
}
+static int stm32_pmx_request(struct pinctrl_dev *pctldev, unsigned int gpio)
+{
+ struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct pinctrl_gpio_range *range;
+
+ range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, gpio);
+ if (!range) {
+ dev_err(pctl->dev, "No gpio range defined.\n");
+ return -EINVAL;
+ }
+
+ if (!gpiochip_line_is_valid(range->gc, stm32_gpio_pin(gpio))) {
+ dev_warn(pctl->dev, "Can't access gpio %d\n", gpio);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
static const struct pinmux_ops stm32_pmx_ops = {
.get_functions_count = stm32_pmx_get_funcs_cnt,
.get_function_name = stm32_pmx_get_func_name,
.get_function_groups = stm32_pmx_get_func_groups,
.set_mux = stm32_pmx_set_mux,
.gpio_set_direction = stm32_pmx_gpio_set_direction,
+ .request = stm32_pmx_request,
.strict = true,
};
@@ -886,7 +907,6 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank,
u32 val;
int err = 0;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
if (pctl->hwlock) {
@@ -910,7 +930,6 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank,
unlock:
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return err;
}
@@ -921,14 +940,12 @@ static u32 stm32_pconf_get_driving(struct stm32_gpio_bank *bank,
unsigned long flags;
u32 val;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = readl_relaxed(bank->base + STM32_GPIO_TYPER);
val &= BIT(offset);
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return (val >> offset);
}
@@ -941,7 +958,6 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank,
u32 val;
int err = 0;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
if (pctl->hwlock) {
@@ -965,7 +981,6 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank,
unlock:
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return err;
}
@@ -976,14 +991,12 @@ static u32 stm32_pconf_get_speed(struct stm32_gpio_bank *bank,
unsigned long flags;
u32 val;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR);
val &= GENMASK(offset * 2 + 1, offset * 2);
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return (val >> (offset * 2));
}
@@ -996,7 +1009,6 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank,
u32 val;
int err = 0;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
if (pctl->hwlock) {
@@ -1020,7 +1032,6 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank,
unlock:
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return err;
}
@@ -1031,14 +1042,12 @@ static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank,
unsigned long flags;
u32 val;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
val = readl_relaxed(bank->base + STM32_GPIO_PUPDR);
val &= GENMASK(offset * 2 + 1, offset * 2);
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return (val >> (offset * 2));
}
@@ -1049,7 +1058,6 @@ static bool stm32_pconf_get(struct stm32_gpio_bank *bank,
unsigned long flags;
u32 val;
- clk_enable(bank->clk);
spin_lock_irqsave(&bank->lock, flags);
if (dir)
@@ -1060,7 +1068,6 @@ static bool stm32_pconf_get(struct stm32_gpio_bank *bank,
BIT(offset));
spin_unlock_irqrestore(&bank->lock, flags);
- clk_disable(bank->clk);
return val;
}
@@ -1083,6 +1090,11 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev,
bank = gpiochip_get_data(range->gc);
offset = stm32_gpio_pin(pin);
+ if (!gpiochip_line_is_valid(range->gc, offset)) {
+ dev_warn(pctl->dev, "Can't access gpio %d\n", pin);
+ return -EACCES;
+ }
+
switch (param) {
case PIN_CONFIG_DRIVE_PUSH_PULL:
ret = stm32_pconf_set_driving(bank, offset, 0);
@@ -1162,10 +1174,27 @@ static int stm32_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
return 0;
}
+static struct stm32_desc_pin *
+stm32_pconf_get_pin_desc_by_pin_number(struct stm32_pinctrl *pctl,
+ unsigned int pin_number)
+{
+ struct stm32_desc_pin *pins = pctl->pins;
+ int i;
+
+ for (i = 0; i < pctl->npins; i++) {
+ if (pins->pin.number == pin_number)
+ return pins;
+ pins++;
+ }
+ return NULL;
+}
+
static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned int pin)
{
+ struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ const struct stm32_desc_pin *pin_desc;
struct pinctrl_gpio_range *range;
struct stm32_gpio_bank *bank;
int offset;
@@ -1185,6 +1214,11 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
bank = gpiochip_get_data(range->gc);
offset = stm32_gpio_pin(pin);
+ if (!gpiochip_line_is_valid(range->gc, offset)) {
+ seq_puts(s, "NO ACCESS");
+ return;
+ }
+
stm32_pmx_get_mode(bank, offset, &mode, &alt);
bias = stm32_pconf_get_bias(bank, offset);
@@ -1215,7 +1249,12 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev,
case 2:
drive = stm32_pconf_get_driving(bank, offset);
speed = stm32_pconf_get_speed(bank, offset);
- seq_printf(s, "%d - %s - %s - %s %s", alt,
+ pin_desc = stm32_pconf_get_pin_desc_by_pin_number(pctl, pin);
+ if (!pin_desc)
+ return;
+
+ seq_printf(s, "%d (%s) - %s - %s - %s %s", alt,
+ pin_desc->functions[alt + 1].name,
drive ? "open drain" : "push pull",
biasing[bias],
speeds[speed], "speed");
@@ -1234,13 +1273,12 @@ static const struct pinconf_ops stm32_pconf_ops = {
.pin_config_dbg_show = stm32_pconf_dbg_show,
};
-static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
- struct device_node *np)
+static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode_handle *fwnode)
{
struct stm32_gpio_bank *bank = &pctl->banks[pctl->nbanks];
int bank_ioport_nr;
struct pinctrl_gpio_range *range = &bank->range;
- struct of_phandle_args args;
+ struct fwnode_reference_args args;
struct device *dev = pctl->dev;
struct resource res;
int npins = STM32_GPIO_PINS_PER_BANK;
@@ -1249,30 +1287,30 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
if (!IS_ERR(bank->rstc))
reset_control_deassert(bank->rstc);
- if (of_address_to_resource(np, 0, &res))
+ if (of_address_to_resource(to_of_node(fwnode), 0, &res))
return -ENODEV;
bank->base = devm_ioremap_resource(dev, &res);
if (IS_ERR(bank->base))
return PTR_ERR(bank->base);
- err = clk_prepare(bank->clk);
+ err = clk_prepare_enable(bank->clk);
if (err) {
- dev_err(dev, "failed to prepare clk (%d)\n", err);
+ dev_err(dev, "failed to prepare_enable clk (%d)\n", err);
return err;
}
bank->gpio_chip = stm32_gpio_template;
- of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label);
+ fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label);
- if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, i, &args)) {
+ if (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, i, &args)) {
bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.base = args.args[1];
/* get the last defined gpio line (offset + nb of pins) */
npins = args.args[0] + args.args[2];
- while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ++i, &args))
+ while (!fwnode_property_get_reference_args(fwnode, "gpio-ranges", NULL, 3, ++i, &args))
npins = max(npins, (int)(args.args[0] + args.args[2]));
} else {
bank_nr = pctl->nbanks;
@@ -1287,40 +1325,48 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
&pctl->banks[bank_nr].range);
}
- if (of_property_read_u32(np, "st,bank-ioport", &bank_ioport_nr))
+ if (fwnode_property_read_u32(fwnode, "st,bank-ioport", &bank_ioport_nr))
bank_ioport_nr = bank_nr;
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.ngpio = npins;
- bank->gpio_chip.of_node = np;
+ bank->gpio_chip.fwnode = fwnode;
bank->gpio_chip.parent = dev;
bank->bank_nr = bank_nr;
bank->bank_ioport_nr = bank_ioport_nr;
+ bank->secure_control = pctl->match_data->secure_control;
spin_lock_init(&bank->lock);
/* create irq hierarchical domain */
- bank->fwnode = of_node_to_fwnode(np);
+ bank->fwnode = fwnode;
bank->domain = irq_domain_create_hierarchy(pctl->domain, 0,
STM32_GPIO_IRQ_LINE, bank->fwnode,
&stm32_gpio_domain_ops, bank);
- if (!bank->domain)
- return -ENODEV;
+ if (!bank->domain) {
+ err = -ENODEV;
+ goto err_clk;
+ }
err = gpiochip_add_data(&bank->gpio_chip, bank);
if (err) {
dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr);
- return err;
+ goto err_clk;
}
dev_info(dev, "%s bank added\n", bank->gpio_chip.label);
return 0;
+
+err_clk:
+ clk_disable_unprepare(bank->clk);
+ return err;
}
-static struct irq_domain *stm32_pctrl_get_irq_domain(struct device_node *np)
+static struct irq_domain *stm32_pctrl_get_irq_domain(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
struct device_node *parent;
struct irq_domain *domain;
@@ -1424,7 +1470,8 @@ static int stm32_pctrl_create_pins_tab(struct stm32_pinctrl *pctl,
if (pctl->pkg && !(pctl->pkg & p->pkg))
continue;
pins->pin = p->pin;
- pins->functions = p->functions;
+ memcpy((struct stm32_desc_pin *)pins->functions, p->functions,
+ STM32_CONFIG_NUM * sizeof(struct stm32_desc_function));
pins++;
nb_pins_available++;
}
@@ -1436,22 +1483,19 @@ static int stm32_pctrl_create_pins_tab(struct stm32_pinctrl *pctl,
int stm32_pctl_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *child;
- const struct of_device_id *match;
+ const struct stm32_pinctrl_match_data *match_data;
+ struct fwnode_handle *child;
struct device *dev = &pdev->dev;
struct stm32_pinctrl *pctl;
struct pinctrl_pin_desc *pins;
- int i, ret, hwlock_id, banks = 0;
+ int i, ret, hwlock_id;
+ unsigned int banks;
- if (!np)
+ match_data = device_get_match_data(dev);
+ if (!match_data)
return -EINVAL;
- match = of_match_device(dev->driver->of_match_table, dev);
- if (!match || !match->data)
- return -EINVAL;
-
- if (!of_find_property(np, "pins-are-numbered", NULL)) {
+ if (!device_property_present(dev, "pins-are-numbered")) {
dev_err(dev, "only support pins-are-numbered format\n");
return -EINVAL;
}
@@ -1463,7 +1507,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pctl);
/* check for IRQ controller (may require deferred probe) */
- pctl->domain = stm32_pctrl_get_irq_domain(np);
+ pctl->domain = stm32_pctrl_get_irq_domain(pdev);
if (IS_ERR(pctl->domain))
return PTR_ERR(pctl->domain);
@@ -1479,10 +1523,10 @@ int stm32_pctl_probe(struct platform_device *pdev)
spin_lock_init(&pctl->irqmux_lock);
pctl->dev = dev;
- pctl->match_data = match->data;
+ pctl->match_data = match_data;
/* get optional package information */
- if (!of_property_read_u32(np, "st,package", &pctl->pkg))
+ if (!device_property_read_u32(dev, "st,package", &pctl->pkg))
dev_dbg(pctl->dev, "package detected: %x\n", pctl->pkg);
pctl->pins = devm_kcalloc(pctl->dev, pctl->match_data->npins,
@@ -1532,10 +1576,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
return PTR_ERR(pctl->pctl_dev);
}
- for_each_available_child_of_node(np, child)
- if (of_property_read_bool(child, "gpio-controller"))
- banks++;
-
+ banks = gpiochip_node_count(dev);
if (!banks) {
dev_err(dev, "at least one GPIO bank is required\n");
return -EINVAL;
@@ -1546,40 +1587,38 @@ int stm32_pctl_probe(struct platform_device *pdev)
return -ENOMEM;
i = 0;
- for_each_available_child_of_node(np, child) {
+ for_each_gpiochip_node(dev, child) {
struct stm32_gpio_bank *bank = &pctl->banks[i];
+ struct device_node *np = to_of_node(child);
- if (of_property_read_bool(child, "gpio-controller")) {
- bank->rstc = of_reset_control_get_exclusive(child,
- NULL);
- if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
- of_node_put(child);
- return -EPROBE_DEFER;
- }
+ bank->rstc = of_reset_control_get_exclusive(np, NULL);
+ if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) {
+ fwnode_handle_put(child);
+ return -EPROBE_DEFER;
+ }
- bank->clk = of_clk_get_by_name(child, NULL);
- if (IS_ERR(bank->clk)) {
- if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
- dev_err(dev,
- "failed to get clk (%ld)\n",
- PTR_ERR(bank->clk));
- of_node_put(child);
- return PTR_ERR(bank->clk);
- }
- i++;
+ bank->clk = of_clk_get_by_name(np, NULL);
+ if (IS_ERR(bank->clk)) {
+ if (PTR_ERR(bank->clk) != -EPROBE_DEFER)
+ dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk));
+ fwnode_handle_put(child);
+ return PTR_ERR(bank->clk);
}
+ i++;
}
- for_each_available_child_of_node(np, child) {
- if (of_property_read_bool(child, "gpio-controller")) {
- ret = stm32_gpiolib_register_bank(pctl, child);
- if (ret) {
- of_node_put(child);
- return ret;
- }
+ for_each_gpiochip_node(dev, child) {
+ ret = stm32_gpiolib_register_bank(pctl, child);
+ if (ret) {
+ fwnode_handle_put(child);
+
+ for (i = 0; i < pctl->nbanks; i++)
+ clk_disable_unprepare(pctl->banks[i].clk);
- pctl->nbanks++;
+ return ret;
}
+
+ pctl->nbanks++;
}
dev_info(dev, "Pinctrl STM32 initialized\n");
@@ -1601,6 +1640,9 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
if (!range)
return 0;
+ if (!gpiochip_line_is_valid(range->gc, offset))
+ return 0;
+
pin_is_irq = gpiochip_line_is_irq(range->gc, offset);
if (!desc || (!pin_is_irq && !desc->gpio_owner))
@@ -1647,12 +1689,26 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs(
return 0;
}
+int __maybe_unused stm32_pinctrl_suspend(struct device *dev)
+{
+ struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < pctl->nbanks; i++)
+ clk_disable(pctl->banks[i].clk);
+
+ return 0;
+}
+
int __maybe_unused stm32_pinctrl_resume(struct device *dev)
{
struct stm32_pinctrl *pctl = dev_get_drvdata(dev);
struct stm32_pinctrl_group *g = pctl->groups;
int i;
+ for (i = 0; i < pctl->nbanks; i++)
+ clk_enable(pctl->banks[i].clk);
+
for (i = 0; i < pctl->ngroups; i++, g++)
stm32_pinctrl_restore_gpio_regs(pctl, g->pin);