Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1601611 > unrolled thread
| Started by | John Keeping <john@metanate.com> |
|---|---|
| First post | 2017-03-15 19:10 +0100 |
| Last post | 2017-03-15 19:20 +0100 |
| Articles | 7 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes John Keeping <john@metanate.com> - 2017-03-15 19:10 +0100
[PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip John Keeping <john@metanate.com> - 2017-03-15 19:20 +0100
[PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking John Keeping <john@metanate.com> - 2017-03-15 19:20 +0100
[PATCH v2.1 1/4] pinctrl: rockchip: remove unnecessary locking John Keeping <john@metanate.com> - 2017-03-15 20:00 +0100
Re: [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking Linus Walleij <linus.walleij@linaro.org> - 2017-03-23 10:10 +0100
[PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock John Keeping <john@metanate.com> - 2017-03-15 19:20 +0100
[PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings John Keeping <john@metanate.com> - 2017-03-15 19:20 +0100
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 19:10 +0100 |
| Subject | [PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes |
| Message-ID | <tllx0-2TA-11@gated-at.bofh.it> |
This is an updated version of [1] rebased on top of pinctrl/for-next. The only change is in patch 1 to remove locking in the new rockchip_set_schmitt() function. The aim of the series is to make the Rockchip pinctrl irq_chip implementation safe for use with RT_FULL which requires that raw spinlocks are used to avoid sleeping in hardirq context. [1] https://www.spinics.net/lists/arm-kernel/msg568279.html John Keeping (4): pinctrl: rockchip: remove unnecessary locking pinctrl: rockchip: convert to raw spinlock pinctrl: rockchip: split out verification of mux settings pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip drivers/pinctrl/pinctrl-rockchip.c | 148 ++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 61 deletions(-) -- 2.12.0.377.gf910686b23.dirty
[toc] | [next] | [standalone]
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 19:20 +0100 |
| Subject | [PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip |
| Message-ID | <tllGF-2YN-1@gated-at.bofh.it> |
| In reply to | #1601611 |
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>
---
v2: unchanged
---
drivers/pinctrl/pinctrl-rockchip.c | 44 ++++++++++++++++++++++++++++++++++----
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 426f5ea57b16..5796b3c7cdd8 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -143,6 +143,9 @@ 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()
*/
struct rockchip_pin_bank {
void __iomem *reg_base;
@@ -165,6 +168,8 @@ struct rockchip_pin_bank {
struct pinctrl_gpio_range grange;
raw_spinlock_t slock;
u32 toggle_edge_mode;
+ struct mutex irq_lock;
+ u32 new_irqs;
};
#define PIN_BANK(id, pins, label) \
@@ -2134,11 +2139,12 @@ 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_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+ ret = rockchip_verify_mux(bank, d->hwirq, RK_FUNC_GPIO);
if (ret < 0)
return ret;
- clk_enable(bank->clk);
+ bank->new_irqs |= mask;
+
raw_spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -2196,7 +2202,6 @@ 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;
}
@@ -2205,7 +2210,6 @@ 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;
}
@@ -2249,6 +2253,34 @@ static 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)
{
@@ -2314,6 +2346,9 @@ 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,
@@ -2487,6 +2522,7 @@ 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;
--
2.12.0.377.gf910686b23.dirty
[toc] | [prev] | [next] | [standalone]
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 19:20 +0100 |
| Subject | [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking |
| Message-ID | <tllGF-2YN-5@gated-at.bofh.it> |
| In reply to | #1601611 |
regmap_update_bits does its own locking and everything else accessed
here is a local variable so there is no need to lock around it.
Signed-off-by: John Keeping <john@metanate.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
v2:
- Also remove locking in rockchip_set_schmitt()
---
drivers/pinctrl/pinctrl-rockchip.c | 28 ++--------------------------
1 file changed, 2 insertions(+), 26 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 1e276dfe1763..128c383ea7ba 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -652,7 +652,6 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
int iomux_num = (pin / 8);
struct regmap *regmap;
int reg, ret, mask, mux_type;
- unsigned long flags;
u8 bit;
u32 data, rmask;
@@ -701,15 +700,11 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, ®, &bit, &mask);
- spin_lock_irqsave(&bank->slock, flags);
-
data = (mask << (bit + 16));
rmask = data | (data >> 16);
data |= (mux & mask) << bit;
ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
-
return ret;
}
@@ -1135,7 +1130,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
- unsigned long flags;
int reg, ret, i;
u32 data, rmask, rmask_bits, temp;
u8 bit;
@@ -1163,8 +1157,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
return ret;
}
- spin_lock_irqsave(&bank->slock, flags);
-
switch (drv_type) {
case DRV_TYPE_IO_1V8_3V0_AUTO:
case DRV_TYPE_IO_3V3_ONLY:
@@ -1185,17 +1177,14 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask = BIT(15) | BIT(31);
data |= BIT(31);
ret = regmap_update_bits(regmap, reg, rmask, data);
- if (ret) {
- spin_unlock_irqrestore(&bank->slock, flags);
+ if (ret)
return ret;
- }
rmask = 0x3 | (0x3 << 16);
temp |= (0x3 << 16);
reg += 0x4;
ret = regmap_update_bits(regmap, reg, rmask, temp);
- spin_unlock_irqrestore(&bank->slock, flags);
return ret;
case 18 ... 21:
/* setting fully enclosed in the second register */
@@ -1203,7 +1192,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
bit -= 16;
break;
default:
- spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n",
bit, drv_type);
return -EINVAL;
@@ -1215,7 +1203,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask_bits = RK3288_DRV_BITS_PER_PIN;
break;
default:
- spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
drv_type);
return -EINVAL;
@@ -1227,7 +1214,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
return ret;
}
@@ -1339,16 +1325,12 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
return ret;
}
- spin_lock_irqsave(&bank->slock, flags);
-
/* enable the write to the equivalent lower bits */
data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
rmask = data | (data >> 16);
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
-
- spin_unlock_irqrestore(&bank->slock, flags);
break;
default:
dev_err(info->dev, "unsupported pinctrl type\n");
@@ -1408,7 +1390,6 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret;
- unsigned long flags;
u8 bit;
u32 data, rmask;
@@ -1419,16 +1400,11 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
if (ret)
return ret;
- spin_lock_irqsave(&bank->slock, flags);
-
/* enable the write to the equivalent lower bits */
data = BIT(bit + 16) | (enable << bit);
rmask = BIT(bit + 16) | BIT(bit);
- ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
-
- return ret;
+ return regmap_update_bits(regmap, reg, rmask, data);
}
/*
--
2.12.0.377.gf910686b23.dirty
[toc] | [prev] | [next] | [standalone]
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 20:00 +0100 |
| Subject | [PATCH v2.1 1/4] pinctrl: rockchip: remove unnecessary locking |
| Message-ID | <tlmjo-3g1-17@gated-at.bofh.it> |
| In reply to | #1601616 |
regmap_update_bits does its own locking and everything else accessed
here is a local variable so there is no need to lock around it.
Signed-off-by: John Keeping <john@metanate.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
v2.1:
- Remove RK2928 locking in rockchip_set_pull()
v2:
- Also remove locking in rockchip_set_schmitt()
---
drivers/pinctrl/pinctrl-rockchip.c | 33 ++-------------------------------
1 file changed, 2 insertions(+), 31 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 1e276dfe1763..1d835370c2c7 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -652,7 +652,6 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
int iomux_num = (pin / 8);
struct regmap *regmap;
int reg, ret, mask, mux_type;
- unsigned long flags;
u8 bit;
u32 data, rmask;
@@ -701,15 +700,11 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, ®, &bit, &mask);
- spin_lock_irqsave(&bank->slock, flags);
-
data = (mask << (bit + 16));
rmask = data | (data >> 16);
data |= (mux & mask) << bit;
ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
-
return ret;
}
@@ -1135,7 +1130,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata;
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
- unsigned long flags;
int reg, ret, i;
u32 data, rmask, rmask_bits, temp;
u8 bit;
@@ -1163,8 +1157,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
return ret;
}
- spin_lock_irqsave(&bank->slock, flags);
-
switch (drv_type) {
case DRV_TYPE_IO_1V8_3V0_AUTO:
case DRV_TYPE_IO_3V3_ONLY:
@@ -1185,17 +1177,14 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask = BIT(15) | BIT(31);
data |= BIT(31);
ret = regmap_update_bits(regmap, reg, rmask, data);
- if (ret) {
- spin_unlock_irqrestore(&bank->slock, flags);
+ if (ret)
return ret;
- }
rmask = 0x3 | (0x3 << 16);
temp |= (0x3 << 16);
reg += 0x4;
ret = regmap_update_bits(regmap, reg, rmask, temp);
- spin_unlock_irqrestore(&bank->slock, flags);
return ret;
case 18 ... 21:
/* setting fully enclosed in the second register */
@@ -1203,7 +1192,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
bit -= 16;
break;
default:
- spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n",
bit, drv_type);
return -EINVAL;
@@ -1215,7 +1203,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
rmask_bits = RK3288_DRV_BITS_PER_PIN;
break;
default:
- spin_unlock_irqrestore(&bank->slock, flags);
dev_err(info->dev, "unsupported pinctrl drive type: %d\n",
drv_type);
return -EINVAL;
@@ -1227,7 +1214,6 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
return ret;
}
@@ -1294,7 +1280,6 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret, i, pull_type;
- unsigned long flags;
u8 bit;
u32 data, rmask;
@@ -1309,14 +1294,10 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
switch (ctrl->type) {
case RK2928:
- spin_lock_irqsave(&bank->slock, flags);
-
data = BIT(bit + 16);
if (pull == PIN_CONFIG_BIAS_DISABLE)
data |= BIT(bit);
ret = regmap_write(regmap, reg, data);
-
- spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK1108:
case RK3188:
@@ -1339,16 +1320,12 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
return ret;
}
- spin_lock_irqsave(&bank->slock, flags);
-
/* enable the write to the equivalent lower bits */
data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
rmask = data | (data >> 16);
data |= (ret << bit);
ret = regmap_update_bits(regmap, reg, rmask, data);
-
- spin_unlock_irqrestore(&bank->slock, flags);
break;
default:
dev_err(info->dev, "unsupported pinctrl type\n");
@@ -1408,7 +1385,6 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct regmap *regmap;
int reg, ret;
- unsigned long flags;
u8 bit;
u32 data, rmask;
@@ -1419,16 +1395,11 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
if (ret)
return ret;
- spin_lock_irqsave(&bank->slock, flags);
-
/* enable the write to the equivalent lower bits */
data = BIT(bit + 16) | (enable << bit);
rmask = BIT(bit + 16) | BIT(bit);
- ret = regmap_update_bits(regmap, reg, rmask, data);
- spin_unlock_irqrestore(&bank->slock, flags);
-
- return ret;
+ return regmap_update_bits(regmap, reg, rmask, data);
}
/*
--
2.12.0.377.gf910686b23.dirty
[toc] | [prev] | [next] | [standalone]
| From | Linus Walleij <linus.walleij@linaro.org> |
|---|---|
| Date | 2017-03-23 10:10 +0100 |
| Subject | Re: [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking |
| Message-ID | <to6UN-89-1@gated-at.bofh.it> |
| In reply to | #1601616 |
On Wed, Mar 15, 2017 at 6:46 PM, John Keeping <john@metanate.com> wrote: > regmap_update_bits does its own locking and everything else accessed > here is a local variable so there is no need to lock around it. > > Signed-off-by: John Keeping <john@metanate.com> > Reviewed-by: Heiko Stuebner <heiko@sntech.de> > Tested-by: Heiko Stuebner <heiko@sntech.de> > --- > v2: > - Also remove locking in rockchip_set_schmitt() This does not apply on my "devel" branch in the pinctrl tree. Please rebase on that and resend. Since I have no patches for rockchip so far I suspect this is not even based on v4.11-rc1 so pls forward-port. Yours, Linus Walleij
[toc] | [prev] | [next] | [standalone]
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 19:20 +0100 |
| Subject | [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock |
| Message-ID | <tllx0-2TA-13@gated-at.bofh.it> |
| In reply to | #1601611 |
This lock is used from rockchip_irq_set_type() which is part of the
irq_chip implementation and thus must use raw_spinlock_t as documented
in Documentation/gpio/driver.txt.
Signed-off-by: John Keeping <john@metanate.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
v2: unchanged
---
drivers/pinctrl/pinctrl-rockchip.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 128c383ea7ba..8c1cae6d78d7 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -163,7 +163,7 @@ struct rockchip_pin_bank {
struct irq_domain *domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
- spinlock_t slock;
+ raw_spinlock_t slock;
u32 toggle_edge_mode;
};
@@ -1295,14 +1295,14 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
switch (ctrl->type) {
case RK2928:
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
data = BIT(bit + 16);
if (pull == PIN_CONFIG_BIAS_DISABLE)
data |= BIT(bit);
ret = regmap_write(regmap, reg, data);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK1108:
case RK3188:
@@ -1503,7 +1503,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
return ret;
clk_enable(bank->clk);
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */
@@ -1513,7 +1513,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
data &= ~BIT(pin);
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
return 0;
@@ -1963,7 +1963,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
u32 data;
clk_enable(bank->clk);
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
data = readl(reg);
data &= ~BIT(offset);
@@ -1971,7 +1971,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
data |= BIT(offset);
writel(data, reg);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
}
@@ -2083,7 +2083,7 @@ static void rockchip_irq_demux(struct irq_desc *desc)
data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
do {
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
polarity = readl_relaxed(bank->reg_base +
GPIO_INT_POLARITY);
@@ -2094,7 +2094,7 @@ static void rockchip_irq_demux(struct irq_desc *desc)
writel(polarity,
bank->reg_base + GPIO_INT_POLARITY);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
data_old = data;
data = readl_relaxed(bank->reg_base +
@@ -2125,20 +2125,20 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
return ret;
clk_enable(bank->clk);
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
if (type & IRQ_TYPE_EDGE_BOTH)
irq_set_handler_locked(d, handle_edge_irq);
else
irq_set_handler_locked(d, handle_level_irq);
- spin_lock_irqsave(&bank->slock, flags);
+ raw_spin_lock_irqsave(&bank->slock, flags);
irq_gc_lock(gc);
level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
@@ -2181,7 +2181,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
break;
default:
irq_gc_unlock(gc);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
return -EINVAL;
}
@@ -2190,7 +2190,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
irq_gc_unlock(gc);
- spin_unlock_irqrestore(&bank->slock, flags);
+ raw_spin_unlock_irqrestore(&bank->slock, flags);
clk_disable(bank->clk);
return 0;
@@ -2472,7 +2472,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
int bank_pins = 0;
- spin_lock_init(&bank->slock);
+ raw_spin_lock_init(&bank->slock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
--
2.12.0.377.gf910686b23.dirty
[toc] | [prev] | [next] | [standalone]
| From | John Keeping <john@metanate.com> |
|---|---|
| Date | 2017-03-15 19:20 +0100 |
| Subject | [PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings |
| Message-ID | <tllGG-2YN-15@gated-at.bofh.it> |
| In reply to | #1601611 |
We need to avoid calling regmap functions from irq handlers, so the next
commit is going to move the call to rockchip_set_mux() into an
irq_bus_sync_unlock handler. But we can't return an error from there so
we still need to check the settings from rockchip_irq_set_type() and we
will use this new rockchip_verify_mux() function from there.
Signed-off-by: John Keeping <john@metanate.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Tested-by: Heiko Stuebner <heiko@sntech.de>
---
v2: unchanged
---
drivers/pinctrl/pinctrl-rockchip.c | 46 +++++++++++++++++++++++++-------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 8c1cae6d78d7..426f5ea57b16 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -632,6 +632,31 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
return ((val >> bit) & mask);
}
+static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
+ int pin, int mux)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+ int iomux_num = (pin / 8);
+
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+ dev_err(info->dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
+ if (mux != RK_FUNC_GPIO) {
+ dev_err(info->dev,
+ "pin %d only supports a gpio mux\n", pin);
+ return -ENOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
/*
* Set a new mux function for a pin.
*
@@ -655,23 +680,12 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
u8 bit;
u32 data, rmask;
- if (iomux_num > 3)
- return -EINVAL;
-
- if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
- dev_err(info->dev, "pin %d is unrouted\n", pin);
- return -EINVAL;
- }
+ ret = rockchip_verify_mux(bank, pin, mux);
+ if (ret < 0)
+ return ret;
- if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
- if (mux != RK_FUNC_GPIO) {
- dev_err(info->dev,
- "pin %d only supports a gpio mux\n", pin);
- return -ENOTSUPP;
- } else {
- return 0;
- }
- }
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
+ return 0;
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
--
2.12.0.377.gf910686b23.dirty
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web