Commit ede950b0 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v6.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:
 "I'm mostly on vacation but what would vacation be without a few
  critical fixes so people can use their gaming laptops when hiding away
  from the sun (or rain)?

   - Fix a really annoying interrupt storm in the AMD driver affecting
     Asus TUF gaming notebooks

   - Fix device tree parsing in the Renesas driver"

* tag 'pinctrl-v6.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: amd: Unify debounce handling into amd_pinconf_set()
  pinctrl: amd: Drop pull up select configuration
  pinctrl: amd: Use amd_pinconf_set() for all config options
  pinctrl: amd: Only use special debounce behavior for GPIO 0
  pinctrl: renesas: rzg2l: Handle non-unique subnode names
  pinctrl: renesas: rzv2m: Handle non-unique subnode names
parents fe756ad0 04e601f2
...@@ -116,21 +116,19 @@ static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value) ...@@ -116,21 +116,19 @@ static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value)
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
} }
static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, static int amd_gpio_set_debounce(struct amd_gpio *gpio_dev, unsigned int offset,
unsigned debounce) unsigned int debounce)
{ {
u32 time; u32 time;
u32 pin_reg; u32 pin_reg;
int ret = 0; int ret = 0;
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
/* Use special handling for Pin0 debounce */ /* Use special handling for Pin0 debounce */
pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); if (offset == 0) {
if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
debounce = 0; if (pin_reg & INTERNAL_GPIO0_DEBOUNCE)
debounce = 0;
}
pin_reg = readl(gpio_dev->base + offset * 4); pin_reg = readl(gpio_dev->base + offset * 4);
...@@ -182,23 +180,10 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, ...@@ -182,23 +180,10 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF);
} }
writel(pin_reg, gpio_dev->base + offset * 4); writel(pin_reg, gpio_dev->base + offset * 4);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret; return ret;
} }
static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset,
unsigned long config)
{
u32 debounce;
if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
return -ENOTSUPP;
debounce = pinconf_to_config_argument(config);
return amd_gpio_set_debounce(gc, offset, debounce);
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
{ {
...@@ -220,7 +205,6 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) ...@@ -220,7 +205,6 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
char *pin_sts; char *pin_sts;
char *interrupt_sts; char *interrupt_sts;
char *wake_sts; char *wake_sts;
char *pull_up_sel;
char *orientation; char *orientation;
char debounce_value[40]; char debounce_value[40];
char *debounce_enable; char *debounce_enable;
...@@ -328,14 +312,9 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) ...@@ -328,14 +312,9 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
seq_printf(s, " %s|", wake_sts); seq_printf(s, " %s|", wake_sts);
if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) { if (pin_reg & BIT(PULL_UP_ENABLE_OFF)) {
if (pin_reg & BIT(PULL_UP_SEL_OFF)) seq_puts(s, " ↑ |");
pull_up_sel = "8k";
else
pull_up_sel = "4k";
seq_printf(s, "%s ↑|",
pull_up_sel);
} else if (pin_reg & BIT(PULL_DOWN_ENABLE_OFF)) { } else if (pin_reg & BIT(PULL_DOWN_ENABLE_OFF)) {
seq_puts(s, " |"); seq_puts(s, " |");
} else { } else {
seq_puts(s, " |"); seq_puts(s, " |");
} }
...@@ -761,7 +740,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -761,7 +740,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev,
break; break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
arg = (pin_reg >> PULL_UP_SEL_OFF) & (BIT(0) | BIT(1)); arg = (pin_reg >> PULL_UP_ENABLE_OFF) & BIT(0);
break; break;
case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_DRIVE_STRENGTH:
...@@ -780,7 +759,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -780,7 +759,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned num_configs) unsigned long *configs, unsigned int num_configs)
{ {
int i; int i;
u32 arg; u32 arg;
...@@ -798,9 +777,8 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -798,9 +777,8 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch (param) { switch (param) {
case PIN_CONFIG_INPUT_DEBOUNCE: case PIN_CONFIG_INPUT_DEBOUNCE:
pin_reg &= ~DB_TMR_OUT_MASK; ret = amd_gpio_set_debounce(gpio_dev, pin, arg);
pin_reg |= arg & DB_TMR_OUT_MASK; goto out_unlock;
break;
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
pin_reg &= ~BIT(PULL_DOWN_ENABLE_OFF); pin_reg &= ~BIT(PULL_DOWN_ENABLE_OFF);
...@@ -808,10 +786,8 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -808,10 +786,8 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
break; break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
pin_reg &= ~BIT(PULL_UP_SEL_OFF);
pin_reg |= (arg & BIT(0)) << PULL_UP_SEL_OFF;
pin_reg &= ~BIT(PULL_UP_ENABLE_OFF); pin_reg &= ~BIT(PULL_UP_ENABLE_OFF);
pin_reg |= ((arg>>1) & BIT(0)) << PULL_UP_ENABLE_OFF; pin_reg |= (arg & BIT(0)) << PULL_UP_ENABLE_OFF;
break; break;
case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_DRIVE_STRENGTH:
...@@ -829,6 +805,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -829,6 +805,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
writel(pin_reg, gpio_dev->base + pin*4); writel(pin_reg, gpio_dev->base + pin*4);
} }
out_unlock:
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret; return ret;
...@@ -870,6 +847,14 @@ static int amd_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -870,6 +847,14 @@ static int amd_pinconf_group_set(struct pinctrl_dev *pctldev,
return 0; return 0;
} }
static int amd_gpio_set_config(struct gpio_chip *gc, unsigned int pin,
unsigned long config)
{
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1);
}
static const struct pinconf_ops amd_pinconf_ops = { static const struct pinconf_ops amd_pinconf_ops = {
.pin_config_get = amd_pinconf_get, .pin_config_get = amd_pinconf_get,
.pin_config_set = amd_pinconf_set, .pin_config_set = amd_pinconf_set,
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#define WAKE_CNTRL_OFF_S4 15 #define WAKE_CNTRL_OFF_S4 15
#define PIN_STS_OFF 16 #define PIN_STS_OFF 16
#define DRV_STRENGTH_SEL_OFF 17 #define DRV_STRENGTH_SEL_OFF 17
#define PULL_UP_SEL_OFF 19
#define PULL_UP_ENABLE_OFF 20 #define PULL_UP_ENABLE_OFF 20
#define PULL_DOWN_ENABLE_OFF 21 #define PULL_DOWN_ENABLE_OFF 21
#define OUTPUT_VALUE_OFF 22 #define OUTPUT_VALUE_OFF 22
......
...@@ -249,6 +249,7 @@ static int rzg2l_map_add_config(struct pinctrl_map *map, ...@@ -249,6 +249,7 @@ static int rzg2l_map_add_config(struct pinctrl_map *map,
static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct device_node *np,
struct device_node *parent,
struct pinctrl_map **map, struct pinctrl_map **map,
unsigned int *num_maps, unsigned int *num_maps,
unsigned int *index) unsigned int *index)
...@@ -266,6 +267,7 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -266,6 +267,7 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct property *prop; struct property *prop;
int ret, gsel, fsel; int ret, gsel, fsel;
const char **pin_fn; const char **pin_fn;
const char *name;
const char *pin; const char *pin;
pinmux = of_find_property(np, "pinmux", NULL); pinmux = of_find_property(np, "pinmux", NULL);
...@@ -349,8 +351,19 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -349,8 +351,19 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
psel_val[i] = MUX_FUNC(value); psel_val[i] = MUX_FUNC(value);
} }
if (parent) {
name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn",
parent, np);
if (!name) {
ret = -ENOMEM;
goto done;
}
} else {
name = np->name;
}
/* Register a single pin group listing all the pins we read from DT */ /* Register a single pin group listing all the pins we read from DT */
gsel = pinctrl_generic_add_group(pctldev, np->name, pins, num_pinmux, NULL); gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
if (gsel < 0) { if (gsel < 0) {
ret = gsel; ret = gsel;
goto done; goto done;
...@@ -360,17 +373,16 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -360,17 +373,16 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
* Register a single group function where the 'data' is an array PSEL * Register a single group function where the 'data' is an array PSEL
* register values read from DT. * register values read from DT.
*/ */
pin_fn[0] = np->name; pin_fn[0] = name;
fsel = pinmux_generic_add_function(pctldev, np->name, pin_fn, 1, fsel = pinmux_generic_add_function(pctldev, name, pin_fn, 1, psel_val);
psel_val);
if (fsel < 0) { if (fsel < 0) {
ret = fsel; ret = fsel;
goto remove_group; goto remove_group;
} }
maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
maps[idx].data.mux.group = np->name; maps[idx].data.mux.group = name;
maps[idx].data.mux.function = np->name; maps[idx].data.mux.function = name;
idx++; idx++;
dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux); dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux);
...@@ -417,7 +429,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -417,7 +429,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
index = 0; index = 0;
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
ret = rzg2l_dt_subnode_to_map(pctldev, child, map, ret = rzg2l_dt_subnode_to_map(pctldev, child, np, map,
num_maps, &index); num_maps, &index);
if (ret < 0) { if (ret < 0) {
of_node_put(child); of_node_put(child);
...@@ -426,7 +438,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -426,7 +438,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
} }
if (*num_maps == 0) { if (*num_maps == 0) {
ret = rzg2l_dt_subnode_to_map(pctldev, np, map, ret = rzg2l_dt_subnode_to_map(pctldev, np, NULL, map,
num_maps, &index); num_maps, &index);
if (ret < 0) if (ret < 0)
goto done; goto done;
......
...@@ -209,6 +209,7 @@ static int rzv2m_map_add_config(struct pinctrl_map *map, ...@@ -209,6 +209,7 @@ static int rzv2m_map_add_config(struct pinctrl_map *map,
static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct device_node *np,
struct device_node *parent,
struct pinctrl_map **map, struct pinctrl_map **map,
unsigned int *num_maps, unsigned int *num_maps,
unsigned int *index) unsigned int *index)
...@@ -226,6 +227,7 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -226,6 +227,7 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct property *prop; struct property *prop;
int ret, gsel, fsel; int ret, gsel, fsel;
const char **pin_fn; const char **pin_fn;
const char *name;
const char *pin; const char *pin;
pinmux = of_find_property(np, "pinmux", NULL); pinmux = of_find_property(np, "pinmux", NULL);
...@@ -309,8 +311,19 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -309,8 +311,19 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
psel_val[i] = MUX_FUNC(value); psel_val[i] = MUX_FUNC(value);
} }
if (parent) {
name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn",
parent, np);
if (!name) {
ret = -ENOMEM;
goto done;
}
} else {
name = np->name;
}
/* Register a single pin group listing all the pins we read from DT */ /* Register a single pin group listing all the pins we read from DT */
gsel = pinctrl_generic_add_group(pctldev, np->name, pins, num_pinmux, NULL); gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
if (gsel < 0) { if (gsel < 0) {
ret = gsel; ret = gsel;
goto done; goto done;
...@@ -320,17 +333,16 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -320,17 +333,16 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
* Register a single group function where the 'data' is an array PSEL * Register a single group function where the 'data' is an array PSEL
* register values read from DT. * register values read from DT.
*/ */
pin_fn[0] = np->name; pin_fn[0] = name;
fsel = pinmux_generic_add_function(pctldev, np->name, pin_fn, 1, fsel = pinmux_generic_add_function(pctldev, name, pin_fn, 1, psel_val);
psel_val);
if (fsel < 0) { if (fsel < 0) {
ret = fsel; ret = fsel;
goto remove_group; goto remove_group;
} }
maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
maps[idx].data.mux.group = np->name; maps[idx].data.mux.group = name;
maps[idx].data.mux.function = np->name; maps[idx].data.mux.function = name;
idx++; idx++;
dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux); dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux);
...@@ -377,7 +389,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -377,7 +389,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev,
index = 0; index = 0;
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
ret = rzv2m_dt_subnode_to_map(pctldev, child, map, ret = rzv2m_dt_subnode_to_map(pctldev, child, np, map,
num_maps, &index); num_maps, &index);
if (ret < 0) { if (ret < 0) {
of_node_put(child); of_node_put(child);
...@@ -386,7 +398,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -386,7 +398,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev,
} }
if (*num_maps == 0) { if (*num_maps == 0) {
ret = rzv2m_dt_subnode_to_map(pctldev, np, map, ret = rzv2m_dt_subnode_to_map(pctldev, np, NULL, map,
num_maps, &index); num_maps, &index);
if (ret < 0) if (ret < 0)
goto done; goto done;
......
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