linux/drivers/pinctrl
Evgenii Shatokhin 8c6fd5803b pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking
commit a37eecb705 upstream.

If a device uses MCP23xxx IO expander to receive IRQs, the following
bug can happen:

  BUG: sleeping function called from invalid context
    at kernel/locking/mutex.c:283
  in_atomic(): 1, irqs_disabled(): 1, non_block: 0, ...
  preempt_count: 1, expected: 0
  ...
  Call Trace:
  ...
  __might_resched+0x104/0x10e
  __might_sleep+0x3e/0x62
  mutex_lock+0x20/0x4c
  regmap_lock_mutex+0x10/0x18
  regmap_update_bits_base+0x2c/0x66
  mcp23s08_irq_set_type+0x1ae/0x1d6
  __irq_set_trigger+0x56/0x172
  __setup_irq+0x1e6/0x646
  request_threaded_irq+0xb6/0x160
  ...

We observed the problem while experimenting with a touchscreen driver which
used MCP23017 IO expander (I2C).

The regmap in the pinctrl-mcp23s08 driver uses a mutex for protection from
concurrent accesses, which is the default for regmaps without .fast_io,
.disable_locking, etc.

mcp23s08_irq_set_type() calls regmap_update_bits_base(), and the latter
locks the mutex.

However, __setup_irq() locks desc->lock spinlock before calling these
functions. As a result, the system tries to lock the mutex whole holding
the spinlock.

It seems, the internal regmap locks are not needed in this driver at all.
mcp->lock seems to protect the regmap from concurrent accesses already,
except, probably, in mcp_pinconf_get/set.

mcp23s08_irq_set_type() and mcp23s08_irq_mask/unmask() are called under
chip_bus_lock(), which calls mcp23s08_irq_bus_lock(). The latter takes
mcp->lock and enables regmap caching, so that the potentially slow I2C
accesses are deferred until chip_bus_unlock().

The accesses to the regmap from mcp23s08_probe_one() do not need additional
locking.

In all remaining places where the regmap is accessed, except
mcp_pinconf_get/set(), the driver already takes mcp->lock.

This patch adds locking in mcp_pinconf_get/set() and disables internal
locking in the regmap config. Among other things, it fixes the sleeping
in atomic context described above.

