4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Patrice Chotard <patrice.chot...@st.com>

commit b888fb6f2a278442933e3bfab70262e9a5365fb3 upstream.

Move the workaround from stmpe_gpio_irq_unmask() which is executed
in atomic context to stmpe_gpio_irq_sync_unlock() which is not.

It fixes the following issue:

[    1.500000] BUG: scheduling while atomic: swapper/1/0x00000002
[    1.500000] CPU: 0 PID: 1 Comm: swapper Not tainted 
4.15.0-rc2-00020-gbd4301f-dirty #28
[    1.520000] Hardware name: STM32 (Device Tree Support)
[    1.520000] [<0000bfc9>] (unwind_backtrace) from [<0000b347>] 
(show_stack+0xb/0xc)
[    1.530000] [<0000b347>] (show_stack) from [<0001fc49>] 
(__schedule_bug+0x39/0x58)
[    1.530000] [<0001fc49>] (__schedule_bug) from [<00168211>] 
(__schedule+0x23/0x2b2)
[    1.550000] [<00168211>] (__schedule) from [<001684f7>] (schedule+0x57/0x64)
[    1.550000] [<001684f7>] (schedule) from [<0016a513>] 
(schedule_timeout+0x137/0x164)
[    1.550000] [<0016a513>] (schedule_timeout) from [<00168b91>] 
(wait_for_common+0x8d/0xfc)
[    1.570000] [<00168b91>] (wait_for_common) from [<00139753>] 
(stm32f4_i2c_xfer+0xe9/0xfe)
[    1.580000] [<00139753>] (stm32f4_i2c_xfer) from [<00138545>] 
(__i2c_transfer+0x111/0x148)
[    1.590000] [<00138545>] (__i2c_transfer) from [<001385cf>] 
(i2c_transfer+0x53/0x70)
[    1.590000] [<001385cf>] (i2c_transfer) from [<001388a5>] 
(i2c_smbus_xfer+0x12f/0x36e)
[    1.600000] [<001388a5>] (i2c_smbus_xfer) from [<00138b49>] 
(i2c_smbus_read_byte_data+0x1f/0x2a)
[    1.610000] [<00138b49>] (i2c_smbus_read_byte_data) from [<00124fdd>] 
(__stmpe_reg_read+0xd/0x24)
[    1.620000] [<00124fdd>] (__stmpe_reg_read) from [<001252b3>] 
(stmpe_reg_read+0x19/0x24)
[    1.630000] [<001252b3>] (stmpe_reg_read) from [<0002c4d1>] 
(unmask_irq+0x17/0x22)
[    1.640000] [<0002c4d1>] (unmask_irq) from [<0002c57f>] 
(irq_startup+0x6f/0x78)
[    1.650000] [<0002c57f>] (irq_startup) from [<0002b7a1>] 
(__setup_irq+0x319/0x47c)
[    1.650000] [<0002b7a1>] (__setup_irq) from [<0002bad3>] 
(request_threaded_irq+0x6b/0xe8)
[    1.660000] [<0002bad3>] (request_threaded_irq) from [<0002d0b9>] 
(devm_request_threaded_irq+0x3b/0x6a)
[    1.670000] [<0002d0b9>] (devm_request_threaded_irq) from [<001446e7>] 
(mmc_gpiod_request_cd_irq+0x49/0x8a)
[    1.680000] [<001446e7>] (mmc_gpiod_request_cd_irq) from [<0013d45d>] 
(mmc_start_host+0x49/0x60)
[    1.690000] [<0013d45d>] (mmc_start_host) from [<0013e40b>] 
(mmc_add_host+0x3b/0x54)
[    1.700000] [<0013e40b>] (mmc_add_host) from [<00148119>] 
(mmci_probe+0x4d1/0x60c)
[    1.710000] [<00148119>] (mmci_probe) from [<000f903b>] 
(amba_probe+0x7b/0xbe)
[    1.720000] [<000f903b>] (amba_probe) from [<001170e5>] 
(driver_probe_device+0x169/0x1f8)
[    1.730000] [<001170e5>] (driver_probe_device) from [<001171b7>] 
(__driver_attach+0x43/0x5c)
[    1.740000] [<001171b7>] (__driver_attach) from [<0011618d>] 
(bus_for_each_dev+0x3d/0x46)
[    1.740000] [<0011618d>] (bus_for_each_dev) from [<001165cd>] 
(bus_add_driver+0xcd/0x124)
[    1.740000] [<001165cd>] (bus_add_driver) from [<00117713>] 
(driver_register+0x4d/0x7a)
[    1.760000] [<00117713>] (driver_register) from [<001fc765>] 
(do_one_initcall+0xbd/0xe8)
[    1.770000] [<001fc765>] (do_one_initcall) from [<001fc88b>] 
(kernel_init_freeable+0xfb/0x134)
[    1.780000] [<001fc88b>] (kernel_init_freeable) from [<00167ee3>] 
(kernel_init+0x7/0x9c)
[    1.790000] [<00167ee3>] (kernel_init) from [<00009b65>] 
(ret_from_fork+0x11/0x2c)

Signed-off-by: Alexandre TORGUE <alexandre.tor...@st.com>
Signed-off-by: Patrice Chotard <patrice.chot...@st.com>
Signed-off-by: Linus Walleij <linus.wall...@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/gpio/gpio-stmpe.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -190,6 +190,16 @@ static void stmpe_gpio_irq_sync_unlock(s
        };
        int i, j;
 
+       /*
+        * STMPE1600: to be able to get IRQ from pins,
+        * a read must be done on GPMR register, or a write in
+        * GPSR or GPCR registers
+        */
+       if (stmpe->partnum == STMPE1600) {
+               stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]);
+               stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]);
+       }
+
        for (i = 0; i < CACHE_NR_REGS; i++) {
                /* STMPE801 and STMPE1600 don't have RE and FE registers */
                if ((stmpe->partnum == STMPE801 ||
@@ -227,21 +237,11 @@ static void stmpe_gpio_irq_unmask(struct
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc);
-       struct stmpe *stmpe = stmpe_gpio->stmpe;
        int offset = d->hwirq;
        int regoffset = offset / 8;
        int mask = BIT(offset % 8);
 
        stmpe_gpio->regs[REG_IE][regoffset] |= mask;
-
-       /*
-        * STMPE1600 workaround: to be able to get IRQ from pins,
-        * a read must be done on GPMR register, or a write in
-        * GPSR or GPCR registers
-        */
-       if (stmpe->partnum == STMPE1600)
-               stmpe_reg_read(stmpe,
-                              stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]);
 }
 
 static void stmpe_dbg_show_one(struct seq_file *s,


Reply via email to