Pin control fixes for v6.7:

- 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.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmWEv9gACgkQQRCzN7AZ
 XXPDxA/+M/gXlbck8v3YJCa3/u59CPJtl23K27daGFLvuqAf1V+ZOxqq7UinHDRW
 OXlCgefX74NRMYkfS1FS9wZfHqdt8j9xX7OEbnst/1Q7DwNDKjry9Ax/yebZ+VEn
 B6JxiWpAevdR1vPvt+5FvM/kCChav2p0BoMm4OnCVLAmWYOhr+rx36oKtfuOLoYx
 TCxYo7CNkaaTrEWMStAv5VDudddCHjryOqnLHulIy62FQ8u7BJI8NtvTbna3cJD9
 yrI2qBqvPFAAPANfsNikUPghyXUluqbRAPKyqNSBH6c5e2dbeRF4mNP16dawYOMF
 KM7qykob03IhcPOmYEjKTJZ2b8g3w2WFY/U/zw/cE1IXPqW+DMBz/C+jL2L5bRGc
 H3Xc3g/QVj4cdaNMOmKT4jtp1OOgkRwUiWh7ryoospb1ZuRL2nM9RQbnIx8Y//OP
 CRaDJ/SKLelf18JSiMeD+qX1mmjpBiTTQpAq++B4sr1StNzcJOTK9mx7zJG6YTDL
 WuKK809Dta1EXQtYFiKM8Qf5wYCXeID2D0xkn6lFumQ5RmywPiqJ38kfSww2poRh
 R0qEQEFaWTHEAWFn7G5m/RYKRQuoHiTTohUgWJj1FzAZeEOyXHUD3lRCwxfdmHRR
 pUQs0yoqPcoRlxrc9QHdIoNyNknRN2iO3Mg9yrgsvyunjPwl1Ns=
 =eKv/
 -----END PGP SIGNATURE-----

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:
Linus Torvalds 2023-12-21 16:19:27 -08:00
commit 24e0d2e527
6 changed files with 39 additions and 5 deletions

View File

@ -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);
}

View File

@ -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];

View File

@ -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);

View File

@ -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, &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;

View File

@ -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;

View File

@ -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;