summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-rockchip.c
diff options
context:
space:
mode:
authorJohn Keeping <john@metanate.com>2017-03-23 06:59:31 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-03-28 05:18:50 -0400
commit88bb94216f59e10802aaf78c858a4146085faf18 (patch)
treed096b789e02460b33c2e9f20334ad008a8262fd0 /drivers/pinctrl/pinctrl-rockchip.c
parent05709c3e88f5f0adb7889facbfd546c998f65d59 (diff)
pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip
With real-time preemption, regmap functions cannot be used in the implementation of irq_chip since they use spinlocks which may sleep. Move the setting of the mux for IRQs to an irq_bus_sync_unlock handler where we are allowed to sleep. Signed-off-by: John Keeping <john@metanate.com> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 9dd981ddbb17..f141aa0430b1 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -143,6 +143,9 @@ struct rockchip_drv {
143 * @gpio_chip: gpiolib chip 143 * @gpio_chip: gpiolib chip
144 * @grange: gpio range 144 * @grange: gpio range
145 * @slock: spinlock for the gpio bank 145 * @slock: spinlock for the gpio bank
146 * @irq_lock: bus lock for irq chip
147 * @new_irqs: newly configured irqs which must be muxed as GPIOs in
148 * irq_bus_sync_unlock()
146 */ 149 */
147struct rockchip_pin_bank { 150struct rockchip_pin_bank {
148 void __iomem *reg_base; 151 void __iomem *reg_base;
@@ -165,6 +168,8 @@ struct rockchip_pin_bank {
165 struct pinctrl_gpio_range grange; 168 struct pinctrl_gpio_range grange;
166 raw_spinlock_t slock; 169 raw_spinlock_t slock;
167 u32 toggle_edge_mode; 170 u32 toggle_edge_mode;
171 struct mutex irq_lock;
172 u32 new_irqs;
168}; 173};
169 174
170#define PIN_BANK(id, pins, label) \ 175#define PIN_BANK(id, pins, label) \
@@ -2129,11 +2134,12 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
2129 int ret; 2134 int ret;
2130 2135
2131 /* make sure the pin is configured as gpio input */ 2136 /* make sure the pin is configured as gpio input */
2132 ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); 2137 ret = rockchip_verify_mux(bank, d->hwirq, RK_FUNC_GPIO);
2133 if (ret < 0) 2138 if (ret < 0)
2134 return ret; 2139 return ret;
2135 2140
2136 clk_enable(bank->clk); 2141 bank->new_irqs |= mask;
2142
2137 raw_spin_lock_irqsave(&bank->slock, flags); 2143 raw_spin_lock_irqsave(&bank->slock, flags);
2138 2144
2139 data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); 2145 data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -2191,7 +2197,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
2191 default: 2197 default:
2192 irq_gc_unlock(gc); 2198 irq_gc_unlock(gc);
2193 raw_spin_unlock_irqrestore(&bank->slock, flags); 2199 raw_spin_unlock_irqrestore(&bank->slock, flags);
2194 clk_disable(bank->clk);
2195 return -EINVAL; 2200 return -EINVAL;
2196 } 2201 }
2197 2202
@@ -2200,7 +2205,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
2200 2205
2201 irq_gc_unlock(gc); 2206 irq_gc_unlock(gc);
2202 raw_spin_unlock_irqrestore(&bank->slock, flags); 2207 raw_spin_unlock_irqrestore(&bank->slock, flags);
2203 clk_disable(bank->clk);
2204 2208
2205 return 0; 2209 return 0;
2206} 2210}
@@ -2244,6 +2248,34 @@ static void rockchip_irq_disable(struct irq_data *d)
2244 clk_disable(bank->clk); 2248 clk_disable(bank->clk);
2245} 2249}
2246 2250
2251static void rockchip_irq_bus_lock(struct irq_data *d)
2252{
2253 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
2254 struct rockchip_pin_bank *bank = gc->private;
2255
2256 clk_enable(bank->clk);
2257 mutex_lock(&bank->irq_lock);
2258}
2259
2260static void rockchip_irq_bus_sync_unlock(struct irq_data *d)
2261{
2262 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
2263 struct rockchip_pin_bank *bank = gc->private;
2264
2265 while (bank->new_irqs) {
2266 unsigned int irq = __ffs(bank->new_irqs);
2267 int ret;
2268
2269 ret = rockchip_set_mux(bank, irq, RK_FUNC_GPIO);
2270 WARN_ON(ret < 0);
2271
2272 bank->new_irqs &= ~BIT(irq);
2273 }
2274
2275 mutex_unlock(&bank->irq_lock);
2276 clk_disable(bank->clk);
2277}
2278
2247static int rockchip_interrupts_register(struct platform_device *pdev, 2279static int rockchip_interrupts_register(struct platform_device *pdev,
2248 struct rockchip_pinctrl *info) 2280 struct rockchip_pinctrl *info)
2249{ 2281{
@@ -2310,6 +2342,9 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
2310 gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; 2342 gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
2311 gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; 2343 gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
2312 gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; 2344 gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
2345 gc->chip_types[0].chip.irq_bus_lock = rockchip_irq_bus_lock;
2346 gc->chip_types[0].chip.irq_bus_sync_unlock =
2347 rockchip_irq_bus_sync_unlock;
2313 gc->wake_enabled = IRQ_MSK(bank->nr_pins); 2348 gc->wake_enabled = IRQ_MSK(bank->nr_pins);
2314 2349
2315 irq_set_chained_handler_and_data(bank->irq, 2350 irq_set_chained_handler_and_data(bank->irq,
@@ -2483,6 +2518,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
2483 int bank_pins = 0; 2518 int bank_pins = 0;
2484 2519
2485 raw_spin_lock_init(&bank->slock); 2520 raw_spin_lock_init(&bank->slock);
2521 mutex_init(&bank->irq_lock);
2486 bank->drvdata = d; 2522 bank->drvdata = d;
2487 bank->pin_base = ctrl->nr_pins; 2523 bank->pin_base = ctrl->nr_pins;
2488 ctrl->nr_pins += bank->nr_pins; 2524 ctrl->nr_pins += bank->nr_pins;