Revert "UPSTREAM: pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip"
authorHuang, Tao <huangtao@rock-chips.com>
Tue, 6 Jun 2017 12:52:45 +0000 (20:52 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 6 Jun 2017 12:52:45 +0000 (20:52 +0800)
This reverts commit a8b4e18cf1e98ed3b36175cb4e3ef422c03ac01c.

Which will cause such error:

BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620
in_atomic(): 1, irqs_disabled(): 128, pid: 141, name: irq/95-fusb302
1 lock held by irq/95-fusb302/141:
 #0:  (&(&chip->irq_lock)->rlock){......}, at: [<ffffff800859e3a0>] fusb_irq_disable+0x20/0x68
irq event stamp: 52
hardirqs last  enabled at (51): [<ffffff80080bcc30>] queue_work_on+0x68/0x80
hardirqs last disabled at (52): [<ffffff8008c6f41c>] _raw_spin_lock_irqsave+0x20/0x60
softirqs last  enabled at (0): [<ffffff800809e9ec>] copy_process.isra.54+0x390/0x1728
softirqs last disabled at (0): [<          (null)>]           (null)
Preemption disabled at:[<ffffff800859e3a0>] fusb_irq_disable+0x20/0x68

CPU: 5 PID: 141 Comm: irq/95-fusb302 Not tainted 4.4.70 #30
Hardware name: Rockchip RK3399 Evaluation Board v3 (Android) (DT)
Call trace:
[<ffffff800808a82c>] dump_backtrace+0x0/0x1c4
[<ffffff800808aa04>] show_stack+0x14/0x1c
[<ffffff80083c3b90>] dump_stack+0xa8/0xe0
[<ffffff80080cf560>] ___might_sleep+0x214/0x224
[<ffffff80080cf5e4>] __might_sleep+0x74/0x84
[<ffffff8008c6c1ac>] mutex_lock_nested+0x48/0x3cc
[<ffffff80083fe2b0>] rockchip_irq_bus_lock+0x28/0x34
[<ffffff800810b680>] __irq_get_desc_lock+0x68/0x88
[<ffffff800810d558>] __disable_irq_nosync+0x28/0x70
[<ffffff800810d5ac>] disable_irq_nosync+0xc/0x14
[<ffffff800859e3b4>] fusb_irq_disable+0x34/0x68
[<ffffff800859e410>] cc_interrupt_handler+0x28/0x38
[<ffffff800810cd48>] irq_thread_fn+0x28/0x68
[<ffffff800810cf80>] irq_thread+0x130/0x234
[<ffffff80080c58e8>] kthread+0x104/0x10c
[<ffffff8008083080>] ret_from_fork+0x10/0x50

or

BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620
in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/0
INFO: lockdep is turned off.
irq event stamp: 111558
hardirqs last  enabled at (111557): [<ffffff8008116cdc>] rcu_idle_exit+0x70/0x80
hardirqs last disabled at (111558): [<ffffff80080f1078>] cpu_startup_entry+0xc0/0x42c
softirqs last  enabled at (111554): [<ffffff80080a6794>] _local_bh_enable+0x3c/0x44
softirqs last disabled at (111553): [<ffffff80080a7000>] irq_enter+0x28/0x64
Preemption disabled at:[<ffffff80080f1308>] cpu_startup_entry+0x350/0x42c

CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.70 #30
Hardware name: Rockchip RK3399 Evaluation Board v3 (Android) (DT)
Call trace:
[<ffffff800808a82c>] dump_backtrace+0x0/0x1c4
[<ffffff800808aa04>] show_stack+0x14/0x1c
[<ffffff80083c3b90>] dump_stack+0xa8/0xe0
[<ffffff80080cf560>] ___might_sleep+0x214/0x224
[<ffffff80080cf5e4>] __might_sleep+0x74/0x84
[<ffffff8008c6c1ac>] mutex_lock_nested+0x48/0x3cc
[<ffffff80083fe2b0>] rockchip_irq_bus_lock+0x28/0x34
[<ffffff800810b680>] __irq_get_desc_lock+0x68/0x88
[<ffffff800810d558>] __disable_irq_nosync+0x28/0x70
[<ffffff800810d5ac>] disable_irq_nosync+0xc/0x14
[<ffffff8008621f20>] bcmsdh_oob_intr_set+0x4c/0x6c
[<ffffff8008621f5c>] wlan_oob_irq+0x1c/0x38
[<ffffff800810bd28>] handle_irq_event_percpu+0x150/0x3e8
[<ffffff800810c004>] handle_irq_event+0x44/0x74
[<ffffff800810f53c>] handle_level_irq+0xe4/0x11c
[<ffffff800810b228>] generic_handle_irq+0x1c/0x2c
[<ffffff80083fe068>] rockchip_irq_demux+0xe0/0x188
[<ffffff800810b228>] generic_handle_irq+0x1c/0x2c
[<ffffff800810b5b0>] __handle_domain_irq+0xb0/0xec
[<ffffff8008080f70>] gic_handle_irq+0xbc/0x154

Change-Id: I7cfbeaf7df17fc4e923e89917199b7f1c773455a
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
drivers/pinctrl/pinctrl-rockchip.c

index 16bd40e144c5a54c29b4547861c8924ebe839f5d..b22ad41bac77cffc0576324ba5d51ce77829bd40 100644 (file)
@@ -154,9 +154,6 @@ struct rockchip_drv {
  * @gpio_chip: gpiolib chip
  * @grange: gpio range
  * @slock: spinlock for the gpio bank
- * @irq_lock: bus lock for irq chip
- * @new_irqs: newly configured irqs which must be muxed as GPIOs in
- *     irq_bus_sync_unlock()
  * @route_mask: bits describing the routing pins of per bank
  */
 struct rockchip_pin_bank {
@@ -180,8 +177,6 @@ struct rockchip_pin_bank {
        struct pinctrl_gpio_range       grange;
        raw_spinlock_t                  slock;
        u32                             toggle_edge_mode;
-       struct mutex                    irq_lock;
-       u32                             new_irqs;
        u32                             route_mask;
 };
 
@@ -2698,12 +2693,11 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        int ret;
 
        /* make sure the pin is configured as gpio input */
-       ret = rockchip_verify_mux(bank, d->hwirq, RK_FUNC_GPIO);
+       ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
        if (ret < 0)
                return ret;
 
-       bank->new_irqs |= mask;
-
+       clk_enable(bank->clk);
        raw_spin_lock_irqsave(&bank->slock, flags);
 
        data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -2761,6 +2755,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        default:
                irq_gc_unlock(gc);
                raw_spin_unlock_irqrestore(&bank->slock, flags);
+               clk_disable(bank->clk);
                return -EINVAL;
        }
 
@@ -2769,6 +2764,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
 
        irq_gc_unlock(gc);
        raw_spin_unlock_irqrestore(&bank->slock, flags);
+       clk_disable(bank->clk);
 
        return 0;
 }
@@ -2812,34 +2808,6 @@ void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
        clk_disable(bank->clk);
 }
 
