All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes
@ 2017-03-15 17:46 ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-gpio, Linus Walleij, Julia Cartwright, linux-kernel,
	linux-rockchip, John Keeping, linux-arm-kernel

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes
@ 2017-03-15 17:46 ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel, John Keeping

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes
@ 2017-03-15 17:46 ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
  2017-03-15 17:46 ` John Keeping
  (?)
@ 2017-03-15 17:46   ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-gpio, Linus Walleij, Julia Cartwright, linux-kernel,
	linux-rockchip, John Keeping, linux-arm-kernel

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, &reg, &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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel, John Keeping

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, &reg, &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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

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, &reg, &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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 17:46 ` John Keeping
  (?)
@ 2017-03-15 17:46   ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-gpio, Linus Walleij, Julia Cartwright, linux-kernel,
	linux-rockchip, John Keeping, linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel, John Keeping

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings
  2017-03-15 17:46 ` John Keeping
  (?)
@ 2017-03-15 17:46   ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-gpio, Linus Walleij, Julia Cartwright, linux-kernel,
	linux-rockchip, John Keeping, linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel, John Keeping

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip
  2017-03-15 17:46 ` John Keeping
  (?)
@ 2017-03-15 17:46   ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-gpio, Linus Walleij, Julia Cartwright, linux-kernel,
	linux-rockchip, John Keeping, linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel, John Keeping

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip
@ 2017-03-15 17:46   ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 17:46 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 17:46   ` John Keeping
  (?)
@ 2017-03-15 18:01     ` Julia Cartwright
  -1 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:01 UTC (permalink / raw)
  To: John Keeping
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]

Hello John-

On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> 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);

This should be lifted out from under the lock.

>  		ret = regmap_write(regmap, reg, data);

How is this legal?  The regmap_write() here is going to end up acquiring
the regmap mutex.

   Julia

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:01     ` Julia Cartwright
  0 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:01 UTC (permalink / raw)
  To: John Keeping
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]

Hello John-

On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> 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);

This should be lifted out from under the lock.

>  		ret = regmap_write(regmap, reg, data);

How is this legal?  The regmap_write() here is going to end up acquiring
the regmap mutex.

   Julia

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:01     ` Julia Cartwright
  0 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hello John-

On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> 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);

This should be lifted out from under the lock.

>  		ret = regmap_write(regmap, reg, data);

How is this legal?  The regmap_write() here is going to end up acquiring
the regmap mutex.

   Julia
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170315/e870348b/attachment.sig>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 18:01     ` Julia Cartwright
  (?)
@ 2017-03-15 18:08       ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:08 UTC (permalink / raw)
  To: Julia Cartwright
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > 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);  
> 
> This should be lifted out from under the lock.
> 
> >  		ret = regmap_write(regmap, reg, data);  
> 
> How is this legal?  The regmap_write() here is going to end up acquiring
> the regmap mutex.

It's not, the spinlock can be deleted here.  I only have RK3288 hardware
to test and I missed this when checking the uses of slock.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:08       ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:08 UTC (permalink / raw)
  To: Julia Cartwright
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > 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);  
> 
> This should be lifted out from under the lock.
> 
> >  		ret = regmap_write(regmap, reg, data);  
> 
> How is this legal?  The regmap_write() here is going to end up acquiring
> the regmap mutex.

It's not, the spinlock can be deleted here.  I only have RK3288 hardware
to test and I missed this when checking the uses of slock.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:08       ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > 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);  
> 
> This should be lifted out from under the lock.
> 
> >  		ret = regmap_write(regmap, reg, data);  
> 
> How is this legal?  The regmap_write() here is going to end up acquiring
> the regmap mutex.

It's not, the spinlock can be deleted here.  I only have RK3288 hardware
to test and I missed this when checking the uses of slock.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 18:08       ` John Keeping
@ 2017-03-15 18:16         ` Heiko Stuebner
  -1 siblings, 0 replies; 34+ messages in thread
From: Heiko Stuebner @ 2017-03-15 18:16 UTC (permalink / raw)
  To: John Keeping
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

Am Mittwoch, 15. März 2017, 18:08:06 CET schrieb John Keeping:
> On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > > 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);
> > 
> > This should be lifted out from under the lock.
> > 
> > >  		ret = regmap_write(regmap, reg, data);
> > 
> > How is this legal?  The regmap_write() here is going to end up acquiring
> > the regmap mutex.
> 
> It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> to test and I missed this when checking the uses of slock.

That part could very well also use regmap_update_bits like the other parts.
Not really sure, why we use regmap_write here, but I'm also not sure, if it 
matters at all.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:16         ` Heiko Stuebner
  0 siblings, 0 replies; 34+ messages in thread