Fixes: 8f38910ba4 ("pinctrl: mcp23s08: switch to regmap caching")
Cc: stable@vger.kernel.org
Signed-off-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
Link: https://lore.kernel.org/20241209074659.1442898-1-e.shatokhin@yadro.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2025-01-09 13:32:07 +01:00
..
actions pinctrl: actions: remove MODULE_LICENSE in non-modules 2023-04-13 13:13:50 -07:00
aspeed pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T 2024-05-17 12:01:56 +02:00
bcm pinctrl: Use device_get_match_data() 2024-10-04 16:29:27 +02:00
berlin pinctrl: Use device_get_match_data() 2024-10-04 16:29:27 +02:00
cirrus pinctrl: lochnagar: Don't build on MIPS 2024-01-20 11:51:37 +01:00
freescale pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU 2024-12-14 20:00:10 +01:00
intel pinctrl: meteorlake: Add Arrow Lake-H/U ACPI ID 2024-09-18 19:24:10 +02:00
mediatek pinctrl: mediatek: common-v2: Fix broken bias-disable for PULL_PU_PD_RSEL_TYPE 2024-09-04 13:28:23 +02:00
meson pinctrl/meson: fix typo in PDM's pin name 2024-05-17 12:01:57 +02:00
mvebu pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function 2024-10-04 16:29:32 +02:00
nomadik pinctrl: Use device_get_match_data() 2024-10-04 16:29:27 +02:00
nuvoton pinctrl: nuvoton: wpcm450: fix out of bounds write 2023-09-12 09:03:18 +02:00
nxp pinctrl: s32cc: Avoid possible string truncation 2024-01-20 11:51:37 +01:00
pxa pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
qcom pinctrl: qcom: spmi-mpp: Add PM8937 compatible 2024-12-14 20:00:12 +01:00
renesas pinctrl: renesas: r8a779g0: Fix TPU suffixes 2024-08-03 08:54:09 +02:00
samsung pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
spear pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
sprd pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
starfive pinctrl: starfive: jh7110: Correct the level trigger configuration of iev register 2024-09-04 13:28:23 +02:00
stm32 pinctrl: stm32: check devm_kasprintf() returned value 2024-10-22 15:46:34 +02:00
sunplus pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
sunxi pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
tegra Revert "pinctrl: tegra: Add support to display pin function" 2023-09-27 10:51:57 +02:00
ti pinctrl: ti: ti-iodelay: Fix some error handling paths 2024-10-04 16:29:28 +02:00
uniphier pinctrl: uniphier: Add missing header(s) 2022-10-24 17:06:47 +03:00
visconti gpio: visconti: Add Toshiba Visconti GPIO support 2021-02-15 11:43:26 +01:00
vt8500 pinctrl: Get rid of duplicate of_node assignment in the drivers 2021-12-16 04:18:30 +01:00
core.c pinmux: Use sequential access to access desc->pinmux data 2024-12-14 20:00:11 +01:00
core.h pinmux: Use sequential access to access desc->pinmux data 2024-12-14 20:00:11 +01:00
devicetree.c pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() 2024-05-17 12:01:58 +02:00
devicetree.h pinctrl: Clean up headers 2022-10-24 17:06:48 +03:00
Kconfig pinctrl: pinctrl-oxnas: remove obsolete pinctrl driver 2023-08-15 11:06:32 +02:00
Makefile pinctrl: pinctrl-oxnas: remove obsolete pinctrl driver 2023-08-15 11:06:32 +02:00
pinconf-generic.c pinctrl: pinconf-generic: add missing of_node_put() 2022-11-25 10:49:28 +01:00
pinconf.c pinctrl: use to octal permissions for debugfs files 2021-03-10 14:41:58 +01:00
pinconf.h pinctrl: Clean up headers 2022-10-24 17:06:48 +03:00
pinctrl-amd.c pinctrl: amd: Mask non-wake source pins with interrupt enabled at suspend 2024-01-20 11:51:44 +01:00
pinctrl-amd.h pinctrl: amd: Mask non-wake source pins with interrupt enabled at suspend 2024-01-20 11:51:44 +01:00
pinctrl-apple-gpio.c pinctrl: apple: check devm_kasprintf() returned value 2024-10-22 15:46:34 +02:00
pinctrl-artpec6.c pinctrl: artpec6: fix __iomem on reg in set 2020-01-07 13:57:17 +01:00
pinctrl-as3722.c treewide: Replace GPLv2 boilerplate/reference with SPDX - gpl-2.0_318.RULE 2022-06-10 14:51:36 +02:00
pinctrl-at91-pio4.c pinctrl: at91-pio4: use dedicated lock class for IRQ 2024-01-01 12:42:35 +00:00
pinctrl-at91.c pinctrl: Use device_get_match_data() 2024-10-04 16:29:27 +02:00
pinctrl-at91.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
pinctrl-axp209.c pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
pinctrl-bm1880.c pinctrl: bm1880: Add missing header(s) 2022-10-24 12:53:33 +03:00
pinctrl-cy8c95x0.c pinctrl: cy8c95x0: Fix get_pincfg 2024-01-20 11:51:46 +01:00
pinctrl-da850-pupd.c pinctrl: da850-pupd: Drop empty platform remove function 2022-12-29 02:02:46 +01:00
pinctrl-da9062.c pinctrl: Propagate firmware node from a parent device 2021-12-22 03:09:56 +01:00
pinctrl-digicolor.c pinctrl: digicolor: Use proper headers and drop OF dependency 2023-01-16 15:14:03 +01:00
pinctrl-equilibrium.c pinctrl: equilibrium: Convert to immutable irq_chip 2023-04-14 11:08:17 +02:00
pinctrl-equilibrium.h pinctrl: equilibrium: Convert to immutable irq_chip 2023-04-14 11:08:17 +02:00
pinctrl-falcon.c pinctrl: lantiq: Remove unused of_gpio.h inclusion 2023-06-16 15:04:34 +02:00
pinctrl-gemini.c pinctrl: gemini: Add missing header(s) 2022-10-24 17:06:45 +03:00
pinctrl-ingenic.c Pin control changes for the v6.2 kernel cycle: 2022-12-13 13:03:06 -08:00
pinctrl-k210.c pinctrl: k210: Undef K210_PC_DEFAULT 2024-12-09 10:32:22 +01:00
pinctrl-keembay.c pinctrl: keembay: rework loops looking for groups names 2021-12-22 02:57:27 +01:00
pinctrl-lantiq.c pinctrl: lantiq: Add missing header(s) 2022-10-24 17:06:46 +03:00
pinctrl-lantiq.h pinctrl: lantiq: Remove unsued declaration ltq_pinctrl_unregister() 2023-09-11 15:42:12 +02:00
pinctrl-loongson2.c pinctrl: loongson2: Fix some const correctness 2022-11-25 11:41:01 +01:00
pinctrl-lpc18xx.c pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
pinctrl-max77620.c pinctrl: max77620: drop unneeded MODULE_ALIAS 2022-04-22 22:56:46 +02:00
pinctrl-mcp23s08.c pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking 2025-01-09 13:32:07 +01:00
pinctrl-mcp23s08.h pinctrl: mcp23s08: Convert to immutable irq_chip 2023-04-14 11:08:17 +02:00
pinctrl-mcp23s08_i2c.c pinctrl: Switch i2c drivers back to use .probe() 2023-05-29 15:16:30 +02:00
pinctrl-mcp23s08_spi.c pinctrl: mcp23s08: check return value of devm_kasprintf() 2023-08-10 09:56:31 +02:00
pinctrl-microchip-sgpio.c pinctrl: microchip-sgpio: check return value of devm_kasprintf() 2023-06-16 15:01:45 +02:00
pinctrl-mlxbf3.c pinctrl: mlxbf3: Remove gpio_disable_free() 2023-08-25 15:44:15 +02:00
pinctrl-ocelot.c pinctrl: ocelot: fix system hang on level based interrupts 2024-10-22 15:46:34 +02:00
pinctrl-palmas.c pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
pinctrl-pic32.c pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
pinctrl-pic32.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 445 2019-06-05 17:37:18 +02:00
pinctrl-pistachio.c pinctrl: pistachio: Convert to immutable irq_chip 2023-04-20 16:07:40 +02:00
pinctrl-rk805.c pinctrl: rk805: Add rk806 pinctrl support 2023-05-15 16:21:01 +01:00
pinctrl-rockchip.c pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins 2024-09-04 13:28:19 +02:00
pinctrl-rockchip.h pinctrl: rockchip: use dedicated pinctrl type for RK3328 2024-07-05 09:33:43 +02:00
pinctrl-single.c pinctrl: single: fix missing error code in pcs_probe() 2024-10-04 16:29:30 +02:00
pinctrl-st.c pinctrl: st: Convert to immutable irq_chip 2023-04-14 11:08:17 +02:00
pinctrl-stmfx.c pinctrl: stmfx: Do not check for 0 return after calling platform_get_irq() 2023-08-10 10:11:33 +02:00
pinctrl-sx150x.c pinctrl: Explicitly include correct DT includes 2023-07-20 21:41:24 +02:00
pinctrl-tb10x.c pinctrl: use devm_platform_ioremap_resource() to simplify code 2019-11-05 15:33:40 +01:00
pinctrl-utils.c treewide: Replace GPLv2 boilerplate/reference with SPDX - gpl-2.0_318.RULE 2022-06-10 14:51:36 +02:00
pinctrl-utils.h pinctrl: Clean up headers 2022-10-24 17:06:48 +03:00
pinctrl-xway.c pinctrl: Use device_get_match_data() 2024-10-04 16:29:27 +02:00
pinctrl-zynq.c pinctrl: zynq: use module_platform_driver to simplify the code 2022-03-15 01:46:13 +01:00
pinctrl-zynqmp.c pinctrl: zynqmp: drop excess struct member description 2024-12-09 10:32:13 +01:00
pinmux.c pinmux: Use sequential access to access desc->pinmux data 2024-12-14 20:00:11 +01:00
pinmux.h pinctrl: Clean up headers 2022-10-24 17:06:48 +03:00