-static void rockchip_irq_bus_lock(struct irq_data *d)
-{
-       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-       struct rockchip_pin_bank *bank = gc->private;
-
-       clk_enable(bank->clk);
-       mutex_lock(&bank->irq_lock);
-}
-
-static void rockchip_irq_bus_sync_unlock(struct irq_data *d)
-{
-       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-       struct rockchip_pin_bank *bank = gc->private;
-
-       while (bank->new_irqs) {
-               unsigned int irq = __ffs(bank->new_irqs);
-               int ret;
-
-               ret = rockchip_set_mux(bank, irq, RK_FUNC_GPIO);
-               WARN_ON(ret < 0);
-
-               bank->new_irqs &= ~BIT(irq);
-       }
-
-       mutex_unlock(&bank->irq_lock);
-       clk_disable(bank->clk);
-}
-
 static int rockchip_interrupts_register(struct platform_device *pdev,
                                                struct rockchip_pinctrl *info)
 {
@@ -2905,9 +2873,6 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
                gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
                gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
                gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
-               gc->chip_types[0].chip.irq_bus_lock = rockchip_irq_bus_lock;
-               gc->chip_types[0].chip.irq_bus_sync_unlock =
-                                               rockchip_irq_bus_sync_unlock;
                gc->wake_enabled = IRQ_MSK(bank->nr_pins);
 
                irq_set_chained_handler_and_data(bank->irq,
@@ -3081,7 +3046,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
                int bank_pins = 0;
 
                raw_spin_lock_init(&bank->slock);
-               mutex_init(&bank->irq_lock);
                bank->drvdata = d;
                bank->pin_base = ctrl->nr_pins;
                ctrl->nr_pins += bank->nr_pins;