From: Heiko Stuebner @ 2017-03-15 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

Am Mittwoch, 15. M?rz 2017, 18:08:06 CET schrieb John Keeping:
> On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > > 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);
> > 
> > This should be lifted out from under the lock.
> > 
> > >  		ret = regmap_write(regmap, reg, data);
> > 
> > How is this legal?  The regmap_write() here is going to end up acquiring
> > the regmap mutex.
> 
> It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> to test and I missed this when checking the uses of slock.

That part could very well also use regmap_update_bits like the other parts.
Not really sure, why we use regmap_write here, but I'm also not sure, if it 
matters at all.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 18:16         ` Heiko Stuebner
  (?)
@ 2017-03-15 18:23           ` Julia Cartwright
  -1 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:23 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linux-rockchip, Linus Walleij, linux-kernel, linux-gpio,
	John Keeping, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2463 bytes --]

On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> Am Mittwoch, 15. März 2017, 18:08:06 CET schrieb John Keeping:
> > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > > > 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
[..]
> > > > @@ -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);
> > > 
> > > This should be lifted out from under the lock.
> > > 
> > > >  		ret = regmap_write(regmap, reg, data);
> > > 
> > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > the regmap mutex.
> > 
> > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > to test and I missed this when checking the uses of slock.
> 
> That part could very well also use regmap_update_bits like the other parts.
> Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> matters at all.

regmap_update_bits also acquires the regmap lock, which would similarly
be a problem here.[1]

But, if we could pull this entire operation out of the lock (and
convince ourselves that it's okay to do so), then even better!

   Julia

1: Why is this a problem?  Because we're in the middle of a
   raw_spinlock_t protected critical region: if there were contention on
   the nested mutex (the "regmap mutex"), then we'd attempt to sleep in
   atomic context.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:23           ` Julia Cartwright
  0 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:23 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: John Keeping, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2463 bytes --]

On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> Am Mittwoch, 15. März 2017, 18:08:06 CET schrieb John Keeping:
> > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > > > 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
[..]
> > > > @@ -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);
> > > 
> > > This should be lifted out from under the lock.
> > > 
> > > >  		ret = regmap_write(regmap, reg, data);
> > > 
> > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > the regmap mutex.
> > 
> > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > to test and I missed this when checking the uses of slock.
> 
> That part could very well also use regmap_update_bits like the other parts.
> Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> matters at all.

regmap_update_bits also acquires the regmap lock, which would similarly
be a problem here.[1]

But, if we could pull this entire operation out of the lock (and
convince ourselves that it's okay to do so), then even better!

   Julia

1: Why is this a problem?  Because we're in the middle of a
   raw_spinlock_t protected critical region: if there were contention on
   the nested mutex (the "regmap mutex"), then we'd attempt to sleep in
   atomic context.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:23           ` Julia Cartwright
  0 siblings, 0 replies; 34+ messages in thread
From: Julia Cartwright @ 2017-03-15 18:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> Am Mittwoch, 15. M?rz 2017, 18:08:06 CET schrieb John Keeping:
> > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:
> > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:
> > > > 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
[..]
> > > > @@ -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);
> > > 
> > > This should be lifted out from under the lock.
> > > 
> > > >  		ret = regmap_write(regmap, reg, data);
> > > 
> > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > the regmap mutex.
> > 
> > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > to test and I missed this when checking the uses of slock.
> 
> That part could very well also use regmap_update_bits like the other parts.
> Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> matters at all.

