mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-11 15:46:40 +02:00
Merge tag 'pinctrl-v6.7-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control fixes from Linus Walleij:
"Some driver fixes for v6.7, all are in drivers, the most interesting
one is probably the AMD laptop suspend bug which really needs fixing.
Freedestop org has the bug description:
https://gitlab.freedesktop.org/drm/amd/-/issues/2812
Summary:
- Ignore disabled device tree nodes in the Starfive 7100 and 7100
drivers.
- Mask non-wake source pins with interrupt enabled at suspend in the
AMD driver, this blocks unnecessary wakeups from misc interrupts.
This can be power consuming because in many cases the system
doesn't really suspend, it just wakes right back up.
- Fix a typo breaking compilation of the cy8c95x0 driver, and fix up
bugs in the get/set config callbacks.
- Use a dedicated lock class for the PIO4 drivers IRQ. This fixes a
crash on suspend"
* tag 'pinctrl-v6.7-4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
pinctrl: at91-pio4: use dedicated lock class for IRQ
pinctrl: cy8c95x0: Fix get_pincfg
pinctrl: cy8c95x0: Fix regression
pinctrl: cy8c95x0: Fix typo
pinctrl: amd: Mask non-wake source pins with interrupt enabled at suspend
pinctrl: starfive: jh7100: ignore disabled device tree nodes
pinctrl: starfive: jh7110: ignore disabled device tree nodes
This commit is contained in:
@@ -923,6 +923,15 @@ static int amd_gpio_suspend(struct device *dev)
|
||||
|
||||
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
|
||||
gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin * 4) & ~PIN_IRQ_PENDING;
|
||||
|
||||
/* mask any interrupts not intended to be a wake source */
|
||||
if (!(gpio_dev->saved_regs[i] & WAKE_SOURCE)) {
|
||||
writel(gpio_dev->saved_regs[i] & ~BIT(INTERRUPT_MASK_OFF),
|
||||
gpio_dev->base + pin * 4);
|
||||
pm_pr_dbg("Disabling GPIO #%d interrupt for suspend.\n",
|
||||
pin);
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@
|
||||
#define FUNCTION_MASK GENMASK(1, 0)
|
||||
#define FUNCTION_INVALID GENMASK(7, 0)
|
||||
|
||||
#define WAKE_SOURCE (BIT(WAKE_CNTRL_OFF_S0I3) | \
|
||||
BIT(WAKE_CNTRL_OFF_S3) | \
|
||||
BIT(WAKE_CNTRL_OFF_S4) | \
|
||||
BIT(WAKECNTRL_Z_OFF))
|
||||
|
||||
struct amd_function {
|
||||
const char *name;
|
||||
const char * const groups[NSELECTS];
|
||||
|
||||
@@ -1068,6 +1068,13 @@ static const struct of_device_id atmel_pctrl_of_match[] = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This lock class allows to tell lockdep that parent IRQ and children IRQ do
|
||||
* not share the same class so it does not raise false positive
|
||||
*/
|
||||
static struct lock_class_key atmel_lock_key;
|
||||
static struct lock_class_key atmel_request_key;
|
||||
|
||||
static int atmel_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -1214,6 +1221,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
|
||||
irq_set_chip_and_handler(irq, &atmel_gpio_irq_chip,
|
||||
handle_simple_irq);
|
||||
irq_set_chip_data(irq, atmel_pioctrl);
|
||||
irq_set_lockdep_class(irq, &atmel_lock_key, &atmel_request_key);
|
||||
dev_dbg(dev,
|
||||
"atmel gpio irq domain: hwirq: %d, linux irq: %d\n",
|
||||
i, irq);
|
||||
|
||||
@@ -308,6 +308,9 @@ static const char * const cy8c95x0_groups[] = {
|
||||
"gp77",
|
||||
};
|
||||
|
||||
static int cy8c95x0_pinmux_direction(struct cy8c95x0_pinctrl *chip,
|
||||
unsigned int pin, bool input);
|
||||
|
||||
static inline u8 cypress_get_port(struct cy8c95x0_pinctrl *chip, unsigned int pin)
|
||||
{
|
||||
/* Account for GPORT2 which only has 4 bits */
|
||||
@@ -712,6 +715,8 @@ static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip,
|
||||
ret = regmap_read(chip->regmap, reg, ®_val);
|
||||
if (reg_val & bit)
|
||||
arg = 1;
|
||||
if (param == PIN_CONFIG_OUTPUT_ENABLE)
|
||||
arg = !arg;
|
||||
|
||||
*config = pinconf_to_config_packed(param, (u16)arg);
|
||||
out:
|
||||
@@ -727,6 +732,7 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip,
|
||||
u8 port = cypress_get_port(chip, off);
|
||||
u8 bit = cypress_get_pin_mask(chip, off);
|
||||
unsigned long param = pinconf_to_config_param(config);
|
||||
unsigned long arg = pinconf_to_config_argument(config);
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
|
||||
@@ -765,6 +771,12 @@ static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip,
|
||||
case PIN_CONFIG_MODE_PWM:
|
||||
reg = CY8C95X0_PWMSEL;
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT_ENABLE:
|
||||
ret = cy8c95x0_pinmux_direction(chip, off, !arg);
|
||||
goto out;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
ret = cy8c95x0_pinmux_direction(chip, off, arg);
|
||||
goto out;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
goto out;
|
||||
@@ -822,7 +834,7 @@ static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip)
|
||||
gc->get_direction = cy8c95x0_gpio_get_direction;
|
||||
gc->get_multiple = cy8c95x0_gpio_get_multiple;
|
||||
gc->set_multiple = cy8c95x0_gpio_set_multiple;
|
||||
gc->set_config = gpiochip_generic_config,
|
||||
gc->set_config = gpiochip_generic_config;
|
||||
gc->can_sleep = true;
|
||||
gc->add_pin_ranges = cy8c95x0_add_pin_ranges;
|
||||
|
||||
|
||||
@@ -492,7 +492,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
|
||||
nmaps = 0;
|
||||
ngroups = 0;
|
||||
for_each_child_of_node(np, child) {
|
||||
for_each_available_child_of_node(np, child) {
|
||||
int npinmux = of_property_count_u32_elems(child, "pinmux");
|
||||
int npins = of_property_count_u32_elems(child, "pins");
|
||||
|
||||
@@ -527,7 +527,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
nmaps = 0;
|
||||
ngroups = 0;
|
||||
mutex_lock(&sfp->mutex);
|
||||
for_each_child_of_node(np, child) {
|
||||
for_each_available_child_of_node(np, child) {
|
||||
int npins;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
int ret;
|
||||
|
||||
ngroups = 0;
|
||||
for_each_child_of_node(np, child)
|
||||
for_each_available_child_of_node(np, child)
|
||||
ngroups += 1;
|
||||
nmaps = 2 * ngroups;
|
||||
|
||||
@@ -150,7 +150,7 @@ static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
|
||||
nmaps = 0;
|
||||
ngroups = 0;
|
||||
mutex_lock(&sfp->mutex);
|
||||
for_each_child_of_node(np, child) {
|
||||
for_each_available_child_of_node(np, child) {
|
||||
int npins = of_property_count_u32_elems(child, "pinmux");
|
||||
int *pins;
|
||||
u32 *pinmux;
|
||||
|
||||
Reference in New Issue
Block a user