regmap_update_bits also acquires the regmap lock, which would similarly
be a problem here.[1]

But, if we could pull this entire operation out of the lock (and
convince ourselves that it's okay to do so), then even better!

   Julia

1: Why is this a problem?  Because we're in the middle of a
   raw_spinlock_t protected critical region: if there were contention on
   the nested mutex (the "regmap mutex"), then we'd attempt to sleep in
   atomic context.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170315/8296ca0e/attachment.sig>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
  2017-03-15 18:23           ` Julia Cartwright
  (?)
@ 2017-03-15 18:46             ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:46 UTC (permalink / raw)
  To: Julia Cartwright
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

On Wed, 15 Mar 2017 13:23:09 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> > Am Mittwoch, 15. März 2017, 18:08:06 CET schrieb John Keeping:  
> > > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:  
> > > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:  
> > > > > 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  
> [..]
> > > > > @@ -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);  
> > > > 
> > > > This should be lifted out from under the lock.
> > > >   
> > > > >  		ret = regmap_write(regmap, reg, data);  
> > > > 
> > > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > > the regmap mutex.  
> > > 
> > > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > > to test and I missed this when checking the uses of slock.  
> > 
> > That part could very well also use regmap_update_bits like the other parts.
> > Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> > matters at all.  
> 
> regmap_update_bits also acquires the regmap lock, which would similarly
> be a problem here.[1]
> 
> But, if we could pull this entire operation out of the lock (and
> convince ourselves that it's okay to do so), then even better!

Yes, we can delete the lock here for the same reason as all of the
others that are removed in patch 1.

I don't think it makes much difference whether we use regmap_write or
regmap_update_bits here (although consistently using regmap_update_bits
might be nice) so I won't change it as part of this series, especially
since I don't have an RK2928 to test.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:46             ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:46 UTC (permalink / raw)
  To: Julia Cartwright
  Cc: Heiko Stuebner, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

On Wed, 15 Mar 2017 13:23:09 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> > Am Mittwoch, 15. März 2017, 18:08:06 CET schrieb John Keeping:  
> > > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:  
> > > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:  
> > > > > 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  
> [..]
> > > > > @@ -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);  
> > > > 
> > > > This should be lifted out from under the lock.
> > > >   
> > > > >  		ret = regmap_write(regmap, reg, data);  
> > > > 
> > > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > > the regmap mutex.  
> > > 
> > > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > > to test and I missed this when checking the uses of slock.  
> > 
> > That part could very well also use regmap_update_bits like the other parts.
> > Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> > matters at all.  
> 
> regmap_update_bits also acquires the regmap lock, which would similarly
> be a problem here.[1]
> 
> But, if we could pull this entire operation out of the lock (and
> convince ourselves that it's okay to do so), then even better!

Yes, we can delete the lock here for the same reason as all of the
others that are removed in patch 1.

I don't think it makes much difference whether we use regmap_write or
regmap_update_bits here (although consistently using regmap_update_bits
might be nice) so I won't change it as part of this series, especially
since I don't have an RK2928 to test.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock
@ 2017-03-15 18:46             ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 15 Mar 2017 13:23:09 -0500, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 07:16:53PM +0100, Heiko Stuebner wrote:
> > Am Mittwoch, 15. M?rz 2017, 18:08:06 CET schrieb John Keeping:  
> > > On Wed, 15 Mar 2017 13:01:37 -0500, Julia Cartwright wrote:  
> > > > On Wed, Mar 15, 2017 at 05:46:52PM +0000, John Keeping wrote:  
> > > > > 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  
> [..]
> > > > > @@ -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);  
> > > > 
> > > > This should be lifted out from under the lock.
> > > >   
> > > > >  		ret = regmap_write(regmap, reg, data);  
> > > > 
> > > > How is this legal?  The regmap_write() here is going to end up acquiring
> > > > the regmap mutex.  
> > > 
> > > It's not, the spinlock can be deleted here.  I only have RK3288 hardware
> > > to test and I missed this when checking the uses of slock.  
> > 
> > That part could very well also use regmap_update_bits like the other parts.
> > Not really sure, why we use regmap_write here, but I'm also not sure, if it 
> > matters at all.  
> 
> regmap_update_bits also acquires the regmap lock, which would similarly
> be a problem here.[1]
> 
> But, if we could pull this entire operation out of the lock (and
> convince ourselves that it's okay to do so), then even better!

Yes, we can delete the lock here for the same reason as all of the
others that are removed in patch 1.

I don't think it makes much difference whether we use regmap_write or
regmap_update_bits here (although consistently using regmap_update_bits
might be nice) so I won't change it as part of this series, especially
since I don't have an RK2928 to test.


John

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2.1 1/4] pinctrl: rockchip: remove unnecessary locking
  2017-03-15 17:46   ` John Keeping
@ 2017-03-15 18:51     ` John Keeping
  -1 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:51 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: Julia Cartwright, Linus Walleij, linux-gpio, linux-arm-kernel,
	linux-rockchip, linux-kernel

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, &reg, &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


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2.1 1/4] pinctrl: rockchip: remove unnecessary locking
@ 2017-03-15 18:51     ` John Keeping
  0 siblings, 0 replies; 34+ messages in thread
From: John Keeping @ 2017-03-15 18:51 UTC (permalink / raw)
  To: linux-arm-kernel

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, &reg, &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

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
  2017-03-15 17:46   ` John Keeping
  (?)
@ 2017-03-23  9:03     ` Linus Walleij
  -1 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2017-03-23  9:03 UTC (permalink / raw)
  To: John Keeping
  Cc: Heiko Stuebner, Julia Cartwright, linux-gpio, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	linux-kernel

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
@ 2017-03-23  9:03     ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2017-03-23  9:03 UTC (permalink / raw)
  To: John Keeping
  Cc: Heiko Stuebner, Julia Cartwright, linux-gpio, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	linux-kernel

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking
@ 2017-03-23  9:03     ` Linus Walleij
  0 siblings, 0 replies; 34+ messages in thread
From: Linus Walleij @ 2017-03-23  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

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

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2017-03-23  9:03 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-15 17:46 [PATCH v2 0/4] pinctrl: rockchip: PREEMPT_RT_FULL fixes John Keeping
2017-03-15 17:46 ` John Keeping
2017-03-15 17:46 ` John Keeping
2017-03-15 17:46 ` [PATCH v2 1/4] pinctrl: rockchip: remove unnecessary locking John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 18:51   ` [PATCH v2.1 " John Keeping
2017-03-15 18:51     ` John Keeping
2017-03-23  9:03   ` [PATCH v2 " Linus Walleij
2017-03-23  9:03     ` Linus Walleij
2017-03-23  9:03     ` Linus Walleij
2017-03-15 17:46 ` [PATCH v2 2/4] pinctrl: rockchip: convert to raw spinlock John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 18:01   ` Julia Cartwright
2017-03-15 18:01     ` Julia Cartwright
2017-03-15 18:01     ` Julia Cartwright
2017-03-15 18:08     ` John Keeping
2017-03-15 18:08       ` John Keeping
2017-03-15 18:08       ` John Keeping
2017-03-15 18:16       ` Heiko Stuebner
2017-03-15 18:16         ` Heiko Stuebner
2017-03-15 18:23         ` Julia Cartwright
2017-03-15 18:23           ` Julia Cartwright
2017-03-15 18:23           ` Julia Cartwright
2017-03-15 18:46           ` John Keeping
2017-03-15 18:46             ` John Keeping
2017-03-15 18:46             ` John Keeping
2017-03-15 17:46 ` [PATCH v2 3/4] pinctrl: rockchip: split out verification of mux settings John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 17:46 ` [PATCH v2 4/4] pinctrl: rockchip: avoid hardirq-unsafe functions in irq_chip John Keeping
2017-03-15 17:46   ` John Keeping
2017-03-15 17:46   ` John Keeping

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.