The following patchset introduces a new coccinelle patch,
irq_chip_raw_spinlock.cocci, which is used to identify irq_chip implementors
which acquire/release non-raw spinlocks, and in addition, a set of generated
patches for most cases identified.
On mainline builds, there exists no functional difference between
raw_spinlock_t and spinlock_t. However, w/ PREEMPT_RT, the spinlock_t will
cause the calling thread to sleep when the lock is contended. Because sleeping
is illegal in hardirq context, and because the irqchip callbacks are invoked in
hardirq context, irqchip implementations must not use spin_lock_t for
synchronization.
Patches build tested only.
Some notes:
- In order to ensure that latency problems are not introduced for realtime
kernels, the generated patches need to be hand audited to ensure that
raw-spinlock protected regions are bounded and minimal. I've done a quick
audit for each of the modified drivers in this series, but please check my
work.
- There are a couple of matches which will require further intervention to
fully fix. Namely the Intel LPE Audio driver:
drivers/gpu/drm/i915/intel_lpe_audio.c:169:30-38: Use of non-raw spinlock is illegal in this context (struct drm_i915_private::irq_lock)
and the adi2 pinctrl driver:
drivers/pinctrl/pinctrl-adi2.c:308:26-30: Use of non-raw spinlock is illegal in this context (struct gpio_port::lock)
- This semantic patch is not comprehensive, there are other equally broken
usecases which are not properly identified yet, such as the use of a single
global spinlock_t declared via DEFINE_SPINLOCK() (found in arch/alpha, and
perhaps elsewhere).
Julia
Cc: Thomas Gleixner <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Cc: Linus Walleij <[email protected]>
Cc: Julia Lawall <[email protected]>
Cc: Gilles Muller <[email protected]>
Cc: Nicolas Palix <[email protected]>
Cc: Michal Marek <[email protected]>
Cc: [email protected]
---------
Julia Cartwright (19):
Coccinelle: locks: identify callers of spin_lock{,_irq,_irqsave}() in
irqchip implementations
gpio: altera: make use of raw_spinlock variants
alpha: marvel: make use of raw_spinlock variants
powerpc: mpc52xx_gpt: make use of raw_spinlock variants
gpio: 104-dio-48e: make use of raw_spinlock variants
gpio: ath79: make use of raw_spinlock variants
gpio: bcm-kona: make use of raw_spinlock variants
gpio: etraxfs: make use of raw_spinlock variants
gpio: pl061: make use of raw_spinlock variants
gpio: ws16c48: make use of raw_spinlock variants
gpio: zx: make use of raw_spinlock variants
i2c: mux: pca954x: make use of raw_spinlock variants
mfd: asic3: make use of raw_spinlock variants
mfd: t7l66xb: make use of raw_spinlock variants
mfd: tc6393xb: make use of raw_spinlock variants
pinctrl: bcm: make use of raw_spinlock variants
pinctrl: amd: make use of raw_spinlock variants
pinctrl: sirf: atlas7: make use of raw_spinlock variants
pinctrl: sunxi: make use of raw_spinlock variants
arch/alpha/include/asm/core_marvel.h | 2 +-
arch/alpha/kernel/sys_marvel.c | 12 +--
arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 52 ++++++------
drivers/gpio/gpio-104-dio-48e.c | 38 ++++-----
drivers/gpio/gpio-altera.c | 24 +++---
drivers/gpio/gpio-ath79.c | 28 +++----
drivers/gpio/gpio-bcm-kona.c | 48 +++++------
drivers/gpio/gpio-etraxfs.c | 24 +++---
drivers/gpio/gpio-pl061.c | 28 +++----
drivers/gpio/gpio-ws16c48.c | 46 +++++------
drivers/gpio/gpio-zx.c | 24 +++---
drivers/i2c/muxes/i2c-mux-pca954x.c | 12 +--
drivers/mfd/asic3.c | 56 ++++++-------
drivers/mfd/t7l66xb.c | 20 ++---
drivers/mfd/tc6393xb.c | 52 ++++++------
drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 44 +++++-----
drivers/pinctrl/bcm/pinctrl-nsp-gpio.c | 46 +++++------
drivers/pinctrl/pinctrl-amd.c | 66 +++++++--------
drivers/pinctrl/pinctrl-amd.h | 2 +-
drivers/pinctrl/sirf/pinctrl-atlas7.c | 44 +++++-----
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 26 +++---
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 +-
.../coccinelle/locks/irq_chip_raw_spinlock.cocci | 96 ++++++++++++++++++++++
23 files changed, 444 insertions(+), 348 deletions(-)
create mode 100644 scripts/coccinelle/locks/irq_chip_raw_spinlock.cocci
--
2.11.1
On PREEMPT_RT, the spinlock_t type becomes an object which sleeps under
contention. The codepaths used to support scheduling (irq dispatching, arch
code, the scheduler, timers) therefore must make use of the
raw_spin_lock{,_irq,_irqsave}() variations which preserve the non-sleeping
spinlock behavior.
Because the irq_chip callbacks are invoked in the process of interrupt
dispatch, they cannot therefore make use of spin_lock_t type. Instead, the
usage of raw_spinlock_t is appropriate.
Provide a spatch to identify (and attempt to patch) such problematic irqchip
implementations.
Note to those generating patches using this spatch; in order to maintain
correct semantics w/ PREEMPT_RT, it is necessary to audit the
raw_spinlock_t-protected codepaths to ensure their execution is bounded and
minimal. This is a manual audit process.
See commit 47b03ca903fb0 ("pinctrl: qcom: Use raw spinlock variants") as an
example of _one_ such instance, which fixed a real bug seen in the field.
Cc: Thomas Gleixner <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Cc: Linus Walleij <[email protected]>
Signed-off-by: Julia Cartwright <[email protected]>
---
.../coccinelle/locks/irq_chip_raw_spinlock.cocci | 96 ++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 scripts/coccinelle/locks/irq_chip_raw_spinlock.cocci
diff --git a/scripts/coccinelle/locks/irq_chip_raw_spinlock.cocci b/scripts/coccinelle/locks/irq_chip_raw_spinlock.cocci
new file mode 100644
index 000000000000..73fd4519ae29
--- /dev/null
+++ b/scripts/coccinelle/locks/irq_chip_raw_spinlock.cocci
@@ -0,0 +1,96 @@
+// Copyright: (C) 2017 National Instruments Corp. GPLv2.
+// Author: Julia Cartwright <[email protected]>
+//
+// Identify callers of non-raw spinlock_t functions in hardirq irq_chip
+// callbacks.
+//
+// spin_lock{_irq,_irqsave}(), w/ PREEMPT_RT are "sleeping" spinlocks, and so
+// therefore "sleep" under contention; identify (and potentially patch) callers
+// to use raw_spinlock_t instead.
+//
+// Confidence: Moderate
+
+virtual report
+virtual patch
+
+@match@
+identifier __irqchip;
+identifier __irq_mask;
+@@
+ static struct irq_chip __irqchip = {
+ .irq_mask = __irq_mask,
+ };
+
+@match2 depends on match@
+identifier match.__irq_mask;
+identifier data;
+identifier x;
+identifier l;
+type T;
+position j0;
+expression flags;
+@@
+ static void __irq_mask(struct irq_data *data)
+ {
+ ...
+ T *x;
+ ...
+(
+ spin_lock_irqsave(&x->l@j0, flags);
+|
+ spin_lock_irq(&x->l@j0);
+|
+ spin_lock(&x->l@j0);
+)
+ ...
+ }
+
+@match3 depends on match2 && patch@
+type match2.T;
+identifier match2.l;
+@@
+ T {
+ ...
+- spinlock_t l;
++ raw_spinlock_t l;
+ ...
+ };
+
+@match4 depends on match2 && patch@
+type match2.T;
+identifier match2.l;
+expression flags;
+T *x;
+@@
+
+(
+-spin_lock(&x->l)
++raw_spin_lock(&x->l)
+|
+-spin_lock_irqsave(&x->l, flags)
++raw_spin_lock_irqsave(&x->l, flags)
+|
+-spin_lock_irq(&x->l)
++raw_spin_lock_irq(&x->l)
+|
+-spin_unlock(&x->l)
++raw_spin_unlock(&x->l)
+|
+-spin_unlock_irq(&x->l)
++raw_spin_unlock_irq(&x->l)
+|
+-spin_unlock_irqrestore(&x->l, flags)
++raw_spin_unlock_irqrestore(&x->l, flags)
+|
+-spin_lock_init(&x->l)
++raw_spin_lock_init(&x->l)
+)
+
+@script:python wat depends on match2 && report@
+j0 << match2.j0;
+t << match2.T;
+l << match2.l;
+@@
+
+msg = "Use of non-raw spinlock is illegal in this context (%s::%s)" % (t, l)
+coccilib.report.print_report(j0[0], msg)
--
2.11.1
The ws16c48 gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-ws16c48.c | 46 ++++++++++++++++++++++-----------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c
index 901b5ccb032d..87d63695dfcf 100644
--- a/drivers/gpio/gpio-ws16c48.c
+++ b/drivers/gpio/gpio-ws16c48.c
@@ -51,7 +51,7 @@ struct ws16c48_gpio {
struct gpio_chip chip;
unsigned char io_state[6];
unsigned char out_state[6];
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned long irq_mask;
unsigned long flow_mask;
unsigned base;
@@ -73,13 +73,13 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
const unsigned mask = BIT(offset % 8);
unsigned long flags;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
ws16c48gpio->io_state[port] |= mask;
ws16c48gpio->out_state[port] &= ~mask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return 0;
}
@@ -92,7 +92,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
const unsigned mask = BIT(offset % 8);
unsigned long flags;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
ws16c48gpio->io_state[port] &= ~mask;
if (value)
@@ -101,7 +101,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
ws16c48gpio->out_state[port] &= ~mask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return 0;
}
@@ -114,17 +114,17 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned port_state;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
/* ensure that GPIO is set for input */
if (!(ws16c48gpio->io_state[port] & mask)) {
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return -EINVAL;
}
port_state = inb(ws16c48gpio->base + port);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return !!(port_state & mask);
}
@@ -136,11 +136,11 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
const unsigned mask = BIT(offset % 8);
unsigned long flags;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
/* ensure that GPIO is set for output */
if (ws16c48gpio->io_state[port] & mask) {
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return;
}
@@ -150,7 +150,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
ws16c48gpio->out_state[port] &= ~mask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
@@ -178,14 +178,14 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port];
bitmask = iomask & bits[BIT_WORD(i)];
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
/* update output state data and set device gpio register */
ws16c48gpio->out_state[port] &= ~iomask;
ws16c48gpio->out_state[port] |= bitmask;
outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
/* prepare for next gpio register set */
mask[BIT_WORD(i)] >>= gpio_reg_size;
@@ -207,7 +207,7 @@ static void ws16c48_irq_ack(struct irq_data *data)
if (port > 2)
return;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
port_state = ws16c48gpio->irq_mask >> (8*port);
@@ -216,7 +216,7 @@ static void ws16c48_irq_ack(struct irq_data *data)
outb(port_state | mask, ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
static void ws16c48_irq_mask(struct irq_data *data)
@@ -232,7 +232,7 @@ static void ws16c48_irq_mask(struct irq_data *data)
if (port > 2)
return;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
ws16c48gpio->irq_mask &= ~mask;
@@ -240,7 +240,7 @@ static void ws16c48_irq_mask(struct irq_data *data)
outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
static void ws16c48_irq_unmask(struct irq_data *data)
@@ -256,7 +256,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)
if (port > 2)
return;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
ws16c48gpio->irq_mask |= mask;
@@ -264,7 +264,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)
outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
}
static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
@@ -280,7 +280,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
if (port > 2)
return -EINVAL;
- spin_lock_irqsave(&ws16c48gpio->lock, flags);
+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
switch (flow_type) {
case IRQ_TYPE_NONE:
@@ -292,7 +292,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
ws16c48gpio->flow_mask &= ~mask;
break;
default:
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return -EINVAL;
}
@@ -300,7 +300,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
outb(0xC0, ws16c48gpio->base + 7);
- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
return 0;
}
@@ -387,7 +387,7 @@ static int ws16c48_probe(struct device *dev, unsigned int id)
ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
ws16c48gpio->base = base[id];
- spin_lock_init(&ws16c48gpio->lock);
+ raw_spin_lock_init(&ws16c48gpio->lock);
err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
if (err) {
--
2.11.1
The zx gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-zx.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpio/gpio-zx.c b/drivers/gpio/gpio-zx.c
index 93de8be0d885..be3a87da8438 100644
--- a/drivers/gpio/gpio-zx.c
+++ b/drivers/gpio/gpio-zx.c
@@ -41,7 +41,7 @@
#define ZX_GPIO_NR 16
struct zx_gpio {
- spinlock_t lock;
+ raw_spinlock_t lock;
void __iomem *base;
struct gpio_chip gc;
@@ -56,11 +56,11 @@ static int zx_direction_input(struct gpio_chip *gc, unsigned offset)
if (offset >= gc->ngpio)
return -EINVAL;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR);
gpiodir &= ~BIT(offset);
writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -75,7 +75,7 @@ static int zx_direction_output(struct gpio_chip *gc, unsigned offset,
if (offset >= gc->ngpio)
return -EINVAL;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR);
gpiodir |= BIT(offset);
writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR);
@@ -84,7 +84,7 @@ static int zx_direction_output(struct gpio_chip *gc, unsigned offset,
writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO1);
else
writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO0);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -118,7 +118,7 @@ static int zx_irq_type(struct irq_data *d, unsigned trigger)
if (offset < 0 || offset >= ZX_GPIO_NR)
return -EINVAL;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
gpioiev = readw_relaxed(chip->base + ZX_GPIO_IV);
gpiois = readw_relaxed(chip->base + ZX_GPIO_IVE);
@@ -151,7 +151,7 @@ static int zx_irq_type(struct irq_data *d, unsigned trigger)
writew_relaxed(gpioi_epos, chip->base + ZX_GPIO_IEP);
writew_relaxed(gpioi_eneg, chip->base + ZX_GPIO_IEN);
writew_relaxed(gpioiev, chip->base + ZX_GPIO_IV);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -184,12 +184,12 @@ static void zx_irq_mask(struct irq_data *d)
u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR);
u16 gpioie;
- spin_lock(&chip->lock);
+ raw_spin_lock(&chip->lock);
gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) | mask;
writew_relaxed(gpioie, chip->base + ZX_GPIO_IM);
gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) & ~mask;
writew_relaxed(gpioie, chip->base + ZX_GPIO_IE);
- spin_unlock(&chip->lock);
+ raw_spin_unlock(&chip->lock);
}
static void zx_irq_unmask(struct irq_data *d)
@@ -199,12 +199,12 @@ static void zx_irq_unmask(struct irq_data *d)
u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR);
u16 gpioie;
- spin_lock(&chip->lock);
+ raw_spin_lock(&chip->lock);
gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) & ~mask;
writew_relaxed(gpioie, chip->base + ZX_GPIO_IM);
gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) | mask;
writew_relaxed(gpioie, chip->base + ZX_GPIO_IE);
- spin_unlock(&chip->lock);
+ raw_spin_unlock(&chip->lock);
}
static struct irq_chip zx_irqchip = {
@@ -230,7 +230,7 @@ static int zx_gpio_probe(struct platform_device *pdev)
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
- spin_lock_init(&chip->lock);
+ raw_spin_lock_init(&chip->lock);
if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
chip->gc.request = gpiochip_generic_request;
chip->gc.free = gpiochip_generic_free;
--
2.11.1
The bcm pinctrl drivers currently implement an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 44 +++++++++++++++---------------
drivers/pinctrl/bcm/pinctrl-nsp-gpio.c | 46 ++++++++++++++++----------------
2 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index 3ca925dfefd1..af5e904d4a1e 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -99,7 +99,7 @@ struct iproc_gpio {
void __iomem *base;
void __iomem *io_ctrl;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct gpio_chip gc;
unsigned num_banks;
@@ -221,9 +221,9 @@ static void iproc_gpio_irq_mask(struct irq_data *d)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_gpio_irq_set_mask(d, false);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static void iproc_gpio_irq_unmask(struct irq_data *d)
@@ -232,9 +232,9 @@ static void iproc_gpio_irq_unmask(struct irq_data *d)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_gpio_irq_set_mask(d, true);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@@ -274,13 +274,13 @@ static int iproc_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_INT_TYPE_OFFSET, gpio,
level_triggered);
iproc_set_bit(chip, IPROC_GPIO_INT_DE_OFFSET, gpio, dual_edge);
iproc_set_bit(chip, IPROC_GPIO_INT_EDGE_OFFSET, gpio,
rising_or_high);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev,
"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
@@ -328,9 +328,9 @@ static int iproc_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, false);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
@@ -343,10 +343,10 @@ static int iproc_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_OUT_EN_OFFSET, gpio, true);
iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
@@ -358,9 +358,9 @@ static void iproc_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
struct iproc_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
iproc_set_bit(chip, IPROC_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}
@@ -461,7 +461,7 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
{
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
if (disable) {
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, false);
@@ -471,7 +471,7 @@ static int iproc_gpio_set_pull(struct iproc_gpio *chip, unsigned gpio,
iproc_set_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio, true);
}
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
@@ -483,10 +483,10 @@ static void iproc_gpio_get_pull(struct iproc_gpio *chip, unsigned gpio,
{
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
*disable = !iproc_get_bit(chip, IPROC_GPIO_RES_EN_OFFSET, gpio);
*pull_up = iproc_get_bit(chip, IPROC_GPIO_PAD_RES_OFFSET, gpio);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
@@ -515,7 +515,7 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
strength);
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset);
@@ -524,7 +524,7 @@ static int iproc_gpio_set_strength(struct iproc_gpio *chip, unsigned gpio,
writel(val, base + offset);
offset += 4;
}
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -548,7 +548,7 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
shift = IPROC_GPIO_SHIFT(gpio);
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
val = readl(base + offset) & BIT(shift);
@@ -559,7 +559,7 @@ static int iproc_gpio_get_strength(struct iproc_gpio *chip, unsigned gpio,
/* convert to mA */
*strength = (*strength + 1) * 2;
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -769,7 +769,7 @@ static int iproc_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- spin_lock_init(&chip->lock);
+ raw_spin_lock_init(&chip->lock);
gc = &chip->gc;
gc->base = -1;
diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
index 91ea32dc1e7f..22442438275a 100644
--- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
@@ -73,7 +73,7 @@ struct nsp_gpio {
struct pinctrl_dev *pctl;
struct pinctrl_desc pctldesc;
struct irq_domain *irq_domain;
- spinlock_t lock;
+ raw_spinlock_t lock;
};
enum base_type {
@@ -203,9 +203,9 @@ static void nsp_gpio_irq_mask(struct irq_data *d)
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_gpio_irq_set_mask(d, false);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static void nsp_gpio_irq_unmask(struct irq_data *d)
@@ -213,9 +213,9 @@ static void nsp_gpio_irq_unmask(struct irq_data *d)
struct nsp_gpio *chip = irq_data_get_irq_chip_data(d);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_gpio_irq_set_mask(d, true);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@@ -226,7 +226,7 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
bool falling;
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
falling = nsp_get_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio);
level_low = nsp_get_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio);
@@ -250,13 +250,13 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type)
default:
dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
type);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return -EINVAL;
}
nsp_set_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio, falling);
nsp_set_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio, level_low);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u level_low:%s falling:%s\n", gpio,
level_low ? "true" : "false", falling ? "true" : "false");
@@ -295,9 +295,9 @@ static int nsp_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_OUT_EN, gpio, false);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
return 0;
@@ -309,10 +309,10 @@ static int nsp_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_OUT_EN, gpio, true);
nsp_set_bit(chip, REG, NSP_GPIO_DATA_OUT, gpio, !!(val));
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
return 0;
@@ -323,9 +323,9 @@ static void nsp_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
struct nsp_gpio *chip = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, REG, NSP_GPIO_DATA_OUT, gpio, !!(val));
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
}
@@ -381,10 +381,10 @@ static int nsp_gpio_set_pull(struct nsp_gpio *chip, unsigned gpio,
{
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
nsp_set_bit(chip, IO_CTRL, NSP_PULL_DOWN_EN, gpio, pull_down);
nsp_set_bit(chip, IO_CTRL, NSP_PULL_UP_EN, gpio, pull_up);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
dev_dbg(chip->dev, "gpio:%u set pullup:%d pulldown: %d\n",
gpio, pull_up, pull_down);
@@ -396,10 +396,10 @@ static void nsp_gpio_get_pull(struct nsp_gpio *chip, unsigned gpio,
{
unsigned long flags;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
*pull_up = nsp_get_bit(chip, IO_CTRL, NSP_PULL_UP_EN, gpio);
*pull_down = nsp_get_bit(chip, IO_CTRL, NSP_PULL_DOWN_EN, gpio);
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
}
static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
@@ -417,7 +417,7 @@ static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
offset = NSP_GPIO_DRV_CTRL;
dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
strength);
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
strength = (strength / 2) - 1;
for (i = GPIO_DRV_STRENGTH_BITS; i > 0; i--) {
val = readl(chip->io_ctrl + offset);
@@ -426,7 +426,7 @@ static int nsp_gpio_set_strength(struct nsp_gpio *chip, unsigned gpio,
writel(val, chip->io_ctrl + offset);
offset += 4;
}
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -442,7 +442,7 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
offset = NSP_GPIO_DRV_CTRL;
shift = gpio;
- spin_lock_irqsave(&chip->lock, flags);
+ raw_spin_lock_irqsave(&chip->lock, flags);
*strength = 0;
for (i = (GPIO_DRV_STRENGTH_BITS - 1); i >= 0; i--) {
val = readl(chip->io_ctrl + offset) & BIT(shift);
@@ -453,7 +453,7 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio,
/* convert to mA */
*strength = (*strength + 1) * 2;
- spin_unlock_irqrestore(&chip->lock, flags);
+ raw_spin_unlock_irqrestore(&chip->lock, flags);
return 0;
}
@@ -660,7 +660,7 @@ static int nsp_gpio_probe(struct platform_device *pdev)
return PTR_ERR(chip->io_ctrl);
}
- spin_lock_init(&chip->lock);
+ raw_spin_lock_init(&chip->lock);
gc = &chip->gc;
gc->base = -1;
gc->can_sleep = false;
--
2.11.1
The tc6393xb mfd driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/mfd/tc6393xb.c | 52 +++++++++++++++++++++++++-------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index d42d322ac7ca..d16e71bd9482 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -95,7 +95,7 @@ struct tc6393xb {
struct clk *clk; /* 3,6 Mhz */
- spinlock_t lock; /* protects RMW cycles */
+ raw_spinlock_t lock; /* protects RMW cycles */
struct {
u8 fer;
@@ -126,13 +126,13 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
unsigned long flags;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
/* SMD buffer on */
dev_dbg(&dev->dev, "SMD buffer on\n");
tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -226,7 +226,7 @@ static int tc6393xb_ohci_enable(struct platform_device *dev)
u16 ccr;
u8 fer;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
ccr |= SCR_CCR_USBCK;
@@ -236,7 +236,7 @@ static int tc6393xb_ohci_enable(struct platform_device *dev)
fer |= SCR_FER_USBEN;
tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -248,7 +248,7 @@ static int tc6393xb_ohci_disable(struct platform_device *dev)
u16 ccr;
u8 fer;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
fer &= ~SCR_FER_USBEN;
@@ -258,7 +258,7 @@ static int tc6393xb_ohci_disable(struct platform_device *dev)
ccr &= ~SCR_CCR_USBCK;
tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -280,14 +280,14 @@ static int tc6393xb_fb_enable(struct platform_device *dev)
unsigned long flags;
u16 ccr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
ccr &= ~SCR_CCR_MCLK_MASK;
ccr |= SCR_CCR_MCLK_48;
tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -298,14 +298,14 @@ static int tc6393xb_fb_disable(struct platform_device *dev)
unsigned long flags;
u16 ccr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
ccr &= ~SCR_CCR_MCLK_MASK;
ccr |= SCR_CCR_MCLK_OFF;
tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -317,7 +317,7 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
u8 fer;
unsigned long flags;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
fer = ioread8(tc6393xb->scr + SCR_FER);
if (on)
@@ -326,7 +326,7 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
fer &= ~SCR_FER_SLCDEN;
iowrite8(fer, tc6393xb->scr + SCR_FER);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -338,12 +338,12 @@ int tc6393xb_lcd_mode(struct platform_device *fb,
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
unsigned long flags;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -462,11 +462,11 @@ static void tc6393xb_gpio_set(struct gpio_chip *chip,
struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
unsigned long flags;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
__tc6393xb_gpio_set(chip, offset, value);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
}
static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
@@ -476,13 +476,13 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
unsigned long flags;
u8 doecr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
doecr &= ~TC_GPIO_BIT(offset);
tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -494,7 +494,7 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
unsigned long flags;
u8 doecr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
__tc6393xb_gpio_set(chip, offset, value);
@@ -502,7 +502,7 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
doecr |= TC_GPIO_BIT(offset);
tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
@@ -548,11 +548,11 @@ static void tc6393xb_irq_mask(struct irq_data *data)
unsigned long flags;
u8 imr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
imr |= 1 << (data->irq - tc6393xb->irq_base);
tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
}
static void tc6393xb_irq_unmask(struct irq_data *data)
@@ -561,11 +561,11 @@ static void tc6393xb_irq_unmask(struct irq_data *data)
unsigned long flags;
u8 imr;
- spin_lock_irqsave(&tc6393xb->lock, flags);
+ raw_spin_lock_irqsave(&tc6393xb->lock, flags);
imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
imr &= ~(1 << (data->irq - tc6393xb->irq_base));
tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
- spin_unlock_irqrestore(&tc6393xb->lock, flags);
+ raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
}
static struct irq_chip tc6393xb_chip = {
@@ -628,7 +628,7 @@ static int tc6393xb_probe(struct platform_device *dev)
goto err_kzalloc;
}
- spin_lock_init(&tc6393xb->lock);
+ raw_spin_lock_init(&tc6393xb->lock);
platform_set_drvdata(dev, tc6393xb);
--
2.11.1
The altera gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a real-time
kernel. Because the spinlock_t type becomes a "sleeping" spinlock w/ RT
kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-altera.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
index 3fe6a21e05a5..17485dc20384 100644
--- a/drivers/gpio/gpio-altera.c
+++ b/drivers/gpio/gpio-altera.c
@@ -38,7 +38,7 @@
*/
struct altera_gpio_chip {
struct of_mm_gpio_chip mmchip;
- spinlock_t gpio_lock;
+ raw_spinlock_t gpio_lock;
int interrupt_trigger;
int mapped_irq;
};
@@ -53,12 +53,12 @@ static void altera_gpio_irq_unmask(struct irq_data *d)
altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
mm_gc = &altera_gc->mmchip;
- spin_lock_irqsave(&altera_gc->gpio_lock, flags);
+ raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
/* Set ALTERA_GPIO_IRQ_MASK bit to unmask */
intmask |= BIT(irqd_to_hwirq(d));
writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
- spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
}
static void altera_gpio_irq_mask(struct irq_data *d)
@@ -71,12 +71,12 @@ static void altera_gpio_irq_mask(struct irq_data *d)
altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
mm_gc = &altera_gc->mmchip;
- spin_lock_irqsave(&altera_gc->gpio_lock, flags);
+ raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
/* Clear ALTERA_GPIO_IRQ_MASK bit to mask */
intmask &= ~BIT(irqd_to_hwirq(d));
writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
- spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
}
/**
@@ -140,14 +140,14 @@ static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
if (value)
data_reg |= BIT(offset);
else
data_reg &= ~BIT(offset);
writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
}
static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
@@ -160,12 +160,12 @@ static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
/* Set pin as input, assumes software controlled IP */
gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
gpio_ddr &= ~BIT(offset);
writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
return 0;
}
@@ -181,7 +181,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc,
mm_gc = to_of_mm_gpio_chip(gc);
chip = gpiochip_get_data(gc);
- spin_lock_irqsave(&chip->gpio_lock, flags);
+ raw_spin_lock_irqsave(&chip->gpio_lock, flags);
/* Sets the GPIO value */
data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
if (value)
@@ -194,7 +194,7 @@ static int altera_gpio_direction_output(struct gpio_chip *gc,
gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
gpio_ddr |= BIT(offset);
writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
- spin_unlock_irqrestore(&chip->gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
return 0;
}
@@ -262,7 +262,7 @@ static int altera_gpio_probe(struct platform_device *pdev)
if (!altera_gc)
return -ENOMEM;
- spin_lock_init(&altera_gc->gpio_lock);
+ raw_spin_lock_init(&altera_gc->gpio_lock);
if (of_property_read_u32(node, "altr,ngpio", ®))
/* By default assume maximum ngpio */
--
2.11.1
The ath79 gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-ath79.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
index dc37dbe4b46d..f33d4a5fe671 100644
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -32,7 +32,7 @@
struct ath79_gpio_ctrl {
struct gpio_chip gc;
void __iomem *base;
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned long both_edges;
};
@@ -74,9 +74,9 @@ static void ath79_gpio_irq_unmask(struct irq_data *data)
u32 mask = BIT(irqd_to_hwirq(data));
unsigned long flags;
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
}
static void ath79_gpio_irq_mask(struct irq_data *data)
@@ -85,9 +85,9 @@ static void ath79_gpio_irq_mask(struct irq_data *data)
u32 mask = BIT(irqd_to_hwirq(data));
unsigned long flags;
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
}
static void ath79_gpio_irq_enable(struct irq_data *data)
@@ -96,10 +96,10 @@ static void ath79_gpio_irq_enable(struct irq_data *data)
u32 mask = BIT(irqd_to_hwirq(data));
unsigned long flags;
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, mask);
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
}
static void ath79_gpio_irq_disable(struct irq_data *data)
@@ -108,10 +108,10 @@ static void ath79_gpio_irq_disable(struct irq_data *data)
u32 mask = BIT(irqd_to_hwirq(data));
unsigned long flags;
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_MASK, mask, 0);
ath79_gpio_update_bits(ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, 0);
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
}
static int ath79_gpio_irq_set_type(struct irq_data *data,
@@ -140,7 +140,7 @@ static int ath79_gpio_irq_set_type(struct irq_data *data,
return -EINVAL;
}
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
if (flow_type == IRQ_TYPE_EDGE_BOTH) {
ctrl->both_edges |= mask;
@@ -165,7 +165,7 @@ static int ath79_gpio_irq_set_type(struct irq_data *data,
ath79_gpio_update_bits(
ctrl, AR71XX_GPIO_REG_INT_ENABLE, mask, mask);
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
return 0;
}
@@ -191,7 +191,7 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(irqchip, desc);
- spin_lock_irqsave(&ctrl->lock, flags);
+ raw_spin_lock_irqsave(&ctrl->lock, flags);
pending = ath79_gpio_read(ctrl, AR71XX_GPIO_REG_INT_PENDING);
@@ -203,7 +203,7 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc)
both_edges, ~state);
}
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ raw_spin_unlock_irqrestore(&ctrl->lock, flags);
if (pending) {
for_each_set_bit(irq, &pending, gc->ngpio)
@@ -262,7 +262,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
if (!ctrl->base)
return -ENOMEM;
- spin_lock_init(&ctrl->lock);
+ raw_spin_lock_init(&ctrl->lock);
err = bgpio_init(&ctrl->gc, &pdev->dev, 4,
ctrl->base + AR71XX_GPIO_REG_IN,
ctrl->base + AR71XX_GPIO_REG_SET,
--
2.11.1
The pca954x i2c mux driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/i2c/muxes/i2c-mux-pca954x.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index dfc1c0e37c40..15dfc1648716 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -85,7 +85,7 @@ struct pca954x {
struct irq_domain *irq;
unsigned int irq_mask;
- spinlock_t lock;
+ raw_spinlock_t lock;
};
/* Provide specs for the PCA954x types we know about */
@@ -264,13 +264,13 @@ static void pca954x_irq_mask(struct irq_data *idata)
unsigned int pos = idata->hwirq;
unsigned long flags;
- spin_lock_irqsave(&data->lock, flags);
+ raw_spin_lock_irqsave(&data->lock, flags);
data->irq_mask &= ~BIT(pos);
if (!data->irq_mask)
disable_irq(data->client->irq);
- spin_unlock_irqrestore(&data->lock, flags);
+ raw_spin_unlock_irqrestore(&data->lock, flags);
}
static void pca954x_irq_unmask(struct irq_data *idata)
@@ -279,13 +279,13 @@ static void pca954x_irq_unmask(struct irq_data *idata)
unsigned int pos = idata->hwirq;
unsigned long flags;
- spin_lock_irqsave(&data->lock, flags);
+ raw_spin_lock_irqsave(&data->lock, flags);
if (!data->irq_mask)
enable_irq(data->client->irq);
data->irq_mask |= BIT(pos);
- spin_unlock_irqrestore(&data->lock, flags);
+ raw_spin_unlock_irqrestore(&data->lock, flags);
}
static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type)
@@ -311,7 +311,7 @@ static int pca954x_irq_setup(struct i2c_mux_core *muxc)
if (!data->chip->has_irq || client->irq <= 0)
return 0;
- spin_lock_init(&data->lock);
+ raw_spin_lock_init(&data->lock);
data->irq = irq_domain_add_linear(client->dev.of_node,
data->chip->nchans,
--
2.11.1
The sunxi pinctrl driver currently implement an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 26 +++++++++++++-------------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 +-
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 60e6e36c4a7e..58774acfc814 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -581,11 +581,11 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
return -ENOTSUPP;
}
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
reg = readl(pctl->membase + offset);
reg &= ~(mask << shift);
writel(reg | val << shift, pctl->membase + offset);
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
} /* for each config */
return 0;
@@ -634,7 +634,7 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
unsigned long flags;
u32 val, mask;
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
pin -= pctl->desc->pin_base;
val = readl(pctl->membase + sunxi_mux_reg(pin));
@@ -642,7 +642,7 @@ static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
writel((val & ~mask) | config << sunxi_mux_offset(pin),
pctl->membase + sunxi_mux_reg(pin));
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static int sunxi_pmx_set_mux(struct pinctrl_dev *pctldev,
@@ -733,7 +733,7 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
unsigned long flags;
u32 regval;
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
regval = readl(pctl->membase + reg);
@@ -744,7 +744,7 @@ static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
writel(regval, pctl->membase + reg);
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
@@ -856,7 +856,7 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
if (type & IRQ_TYPE_LEVEL_MASK)
irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_level_irq_chip,
@@ -869,7 +869,7 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
regval &= ~(IRQ_CFG_IRQ_MASK << index);
writel(regval | (mode << index), pctl->membase + reg);
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
return 0;
}
@@ -893,13 +893,13 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
unsigned long flags;
u32 val;
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
/* Mask the IRQ */
val = readl(pctl->membase + reg);
writel(val & ~(1 << idx), pctl->membase + reg);
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
@@ -910,13 +910,13 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
unsigned long flags;
u32 val;
- spin_lock_irqsave(&pctl->lock, flags);
+ raw_spin_lock_irqsave(&pctl->lock, flags);
/* Unmask the IRQ */
val = readl(pctl->membase + reg);
writel(val | (1 << idx), pctl->membase + reg);
- spin_unlock_irqrestore(&pctl->lock, flags);
+ raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
@@ -1253,7 +1253,7 @@ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
return -ENOMEM;
platform_set_drvdata(pdev, pctl);
- spin_lock_init(&pctl->lock);
+ raw_spin_lock_init(&pctl->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctl->membase = devm_ioremap_resource(&pdev->dev, res);
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index e1aedd260b2e..a9d315a1256c 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -134,7 +134,7 @@ struct sunxi_pinctrl {
unsigned ngroups;
int *irq;
unsigned *irq_array;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct pinctrl_dev *pctl_dev;
unsigned long variant;
};
--
2.11.1
The 104-dio-48e gpio driver currently implements an irq_chip for
handling interrupts; due to how irq_chip handling is done, it's
necessary for the irq_chip methods to be invoked from hardirq context,
even on a a real-time kernel. Because the spinlock_t type becomes a
"sleeping" spinlock w/ RT kernels, it is not suitable to be used with
irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-104-dio-48e.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
index 17bd2ab4ebe2..61b50c40b87b 100644
--- a/drivers/gpio/gpio-104-dio-48e.c
+++ b/drivers/gpio/gpio-104-dio-48e.c
@@ -55,7 +55,7 @@ struct dio48e_gpio {
unsigned char io_state[6];
unsigned char out_state[6];
unsigned char control[2];
- spinlock_t lock;
+ raw_spinlock_t lock;
unsigned base;
unsigned char irq_mask;
};
@@ -78,7 +78,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned control;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* Check if configuring Port C */
if (io_port == 2 || io_port == 5) {
@@ -103,7 +103,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
control &= ~BIT(7);
outb(control, control_addr);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return 0;
}
@@ -120,7 +120,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
unsigned long flags;
unsigned control;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* Check if configuring Port C */
if (io_port == 2 || io_port == 5) {
@@ -153,7 +153,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
control &= ~BIT(7);
outb(control, control_addr);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return 0;
}
@@ -167,17 +167,17 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned port_state;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* ensure that GPIO is set for input */
if (!(dio48egpio->io_state[port] & mask)) {
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return -EINVAL;
}
port_state = inb(dio48egpio->base + in_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
return !!(port_state & mask);
}
@@ -190,7 +190,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
const unsigned out_port = (port > 2) ? port + 1 : port;
unsigned long flags;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (value)
dio48egpio->out_state[port] |= mask;
@@ -199,7 +199,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
@@ -225,14 +225,14 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
out_port = (port > 2) ? port + 1 : port;
bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
/* update output state data and set device gpio register */
dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
dio48egpio->out_state[port] |= bitmask;
outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
/* prepare for next gpio register set */
mask[BIT_WORD(i)] >>= gpio_reg_size;
@@ -255,7 +255,7 @@ static void dio48e_irq_mask(struct irq_data *data)
if (offset != 19 && offset != 43)
return;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (offset == 19)
dio48egpio->irq_mask &= ~BIT(0);
@@ -266,7 +266,7 @@ static void dio48e_irq_mask(struct irq_data *data)
/* disable interrupts */
inb(dio48egpio->base + 0xB);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static void dio48e_irq_unmask(struct irq_data *data)
@@ -280,7 +280,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
if (offset != 19 && offset != 43)
return;
- spin_lock_irqsave(&dio48egpio->lock, flags);
+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
if (!dio48egpio->irq_mask) {
/* enable interrupts */
@@ -293,7 +293,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
else
dio48egpio->irq_mask |= BIT(1);
- spin_unlock_irqrestore(&dio48egpio->lock, flags);
+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
}
static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
@@ -329,11 +329,11 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
generic_handle_irq(irq_find_mapping(chip->irqdomain,
19 + gpio*24));
- spin_lock(&dio48egpio->lock);
+ raw_spin_lock(&dio48egpio->lock);
outb(0x00, dio48egpio->base + 0xF);
- spin_unlock(&dio48egpio->lock);
+ raw_spin_unlock(&dio48egpio->lock);
return IRQ_HANDLED;
}
@@ -388,7 +388,7 @@ static int dio48e_probe(struct device *dev, unsigned int id)
dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
dio48egpio->base = base[id];
- spin_lock_init(&dio48egpio->lock);
+ raw_spin_lock_init(&dio48egpio->lock);
err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
if (err) {
--
2.11.1
The sirf atlas7 pinctrl drivers currently implement an irq_chip for
handling interrupts; due to how irq_chip handling is done, it's
necessary for the irq_chip methods to be invoked from hardirq context,
even on a a real-time kernel. Because the spinlock_t type becomes a
"sleeping" spinlock w/ RT kernels, it is not suitable to be used with
irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/pinctrl/sirf/pinctrl-atlas7.c | 44 +++++++++++++++++------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c
index 600d6427a978..1efa315a7dbe 100644
--- a/drivers/pinctrl/sirf/pinctrl-atlas7.c
+++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c
@@ -352,7 +352,7 @@ struct atlas7_gpio_chip {
void __iomem *reg;
struct clk *clk;
int nbank;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct gpio_chip chip;
struct atlas7_gpio_bank banks[0];
};
@@ -5650,13 +5650,13 @@ static void atlas7_gpio_irq_ack(struct irq_data *d)
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
/* clear interrupt status */
writel(val, ctrl_reg);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static void __atlas7_gpio_irq_mask(struct atlas7_gpio_chip *a7gc, int idx)
@@ -5681,11 +5681,11 @@ static void atlas7_gpio_irq_mask(struct irq_data *d)
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(gc);
unsigned long flags;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_irq_mask(a7gc, d->hwirq);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static void atlas7_gpio_irq_unmask(struct irq_data *d)
@@ -5701,14 +5701,14 @@ static void atlas7_gpio_irq_unmask(struct irq_data *d)
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
val &= ~ATLAS7_GPIO_CTL_INTR_STATUS_MASK;
val |= ATLAS7_GPIO_CTL_INTR_EN_MASK;
writel(val, ctrl_reg);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static int atlas7_gpio_irq_type(struct irq_data *d,
@@ -5725,7 +5725,7 @@ static int atlas7_gpio_irq_type(struct irq_data *d,
pin_in_bank = d->hwirq - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ctrl_reg);
val &= ~(ATLAS7_GPIO_CTL_INTR_STATUS_MASK |
@@ -5768,7 +5768,7 @@ static int atlas7_gpio_irq_type(struct irq_data *d,
writel(val, ctrl_reg);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@@ -5863,7 +5863,7 @@ static int atlas7_gpio_request(struct gpio_chip *chip,
if (pinctrl_request_gpio(chip->base + gpio))
return -ENODEV;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
/*
* default status:
@@ -5872,7 +5872,7 @@ static int atlas7_gpio_request(struct gpio_chip *chip,
__atlas7_gpio_set_input(a7gc, gpio);
__atlas7_gpio_irq_mask(a7gc, gpio);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@@ -5883,12 +5883,12 @@ static void atlas7_gpio_free(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_irq_mask(a7gc, gpio);
__atlas7_gpio_set_input(a7gc, gpio);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
pinctrl_free_gpio(chip->base + gpio);
}
@@ -5899,11 +5899,11 @@ static int atlas7_gpio_direction_input(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_set_input(a7gc, gpio);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@@ -5936,11 +5936,11 @@ static int atlas7_gpio_direction_output(struct gpio_chip *chip,
struct atlas7_gpio_chip *a7gc = gpiochip_get_data(chip);
unsigned long flags;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
__atlas7_gpio_set_output(a7gc, gpio, value);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return 0;
}
@@ -5956,11 +5956,11 @@ static int atlas7_gpio_get_value(struct gpio_chip *chip,
bank = atlas7_gpio_to_bank(a7gc, gpio);
pin_in_bank = gpio - bank->gpio_offset;
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
val = readl(ATLAS7_GPIO_CTRL(bank, pin_in_bank));
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
return !!(val & ATLAS7_GPIO_CTL_DATAIN_MASK);
}
@@ -5978,7 +5978,7 @@ static void atlas7_gpio_set_value(struct gpio_chip *chip,
pin_in_bank = gpio - bank->gpio_offset;
ctrl_reg = ATLAS7_GPIO_CTRL(bank, pin_in_bank);
- spin_lock_irqsave(&a7gc->lock, flags);
+ raw_spin_lock_irqsave(&a7gc->lock, flags);
ctrl = readl(ctrl_reg);
if (value)
@@ -5987,7 +5987,7 @@ static void atlas7_gpio_set_value(struct gpio_chip *chip,
ctrl &= ~ATLAS7_GPIO_CTL_DATAOUT_MASK;
writel(ctrl, ctrl_reg);
- spin_unlock_irqrestore(&a7gc->lock, flags);
+ raw_spin_unlock_irqrestore(&a7gc->lock, flags);
}
static const struct of_device_id atlas7_gpio_ids[] = {
@@ -6036,7 +6036,7 @@ static int atlas7_gpio_probe(struct platform_device *pdev)
}
a7gc->nbank = nbank;
- spin_lock_init(&a7gc->lock);
+ raw_spin_lock_init(&a7gc->lock);
/* Setup GPIO Chip */
chip = &a7gc->chip;
--
2.11.1
The mpc52xx_gpt code currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 52 +++++++++++++++----------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 22645a7c6b8a..18c1383717f2 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -90,7 +90,7 @@ struct mpc52xx_gpt_priv {
struct list_head list; /* List of all GPT devices */
struct device *dev;
struct mpc52xx_gpt __iomem *regs;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct irq_domain *irqhost;
u32 ipb_freq;
u8 wdt_mode;
@@ -141,9 +141,9 @@ static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
unsigned long flags;
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
}
static void mpc52xx_gpt_irq_mask(struct irq_data *d)
@@ -151,9 +151,9 @@ static void mpc52xx_gpt_irq_mask(struct irq_data *d)
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
unsigned long flags;
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
}
static void mpc52xx_gpt_irq_ack(struct irq_data *d)
@@ -171,14 +171,14 @@ static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
if (flow_type & IRQF_TRIGGER_RISING)
reg |= MPC52xx_GPT_MODE_ICT_RISING;
if (flow_type & IRQF_TRIGGER_FALLING)
reg |= MPC52xx_GPT_MODE_ICT_FALLING;
out_be32(&gpt->regs->mode, reg);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
}
@@ -264,11 +264,11 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
/* If the GPT is currently disabled, then change it to be in Input
* Capture mode. If the mode is non-zero, then the pin could be
* already in use for something. */
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
mode = in_be32(&gpt->regs->mode);
if ((mode & MPC52xx_GPT_MODE_MS_MASK) == 0)
out_be32(&gpt->regs->mode, mode | MPC52xx_GPT_MODE_MS_IC);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
}
@@ -295,9 +295,9 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
}
static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
@@ -307,9 +307,9 @@ static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
}
@@ -436,16 +436,16 @@ static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
}
/* Set and enable the timer, reject an attempt to use a wdt as gpt */
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
if (as_wdt)
gpt->wdt_mode |= MPC52xx_GPT_IS_WDT;
else if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return -EBUSY;
}
out_be32(&gpt->regs->count, prescale << 16 | clocks);
clrsetbits_be32(&gpt->regs->mode, clear, set);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
}
@@ -476,14 +476,14 @@ int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt)
unsigned long flags;
/* reject the operation if the timer is used as watchdog (gpt 0 only) */
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
if ((gpt->wdt_mode & MPC52xx_GPT_IS_WDT) != 0) {
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return -EBUSY;
}
clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_COUNTER_ENABLE);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
return 0;
}
EXPORT_SYMBOL(mpc52xx_gpt_stop_timer);
@@ -500,9 +500,9 @@ u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt)
u64 prescale;
unsigned long flags;
- spin_lock_irqsave(&gpt->lock, flags);
+ raw_spin_lock_irqsave(&gpt->lock, flags);
period = in_be32(&gpt->regs->count);
- spin_unlock_irqrestore(&gpt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt->lock, flags);
prescale = period >> 16;
period &= 0xffff;
@@ -532,9 +532,9 @@ static inline void mpc52xx_gpt_wdt_ping(struct mpc52xx_gpt_priv *gpt_wdt)
{
unsigned long flags;
- spin_lock_irqsave(&gpt_wdt->lock, flags);
+ raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
out_8((u8 *) &gpt_wdt->regs->mode, MPC52xx_GPT_MODE_WDT_PING);
- spin_unlock_irqrestore(&gpt_wdt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
}
/* wdt misc device api */
@@ -638,11 +638,11 @@ static int mpc52xx_wdt_release(struct inode *inode, struct file *file)
struct mpc52xx_gpt_priv *gpt_wdt = file->private_data;
unsigned long flags;
- spin_lock_irqsave(&gpt_wdt->lock, flags);
+ raw_spin_lock_irqsave(&gpt_wdt->lock, flags);
clrbits32(&gpt_wdt->regs->mode,
MPC52xx_GPT_MODE_COUNTER_ENABLE | MPC52xx_GPT_MODE_WDT_EN);
gpt_wdt->wdt_mode &= ~MPC52xx_GPT_IS_WDT;
- spin_unlock_irqrestore(&gpt_wdt->lock, flags);
+ raw_spin_unlock_irqrestore(&gpt_wdt->lock, flags);
#endif
clear_bit(0, &wdt_is_active);
return 0;
@@ -723,7 +723,7 @@ static int mpc52xx_gpt_probe(struct platform_device *ofdev)
if (!gpt)
return -ENOMEM;
- spin_lock_init(&gpt->lock);
+ raw_spin_lock_init(&gpt->lock);
gpt->dev = &ofdev->dev;
gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
gpt->regs = of_iomap(ofdev->dev.of_node, 0);
--
2.11.1
The pl061 gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-pl061.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 0a6bfd2b06e5..3d3d6b6645a7 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -50,7 +50,7 @@ struct pl061_context_save_regs {
#endif
struct pl061 {
- spinlock_t lock;
+ raw_spinlock_t lock;
void __iomem *base;
struct gpio_chip gc;
@@ -74,11 +74,11 @@ static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
unsigned long flags;
unsigned char gpiodir;
- spin_lock_irqsave(&pl061->lock, flags);
+ raw_spin_lock_irqsave(&pl061->lock, flags);
gpiodir = readb(pl061->base + GPIODIR);
gpiodir &= ~(BIT(offset));
writeb(gpiodir, pl061->base + GPIODIR);
- spin_unlock_irqrestore(&pl061->lock, flags);
+ raw_spin_unlock_irqrestore(&pl061->lock, flags);
return 0;
}
@@ -90,7 +90,7 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
unsigned long flags;
unsigned char gpiodir;
- spin_lock_irqsave(&pl061->lock, flags);
+ raw_spin_lock_irqsave(&pl061->lock, flags);
writeb(!!value << offset, pl061->base + (BIT(offset + 2)));
gpiodir = readb(pl061->base + GPIODIR);
gpiodir |= BIT(offset);
@@ -101,7 +101,7 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
* a gpio pin before configuring it in OUT mode.
*/
writeb(!!value << offset, pl061->base + (BIT(offset + 2)));
- spin_unlock_irqrestore(&pl061->lock, flags);
+ raw_spin_unlock_irqrestore(&pl061->lock, flags);
return 0;
}
@@ -143,7 +143,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
}
- spin_lock_irqsave(&pl061->lock, flags);
+ raw_spin_lock_irqsave(&pl061->lock, flags);
gpioiev = readb(pl061->base + GPIOIEV);
gpiois = readb(pl061->base + GPIOIS);
@@ -203,7 +203,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
writeb(gpioibe, pl061->base + GPIOIBE);
writeb(gpioiev, pl061->base + GPIOIEV);
- spin_unlock_irqrestore(&pl061->lock, flags);
+ raw_spin_unlock_irqrestore(&pl061->lock, flags);
return 0;
}
@@ -235,10 +235,10 @@ static void pl061_irq_mask(struct irq_data *d)
u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 gpioie;
- spin_lock(&pl061->lock);
+ raw_spin_lock(&pl061->lock);
gpioie = readb(pl061->base + GPIOIE) & ~mask;
writeb(gpioie, pl061->base + GPIOIE);
- spin_unlock(&pl061->lock);
+ raw_spin_unlock(&pl061->lock);
}
static void pl061_irq_unmask(struct irq_data *d)
@@ -248,10 +248,10 @@ static void pl061_irq_unmask(struct irq_data *d)
u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 gpioie;
- spin_lock(&pl061->lock);
+ raw_spin_lock(&pl061->lock);
gpioie = readb(pl061->base + GPIOIE) | mask;
writeb(gpioie, pl061->base + GPIOIE);
- spin_unlock(&pl061->lock);
+ raw_spin_unlock(&pl061->lock);
}
/**
@@ -268,9 +268,9 @@ static void pl061_irq_ack(struct irq_data *d)
struct pl061 *pl061 = gpiochip_get_data(gc);
u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR);
- spin_lock(&pl061->lock);
+ raw_spin_lock(&pl061->lock);
writeb(mask, pl061->base + GPIOIC);
- spin_unlock(&pl061->lock);
+ raw_spin_unlock(&pl061->lock);
}
static int pl061_irq_set_wake(struct irq_data *d, unsigned int state)
@@ -304,7 +304,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
if (IS_ERR(pl061->base))
return PTR_ERR(pl061->base);
- spin_lock_init(&pl061->lock);
+ raw_spin_lock_init(&pl061->lock);
if (of_property_read_bool(dev->of_node, "gpio-ranges")) {
pl061->gc.request = gpiochip_generic_request;
pl061->gc.free = gpiochip_generic_free;
--
2.11.1
The alpha/marvel code currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
arch/alpha/include/asm/core_marvel.h | 2 +-
arch/alpha/kernel/sys_marvel.c | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/alpha/include/asm/core_marvel.h b/arch/alpha/include/asm/core_marvel.h
index dad300fa14ce..8dcf9dbda618 100644
--- a/arch/alpha/include/asm/core_marvel.h
+++ b/arch/alpha/include/asm/core_marvel.h
@@ -312,7 +312,7 @@ struct io7 {
io7_port7_csrs *csrs;
struct io7_port ports[IO7_NUM_PORTS];
- spinlock_t irq_lock;
+ raw_spinlock_t irq_lock;
};
#ifndef __EXTERN_INLINE
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 24e41bd7d3c9..3e533920371f 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -115,11 +115,11 @@ io7_enable_irq(struct irq_data *d)
return;
}
- spin_lock(&io7->irq_lock);
+ raw_spin_lock(&io7->irq_lock);
*ctl |= 1UL << 24;
mb();
*ctl;
- spin_unlock(&io7->irq_lock);
+ raw_spin_unlock(&io7->irq_lock);
}
static void
@@ -136,11 +136,11 @@ io7_disable_irq(struct irq_data *d)
return;
}
- spin_lock(&io7->irq_lock);
+ raw_spin_lock(&io7->irq_lock);
*ctl &= ~(1UL << 24);
mb();
*ctl;
- spin_unlock(&io7->irq_lock);
+ raw_spin_unlock(&io7->irq_lock);
}
static void
@@ -263,7 +263,7 @@ init_io7_irqs(struct io7 *io7,
*/
printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid);
- spin_lock(&io7->irq_lock);
+ raw_spin_lock(&io7->irq_lock);
/* set up the error irqs */
io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, boot_cpuid);
@@ -295,7 +295,7 @@ init_io7_irqs(struct io7 *io7,
for (i = 0; i < 16; ++i)
init_one_io7_msi(io7, i, boot_cpuid);
- spin_unlock(&io7->irq_lock);
+ raw_spin_unlock(&io7->irq_lock);
}
static void __init
--
2.11.1
The t7l66xb mfd driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/mfd/t7l66xb.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 94bd89cb1f06..22c811396edc 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -69,7 +69,7 @@ static const struct resource t7l66xb_mmc_resources[] = {
struct t7l66xb {
void __iomem *scr;
/* Lock to protect registers requiring read/modify/write ops. */
- spinlock_t lock;
+ raw_spinlock_t lock;
struct resource rscr;
struct clk *clk48m;
@@ -89,13 +89,13 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc)
clk_prepare_enable(t7l66xb->clk32k);
- spin_lock_irqsave(&t7l66xb->lock, flags);
+ raw_spin_lock_irqsave(&t7l66xb->lock, flags);
dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
dev_ctl |= SCR_DEV_CTL_MMC;
tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
- spin_unlock_irqrestore(&t7l66xb->lock, flags);
+ raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0,
t7l66xb_mmc_resources[0].start & 0xfffe);
@@ -110,13 +110,13 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
unsigned long flags;
u8 dev_ctl;
- spin_lock_irqsave(&t7l66xb->lock, flags);
+ raw_spin_lock_irqsave(&t7l66xb->lock, flags);
dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
dev_ctl &= ~SCR_DEV_CTL_MMC;
tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
- spin_unlock_irqrestore(&t7l66xb->lock, flags);
+ raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
clk_disable_unprepare(t7l66xb->clk32k);
@@ -206,11 +206,11 @@ static void t7l66xb_irq_mask(struct irq_data *data)
unsigned long flags;
u8 imr;
- spin_lock_irqsave(&t7l66xb->lock, flags);
+ raw_spin_lock_irqsave(&t7l66xb->lock, flags);
imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
imr |= 1 << (data->irq - t7l66xb->irq_base);
tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
- spin_unlock_irqrestore(&t7l66xb->lock, flags);
+ raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
}
static void t7l66xb_irq_unmask(struct irq_data *data)
@@ -219,11 +219,11 @@ static void t7l66xb_irq_unmask(struct irq_data *data)
unsigned long flags;
u8 imr;
- spin_lock_irqsave(&t7l66xb->lock, flags);
+ raw_spin_lock_irqsave(&t7l66xb->lock, flags);
imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
imr &= ~(1 << (data->irq - t7l66xb->irq_base));
tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
- spin_unlock_irqrestore(&t7l66xb->lock, flags);
+ raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
}
static struct irq_chip t7l66xb_chip = {
@@ -321,7 +321,7 @@ static int t7l66xb_probe(struct platform_device *dev)
if (!t7l66xb)
return -ENOMEM;
- spin_lock_init(&t7l66xb->lock);
+ raw_spin_lock_init(&t7l66xb->lock);
platform_set_drvdata(dev, t7l66xb);
--
2.11.1
The amd pinctrl drivers currently implement an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/pinctrl/pinctrl-amd.c | 66 +++++++++++++++++++++----------------------
drivers/pinctrl/pinctrl-amd.h | 2 +-
2 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index d69e357a7a98..043ac9bcbccb 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -41,11 +41,11 @@ static int amd_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
u32 pin_reg;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
pin_reg &= ~BIT(OUTPUT_ENABLE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
@@ -57,7 +57,7 @@ static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
pin_reg |= BIT(OUTPUT_ENABLE_OFF);
if (value)
@@ -65,7 +65,7 @@ static int amd_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return 0;
}
@@ -76,9 +76,9 @@ static int amd_gpio_get_value(struct gpio_chip *gc, unsigned offset)
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return !!(pin_reg & BIT(PIN_STS_OFF));
}
@@ -89,14 +89,14 @@ static void amd_gpio_set_value(struct gpio_chip *gc, unsigned offset, int value)
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (value)
pin_reg |= BIT(OUTPUT_VALUE_OFF);
else
pin_reg &= ~BIT(OUTPUT_VALUE_OFF);
writel(pin_reg, gpio_dev->base + offset * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
@@ -108,7 +108,7 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
unsigned long flags;
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + offset * 4);
if (debounce) {
@@ -159,7 +159,7 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset,
pin_reg &= ~DB_CNTRl_MASK;
}
writel(pin_reg, gpio_dev->base + offset * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@@ -224,9 +224,9 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc)
}
for (; i < pin_num; i++) {
seq_printf(s, "pin%d\t", i);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + i * 4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
if (pin_reg & BIT(INTERRUPT_ENABLE_OFF)) {
interrupt_enable = "interrupt is enabled|";
@@ -331,12 +331,12 @@ static void amd_gpio_irq_enable(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg |= BIT(INTERRUPT_ENABLE_OFF);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_disable(struct irq_data *d)
@@ -346,12 +346,12 @@ static void amd_gpio_irq_disable(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_ENABLE_OFF);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_mask(struct irq_data *d)
@@ -361,11 +361,11 @@ static void amd_gpio_irq_mask(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg &= ~BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_unmask(struct irq_data *d)
@@ -375,11 +375,11 @@ static void amd_gpio_irq_unmask(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
pin_reg |= BIT(INTERRUPT_MASK_OFF);
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static void amd_gpio_irq_eoi(struct irq_data *d)
@@ -389,11 +389,11 @@ static void amd_gpio_irq_eoi(struct irq_data *d)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@@ -404,7 +404,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
/* Ignore the settings coming from the client and
@@ -469,7 +469,7 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
pin_reg |= CLR_INTR_STAT << INTERRUPT_STS_OFF;
writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@@ -511,14 +511,14 @@ static void amd_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(chip, desc);
/*enable GPIO interrupt again*/
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
reg64 = reg;
reg64 = reg64 << 32;
reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
reg64 |= reg;
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
/*
* first 46 bits indicates interrupt status.
@@ -546,11 +546,11 @@ static void amd_gpio_irq_handler(struct irq_desc *desc)
if (handled == 0)
handle_bad_irq(desc);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
reg |= EOI_MASK;
writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
chained_irq_exit(chip, desc);
}
@@ -602,9 +602,9 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev,
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(*config);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + pin*4);
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
switch (param) {
case PIN_CONFIG_INPUT_DEBOUNCE:
arg = pin_reg & DB_TMR_OUT_MASK;
@@ -644,7 +644,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
enum pin_config_param param;
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
- spin_lock_irqsave(&gpio_dev->lock, flags);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
@@ -683,7 +683,7 @@ static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
writel(pin_reg, gpio_dev->base + pin*4);
}
- spin_unlock_irqrestore(&gpio_dev->lock, flags);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
return ret;
}
@@ -751,7 +751,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
if (!gpio_dev)
return -ENOMEM;
- spin_lock_init(&gpio_dev->lock);
+ raw_spin_lock_init(&gpio_dev->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h
index c03f77822069..5b1cb965c767 100644
--- a/drivers/pinctrl/pinctrl-amd.h
+++ b/drivers/pinctrl/pinctrl-amd.h
@@ -87,7 +87,7 @@ struct amd_function {
};
struct amd_gpio {
- spinlock_t lock;
+ raw_spinlock_t lock;
void __iomem *base;
const struct amd_pingroup *groups;
--
2.11.1
The asic3 mfd driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/mfd/asic3.c | 56 ++++++++++++++++++++++++++---------------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 0413c8159551..cf2e25ab2940 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -78,7 +78,7 @@ struct asic3 {
unsigned int bus_shift;
unsigned int irq_nr;
unsigned int irq_base;
- spinlock_t lock;
+ raw_spinlock_t lock;
u16 irq_bothedge[4];
struct gpio_chip gpio;
struct device *dev;
@@ -108,14 +108,14 @@ static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set)
unsigned long flags;
u32 val;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
val = asic3_read_register(asic, reg);
if (set)
val |= bits;
else
val &= ~bits;
asic3_write_register(asic, reg, val);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
/* IRQs */
@@ -129,13 +129,13 @@ static void asic3_irq_flip_edge(struct asic3 *asic,
u16 edge;
unsigned long flags;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
edge = asic3_read_register(asic,
base + ASIC3_GPIO_EDGE_TRIGGER);
edge ^= bit;
asic3_write_register(asic,
base + ASIC3_GPIO_EDGE_TRIGGER, edge);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static void asic3_irq_demux(struct irq_desc *desc)
@@ -151,10 +151,10 @@ static void asic3_irq_demux(struct irq_desc *desc)
u32 status;
int bank;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
status = asic3_read_register(asic,
ASIC3_OFFSET(INTR, P_INT_STAT));
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
/* Check all ten register bits */
if ((status & 0x3ff) == 0)
@@ -167,7 +167,7 @@ static void asic3_irq_demux(struct irq_desc *desc)
base = ASIC3_GPIO_A_BASE
+ bank * ASIC3_GPIO_BASE_INCR;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
istat = asic3_read_register(asic,
base +
ASIC3_GPIO_INT_STATUS);
@@ -175,7 +175,7 @@ static void asic3_irq_demux(struct irq_desc *desc)
asic3_write_register(asic,
base +
ASIC3_GPIO_INT_STATUS, 0);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) {
int bit = (1 << i);
@@ -230,11 +230,11 @@ static void asic3_mask_gpio_irq(struct irq_data *data)
bank = asic3_irq_to_bank(asic, data->irq);
index = asic3_irq_to_index(asic, data->irq);
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
val |= 1 << index;
asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static void asic3_mask_irq(struct irq_data *data)
@@ -243,7 +243,7 @@ static void asic3_mask_irq(struct irq_data *data)
int regval;
unsigned long flags;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
regval = asic3_read_register(asic,
ASIC3_INTR_BASE +
ASIC3_INTR_INT_MASK);
@@ -255,7 +255,7 @@ static void asic3_mask_irq(struct irq_data *data)
ASIC3_INTR_BASE +
ASIC3_INTR_INT_MASK,
regval);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static void asic3_unmask_gpio_irq(struct irq_data *data)
@@ -267,11 +267,11 @@ static void asic3_unmask_gpio_irq(struct irq_data *data)
bank = asic3_irq_to_bank(asic, data->irq);
index = asic3_irq_to_index(asic, data->irq);
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
val &= ~(1 << index);
asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static void asic3_unmask_irq(struct irq_data *data)
@@ -280,7 +280,7 @@ static void asic3_unmask_irq(struct irq_data *data)
int regval;
unsigned long flags;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
regval = asic3_read_register(asic,
ASIC3_INTR_BASE +
ASIC3_INTR_INT_MASK);
@@ -292,7 +292,7 @@ static void asic3_unmask_irq(struct irq_data *data)
ASIC3_INTR_BASE +
ASIC3_INTR_INT_MASK,
regval);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type)
@@ -306,7 +306,7 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type)
index = asic3_irq_to_index(asic, data->irq);
bit = 1<<index;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
level = asic3_read_register(asic,
bank + ASIC3_GPIO_LEVEL_TRIGGER);
edge = asic3_read_register(asic,
@@ -348,7 +348,7 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type)
edge);
asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE,
trigger);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
return 0;
}
@@ -455,7 +455,7 @@ static int asic3_gpio_direction(struct gpio_chip *chip,
return -EINVAL;
}
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION);
@@ -467,7 +467,7 @@ static int asic3_gpio_direction(struct gpio_chip *chip,
asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
return 0;
@@ -524,7 +524,7 @@ static void asic3_gpio_set(struct gpio_chip *chip,
mask = ASIC3_GPIO_TO_MASK(offset);
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT);
@@ -535,7 +535,7 @@ static void asic3_gpio_set(struct gpio_chip *chip,
asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg);
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -611,13 +611,13 @@ static void asic3_clk_enable(struct asic3 *asic, struct asic3_clk *clk)
unsigned long flags;
u32 cdex;
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
if (clk->enabled++ == 0) {
cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX));
cdex |= clk->cdex;
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
}
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
@@ -627,13 +627,13 @@ static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk)
WARN_ON(clk->enabled == 0);
- spin_lock_irqsave(&asic->lock, flags);
+ raw_spin_lock_irqsave(&asic->lock, flags);
if (--clk->enabled == 0) {
cdex = asic3_read_register(asic, ASIC3_OFFSET(CLOCK, CDEX));
cdex &= ~clk->cdex;
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, CDEX), cdex);
}
- spin_unlock_irqrestore(&asic->lock, flags);
+ raw_spin_unlock_irqrestore(&asic->lock, flags);
}
/* MFD cells (SPI, PWM, LED, DS1WM, MMC) */
@@ -963,7 +963,7 @@ static int __init asic3_probe(struct platform_device *pdev)
if (!asic)
return -ENOMEM;
- spin_lock_init(&asic->lock);
+ raw_spin_lock_init(&asic->lock);
platform_set_drvdata(pdev, asic);
asic->dev = &pdev->dev;
--
2.11.1
The bcm-kona gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-bcm-kona.c | 48 ++++++++++++++++++++++----------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
index 41d0ac142580..dfcf56ee3c61 100644
--- a/drivers/gpio/gpio-bcm-kona.c
+++ b/drivers/gpio/gpio-bcm-kona.c
@@ -67,7 +67,7 @@
struct bcm_kona_gpio {
void __iomem *reg_base;
int num_bank;
- spinlock_t lock;
+ raw_spinlock_t lock;
struct gpio_chip gpio_chip;
struct irq_domain *irq_domain;
struct bcm_kona_gpio_bank *banks;
@@ -95,13 +95,13 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,
unsigned long flags;
int bank_id = GPIO_BANK(gpio);
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
val |= BIT(gpio);
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
@@ -111,13 +111,13 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
unsigned long flags;
int bank_id = GPIO_BANK(gpio);
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
val &= ~BIT(gpio);
bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio)
@@ -141,7 +141,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
kona_gpio = gpiochip_get_data(chip);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
/* this function only applies to output pin */
if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN)
@@ -154,7 +154,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
writel(val, reg_base + reg_offset);
out:
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
@@ -168,7 +168,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
kona_gpio = gpiochip_get_data(chip);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN)
reg_offset = GPIO_IN_STATUS(bank_id);
@@ -178,7 +178,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
/* read the GPIO bank status */
val = readl(reg_base + reg_offset);
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
/* return the specified bit status */
return !!(val & BIT(bit));
@@ -208,14 +208,14 @@ static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
kona_gpio = gpiochip_get_data(chip);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_CONTROL(gpio));
val &= ~GPIO_GPCTR0_IOTR_MASK;
val |= GPIO_GPCTR0_IOTR_CMD_INPUT;
writel(val, reg_base + GPIO_CONTROL(gpio));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
return 0;
}
@@ -232,7 +232,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip,
kona_gpio = gpiochip_get_data(chip);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_CONTROL(gpio));
val &= ~GPIO_GPCTR0_IOTR_MASK;
@@ -244,7 +244,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip,
val |= BIT(bit);
writel(val, reg_base + reg_offset);
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
return 0;
}
@@ -288,7 +288,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio,
}
/* spin lock for read-modify-write of the GPIO register */
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_CONTROL(gpio));
val &= ~GPIO_GPCTR0_DBR_MASK;
@@ -303,7 +303,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio,
writel(val, reg_base + GPIO_CONTROL(gpio));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
return 0;
}
@@ -347,13 +347,13 @@ static void bcm_kona_gpio_irq_ack(struct irq_data *d)
kona_gpio = irq_data_get_irq_chip_data(d);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_INT_STATUS(bank_id));
val |= BIT(bit);
writel(val, reg_base + GPIO_INT_STATUS(bank_id));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static void bcm_kona_gpio_irq_mask(struct irq_data *d)
@@ -368,13 +368,13 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d)
kona_gpio = irq_data_get_irq_chip_data(d);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_INT_MASK(bank_id));
val |= BIT(bit);
writel(val, reg_base + GPIO_INT_MASK(bank_id));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static void bcm_kona_gpio_irq_unmask(struct irq_data *d)
@@ -389,13 +389,13 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d)
kona_gpio = irq_data_get_irq_chip_data(d);
reg_base = kona_gpio->reg_base;
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_INT_MSKCLR(bank_id));
val |= BIT(bit);
writel(val, reg_base + GPIO_INT_MSKCLR(bank_id));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
}
static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type)
@@ -431,14 +431,14 @@ static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- spin_lock_irqsave(&kona_gpio->lock, flags);
+ raw_spin_lock_irqsave(&kona_gpio->lock, flags);
val = readl(reg_base + GPIO_CONTROL(gpio));
val &= ~GPIO_GPCTR0_ITR_MASK;
val |= lvl_type << GPIO_GPCTR0_ITR_SHIFT;
writel(val, reg_base + GPIO_CONTROL(gpio));
- spin_unlock_irqrestore(&kona_gpio->lock, flags);
+ raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
return 0;
}
@@ -655,7 +655,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
bank);
}
- spin_lock_init(&kona_gpio->lock);
+ raw_spin_lock_init(&kona_gpio->lock);
return 0;
--
2.11.1
The etraxfs gpio driver currently implements an irq_chip for handling
interrupts; due to how irq_chip handling is done, it's necessary for the
irq_chip methods to be invoked from hardirq context, even on a a
real-time kernel. Because the spinlock_t type becomes a "sleeping"
spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
A quick audit of the operations under the lock reveal that they do only
minimal, bounded work, and are therefore safe to do under a raw spinlock.
Signed-off-by: Julia Cartwright <[email protected]>
---
drivers/gpio/gpio-etraxfs.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpio/gpio-etraxfs.c b/drivers/gpio/gpio-etraxfs.c
index a254d5b07b94..14c6aac26780 100644
--- a/drivers/gpio/gpio-etraxfs.c
+++ b/drivers/gpio/gpio-etraxfs.c
@@ -54,7 +54,7 @@
struct etraxfs_gpio_info;
struct etraxfs_gpio_block {
- spinlock_t lock;
+ raw_spinlock_t lock;
u32 mask;
u32 cfg;
u32 pins;
@@ -233,10 +233,10 @@ static void etraxfs_gpio_irq_mask(struct irq_data *d)
struct etraxfs_gpio_block *block = chip->block;
unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
- spin_lock(&block->lock);
+ raw_spin_lock(&block->lock);
block->mask &= ~BIT(grpirq);
writel(block->mask, block->regs + block->info->rw_intr_mask);
- spin_unlock(&block->lock);
+ raw_spin_unlock(&block->lock);
}
static void etraxfs_gpio_irq_unmask(struct irq_data *d)
@@ -246,10 +246,10 @@ static void etraxfs_gpio_irq_unmask(struct irq_data *d)
struct etraxfs_gpio_block *block = chip->block;
unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
- spin_lock(&block->lock);
+ raw_spin_lock(&block->lock);
block->mask |= BIT(grpirq);
writel(block->mask, block->regs + block->info->rw_intr_mask);
- spin_unlock(&block->lock);
+ raw_spin_unlock(&block->lock);
}
static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type)
@@ -280,11 +280,11 @@ static int etraxfs_gpio_irq_set_type(struct irq_data *d, u32 type)
return -EINVAL;
}
- spin_lock(&block->lock);
+ raw_spin_lock(&block->lock);
block->cfg &= ~(0x7 << (grpirq * 3));
block->cfg |= (cfg << (grpirq * 3));
writel(block->cfg, block->regs + block->info->rw_intr_cfg);
- spin_unlock(&block->lock);
+ raw_spin_unlock(&block->lock);
return 0;
}
@@ -297,7 +297,7 @@ static int etraxfs_gpio_irq_request_resources(struct irq_data *d)
unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
int ret = -EBUSY;
- spin_lock(&block->lock);
+ raw_spin_lock(&block->lock);
if (block->group[grpirq])
goto out;
@@ -316,7 +316,7 @@ static int etraxfs_gpio_irq_request_resources(struct irq_data *d)
}
out:
- spin_unlock(&block->lock);
+ raw_spin_unlock(&block->lock);
return ret;
}
@@ -327,10 +327,10 @@ static void etraxfs_gpio_irq_release_resources(struct irq_data *d)
struct etraxfs_gpio_block *block = chip->block;
unsigned int grpirq = etraxfs_gpio_to_group_irq(d->hwirq);
- spin_lock(&block->lock);
+ raw_spin_lock(&block->lock);
block->group[grpirq] = 0;
gpiochip_unlock_as_irq(&chip->gc, d->hwirq);
- spin_unlock(&block->lock);
+ raw_spin_unlock(&block->lock);
}
static struct irq_chip etraxfs_gpio_irq_chip = {
@@ -391,7 +391,7 @@ static int etraxfs_gpio_probe(struct platform_device *pdev)
if (!block)
return -ENOMEM;
- spin_lock_init(&block->lock);
+ raw_spin_lock_init(&block->lock);
block->regs = regs;
block->info = info;
--
2.11.1
On Thu, Mar 09, 2017 at 10:21:52AM -0600, Julia Cartwright wrote:
>The 104-dio-48e gpio driver currently implements an irq_chip for
>handling interrupts; due to how irq_chip handling is done, it's
>necessary for the irq_chip methods to be invoked from hardirq context,
>even on a a real-time kernel. Because the spinlock_t type becomes a
>"sleeping" spinlock w/ RT kernels, it is not suitable to be used with
>irq_chips.
>
>A quick audit of the operations under the lock reveal that they do only
>minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
>Signed-off-by: Julia Cartwright <[email protected]>
Acked-by: William Breathitt Gray <[email protected]>
>---
> drivers/gpio/gpio-104-dio-48e.c | 38 +++++++++++++++++++-------------------
> 1 file changed, 19 insertions(+), 19 deletions(-)
>
>diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
>index 17bd2ab4ebe2..61b50c40b87b 100644
>--- a/drivers/gpio/gpio-104-dio-48e.c
>+++ b/drivers/gpio/gpio-104-dio-48e.c
>@@ -55,7 +55,7 @@ struct dio48e_gpio {
> unsigned char io_state[6];
> unsigned char out_state[6];
> unsigned char control[2];
>- spinlock_t lock;
>+ raw_spinlock_t lock;
> unsigned base;
> unsigned char irq_mask;
> };
>@@ -78,7 +78,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> unsigned long flags;
> unsigned control;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> /* Check if configuring Port C */
> if (io_port == 2 || io_port == 5) {
>@@ -103,7 +103,7 @@ static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> control &= ~BIT(7);
> outb(control, control_addr);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
>
> return 0;
> }
>@@ -120,7 +120,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
> unsigned long flags;
> unsigned control;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> /* Check if configuring Port C */
> if (io_port == 2 || io_port == 5) {
>@@ -153,7 +153,7 @@ static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
> control &= ~BIT(7);
> outb(control, control_addr);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
>
> return 0;
> }
>@@ -167,17 +167,17 @@ static int dio48e_gpio_get(struct gpio_chip *chip, unsigned offset)
> unsigned long flags;
> unsigned port_state;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> /* ensure that GPIO is set for input */
> if (!(dio48egpio->io_state[port] & mask)) {
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
> return -EINVAL;
> }
>
> port_state = inb(dio48egpio->base + in_port);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
>
> return !!(port_state & mask);
> }
>@@ -190,7 +190,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> const unsigned out_port = (port > 2) ? port + 1 : port;
> unsigned long flags;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> if (value)
> dio48egpio->out_state[port] |= mask;
>@@ -199,7 +199,7 @@ static void dio48e_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
>
> outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
> }
>
> static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
>@@ -225,14 +225,14 @@ static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
> out_port = (port > 2) ? port + 1 : port;
> bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> /* update output state data and set device gpio register */
> dio48egpio->out_state[port] &= ~mask[BIT_WORD(i)];
> dio48egpio->out_state[port] |= bitmask;
> outb(dio48egpio->out_state[port], dio48egpio->base + out_port);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
>
> /* prepare for next gpio register set */
> mask[BIT_WORD(i)] >>= gpio_reg_size;
>@@ -255,7 +255,7 @@ static void dio48e_irq_mask(struct irq_data *data)
> if (offset != 19 && offset != 43)
> return;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> if (offset == 19)
> dio48egpio->irq_mask &= ~BIT(0);
>@@ -266,7 +266,7 @@ static void dio48e_irq_mask(struct irq_data *data)
> /* disable interrupts */
> inb(dio48egpio->base + 0xB);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
> }
>
> static void dio48e_irq_unmask(struct irq_data *data)
>@@ -280,7 +280,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
> if (offset != 19 && offset != 43)
> return;
>
>- spin_lock_irqsave(&dio48egpio->lock, flags);
>+ raw_spin_lock_irqsave(&dio48egpio->lock, flags);
>
> if (!dio48egpio->irq_mask) {
> /* enable interrupts */
>@@ -293,7 +293,7 @@ static void dio48e_irq_unmask(struct irq_data *data)
> else
> dio48egpio->irq_mask |= BIT(1);
>
>- spin_unlock_irqrestore(&dio48egpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
> }
>
> static int dio48e_irq_set_type(struct irq_data *data, unsigned flow_type)
>@@ -329,11 +329,11 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
> generic_handle_irq(irq_find_mapping(chip->irqdomain,
> 19 + gpio*24));
>
>- spin_lock(&dio48egpio->lock);
>+ raw_spin_lock(&dio48egpio->lock);
>
> outb(0x00, dio48egpio->base + 0xF);
>
>- spin_unlock(&dio48egpio->lock);
>+ raw_spin_unlock(&dio48egpio->lock);
>
> return IRQ_HANDLED;
> }
>@@ -388,7 +388,7 @@ static int dio48e_probe(struct device *dev, unsigned int id)
> dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
> dio48egpio->base = base[id];
>
>- spin_lock_init(&dio48egpio->lock);
>+ raw_spin_lock_init(&dio48egpio->lock);
>
> err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
> if (err) {
>--
>2.11.1
>
On Thu, Mar 09, 2017 at 10:21:57AM -0600, Julia Cartwright wrote:
>The ws16c48 gpio driver currently implements an irq_chip for handling
>interrupts; due to how irq_chip handling is done, it's necessary for the
>irq_chip methods to be invoked from hardirq context, even on a a
>real-time kernel. Because the spinlock_t type becomes a "sleeping"
>spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
>A quick audit of the operations under the lock reveal that they do only
>minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
>Signed-off-by: Julia Cartwright <[email protected]>
Acked-by: William Breathitt Gray <[email protected]>
>---
> drivers/gpio/gpio-ws16c48.c | 46 ++++++++++++++++++++++-----------------------
> 1 file changed, 23 insertions(+), 23 deletions(-)
>
>diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c
>index 901b5ccb032d..87d63695dfcf 100644
>--- a/drivers/gpio/gpio-ws16c48.c
>+++ b/drivers/gpio/gpio-ws16c48.c
>@@ -51,7 +51,7 @@ struct ws16c48_gpio {
> struct gpio_chip chip;
> unsigned char io_state[6];
> unsigned char out_state[6];
>- spinlock_t lock;
>+ raw_spinlock_t lock;
> unsigned long irq_mask;
> unsigned long flow_mask;
> unsigned base;
>@@ -73,13 +73,13 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> const unsigned mask = BIT(offset % 8);
> unsigned long flags;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> ws16c48gpio->io_state[port] |= mask;
> ws16c48gpio->out_state[port] &= ~mask;
> outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>
> return 0;
> }
>@@ -92,7 +92,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
> const unsigned mask = BIT(offset % 8);
> unsigned long flags;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> ws16c48gpio->io_state[port] &= ~mask;
> if (value)
>@@ -101,7 +101,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
> ws16c48gpio->out_state[port] &= ~mask;
> outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>
> return 0;
> }
>@@ -114,17 +114,17 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
> unsigned long flags;
> unsigned port_state;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> /* ensure that GPIO is set for input */
> if (!(ws16c48gpio->io_state[port] & mask)) {
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> return -EINVAL;
> }
>
> port_state = inb(ws16c48gpio->base + port);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>
> return !!(port_state & mask);
> }
>@@ -136,11 +136,11 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> const unsigned mask = BIT(offset % 8);
> unsigned long flags;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> /* ensure that GPIO is set for output */
> if (ws16c48gpio->io_state[port] & mask) {
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> return;
> }
>
>@@ -150,7 +150,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> ws16c48gpio->out_state[port] &= ~mask;
> outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> }
>
> static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
>@@ -178,14 +178,14 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
> iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port];
> bitmask = iomask & bits[BIT_WORD(i)];
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> /* update output state data and set device gpio register */
> ws16c48gpio->out_state[port] &= ~iomask;
> ws16c48gpio->out_state[port] |= bitmask;
> outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>
> /* prepare for next gpio register set */
> mask[BIT_WORD(i)] >>= gpio_reg_size;
>@@ -207,7 +207,7 @@ static void ws16c48_irq_ack(struct irq_data *data)
> if (port > 2)
> return;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> port_state = ws16c48gpio->irq_mask >> (8*port);
>
>@@ -216,7 +216,7 @@ static void ws16c48_irq_ack(struct irq_data *data)
> outb(port_state | mask, ws16c48gpio->base + 8 + port);
> outb(0xC0, ws16c48gpio->base + 7);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> }
>
> static void ws16c48_irq_mask(struct irq_data *data)
>@@ -232,7 +232,7 @@ static void ws16c48_irq_mask(struct irq_data *data)
> if (port > 2)
> return;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> ws16c48gpio->irq_mask &= ~mask;
>
>@@ -240,7 +240,7 @@ static void ws16c48_irq_mask(struct irq_data *data)
> outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
> outb(0xC0, ws16c48gpio->base + 7);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> }
>
> static void ws16c48_irq_unmask(struct irq_data *data)
>@@ -256,7 +256,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)
> if (port > 2)
> return;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> ws16c48gpio->irq_mask |= mask;
>
>@@ -264,7 +264,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)
> outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
> outb(0xC0, ws16c48gpio->base + 7);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> }
>
> static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
>@@ -280,7 +280,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
> if (port > 2)
> return -EINVAL;
>
>- spin_lock_irqsave(&ws16c48gpio->lock, flags);
>+ raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
>
> switch (flow_type) {
> case IRQ_TYPE_NONE:
>@@ -292,7 +292,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
> ws16c48gpio->flow_mask &= ~mask;
> break;
> default:
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
> return -EINVAL;
> }
>
>@@ -300,7 +300,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
> outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
> outb(0xC0, ws16c48gpio->base + 7);
>
>- spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>+ raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
>
> return 0;
> }
>@@ -387,7 +387,7 @@ static int ws16c48_probe(struct device *dev, unsigned int id)
> ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
> ws16c48gpio->base = base[id];
>
>- spin_lock_init(&ws16c48gpio->lock);
>+ raw_spin_lock_init(&ws16c48gpio->lock);
>
> err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
> if (err) {
>--
>2.11.1
>
> +@match2 depends on match@
> +identifier match.__irq_mask;
> +identifier data;
> +identifier x;
> +identifier l;
> +type T;
> +position j0;
> +expression flags;
> +@@
> + static void __irq_mask(struct irq_data *data)
> + {
> + ...
> + T *x;
> + ...
> +(
> + spin_lock_irqsave(&x->l@j0, flags);
> +|
> + spin_lock_irq(&x->l@j0);
> +|
> + spin_lock(&x->l@j0);
> +)
> + ...
> + }
I guess that here you want a match if there is a lock anywhere in the
function? Currently, the rule requires that the lock appear on every
control-flow path. If you put exists after depends on match in the rule
header, it will match if there exists a control-flow patch that contains a
local call.
Also, ... matches the shortest path between the pattern before the ... and
the pattern after. Thus, x would have to be the first variable in the
function of pointer type. To eliminate this constraint, put when any on
each of the ...s. This will additionally allow more than one lock call in
the function.
All in all, I would suggest the following for this rule:
@match2 depends on match exists@
identifier match.__irq_mask;
identifier data;
identifier x;
identifier l;
type T;
position j0;
expression flags;
@@
static void __irq_mask(struct irq_data *data)
{
... when any
T *x;
... when any
(
spin_lock_irqsave(&x->l@j0, flags);
|
spin_lock_irq(&x->l@j0);
|
spin_lock(&x->l@j0);
)
... when any
}
julia
Hello Julia-
Thanks for the feedback.
On Thu, Mar 09, 2017 at 09:15:21PM +0100, Julia Lawall wrote:
> > +@match2 depends on match@
> > +identifier match.__irq_mask;
> > +identifier data;
> > +identifier x;
> > +identifier l;
> > +type T;
> > +position j0;
> > +expression flags;
> > +@@
> > + static void __irq_mask(struct irq_data *data)
> > + {
> > + ...
> > + T *x;
> > + ...
> > +(
> > + spin_lock_irqsave(&x->l@j0, flags);
> > +|
> > + spin_lock_irq(&x->l@j0);
> > +|
> > + spin_lock(&x->l@j0);
> > +)
> > + ...
> > + }
>
> I guess that here you want a match if there is a lock anywhere in the
> function?
Most generally, yes. Any invocation of spin_lock{,_irq,_irqsave}() in
the irq_mask callback of an irq_chip implementation (irq_mask is only
_one_ such problematic callback, but a fairly representative one).
I should probably introduce a more generic report-mode rule which more
matches spin_lock{,_irq,_irqsave}(e), leaving this rule which requires
the lock accessed through local pointer-indirection only used as a
condition for patch mode.
I'll play with this a bit.
> Currently, the rule requires that the lock appear on every
> control-flow path. If you put exists after depends on match in the rule
> header, it will match if there exists a control-flow patch that contains a
> local call.
Thanks, this makes sense.
> Also, ... matches the shortest path between the pattern before the ... and
> the pattern after. Thus, x would have to be the first variable in the
> function of pointer type. To eliminate this constraint, put when any on
> each of the ...s. This will additionally allow more than one lock call in
> the function.
>
> All in all, I would suggest the following for this rule:
>
> @match2 depends on match exists@
> identifier match.__irq_mask;
> identifier data;
> identifier x;
> identifier l;
> type T;
> position j0;
> expression flags;
> @@
> static void __irq_mask(struct irq_data *data)
> {
> ... when any
> T *x;
> ... when any
> (
> spin_lock_irqsave(&x->l@j0, flags);
> |
> spin_lock_irq(&x->l@j0);
> |
> spin_lock(&x->l@j0);
> )
> ... when any
> }
Great, thanks, Julia!
- The Other Julia
Hi Julia/Linus,
On 3/9/2017 8:21 AM, Julia Cartwright wrote:
> The bcm-kona gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
This is new to me. But it seems like, for the vast majority cases, user
can still continue to use spin_lock as it is without needing to worry
about the underlying difference between standard or RT kernels. But in
certain cases, e.g., irq_chips, extra care needs to be done, i.e.,
switching to use raw spin lock to make sure that it is not blocking in
the case of RT.
Is such API use change well accepted by the open source community already?
Thanks,
Ray
>
> Signed-off-by: Julia Cartwright <[email protected]>
> ---
> drivers/gpio/gpio-bcm-kona.c | 48 ++++++++++++++++++++++----------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
> index 41d0ac142580..dfcf56ee3c61 100644
> --- a/drivers/gpio/gpio-bcm-kona.c
> +++ b/drivers/gpio/gpio-bcm-kona.c
> @@ -67,7 +67,7 @@
> struct bcm_kona_gpio {
> void __iomem *reg_base;
> int num_bank;
> - spinlock_t lock;
> + raw_spinlock_t lock;
> struct gpio_chip gpio_chip;
> struct irq_domain *irq_domain;
> struct bcm_kona_gpio_bank *banks;
> @@ -95,13 +95,13 @@ static void bcm_kona_gpio_lock_gpio(struct bcm_kona_gpio *kona_gpio,
> unsigned long flags;
> int bank_id = GPIO_BANK(gpio);
>
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
> val |= BIT(gpio);
> bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
> @@ -111,13 +111,13 @@ static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio,
> unsigned long flags;
> int bank_id = GPIO_BANK(gpio);
>
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id));
> val &= ~BIT(gpio);
> bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val);
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio)
> @@ -141,7 +141,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
>
> kona_gpio = gpiochip_get_data(chip);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> /* this function only applies to output pin */
> if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN)
> @@ -154,7 +154,7 @@ static void bcm_kona_gpio_set(struct gpio_chip *chip, unsigned gpio, int value)
> writel(val, reg_base + reg_offset);
>
> out:
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
> @@ -168,7 +168,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
>
> kona_gpio = gpiochip_get_data(chip);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> if (bcm_kona_gpio_get_dir(chip, gpio) == GPIOF_DIR_IN)
> reg_offset = GPIO_IN_STATUS(bank_id);
> @@ -178,7 +178,7 @@ static int bcm_kona_gpio_get(struct gpio_chip *chip, unsigned gpio)
> /* read the GPIO bank status */
> val = readl(reg_base + reg_offset);
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
>
> /* return the specified bit status */
> return !!(val & BIT(bit));
> @@ -208,14 +208,14 @@ static int bcm_kona_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
>
> kona_gpio = gpiochip_get_data(chip);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_CONTROL(gpio));
> val &= ~GPIO_GPCTR0_IOTR_MASK;
> val |= GPIO_GPCTR0_IOTR_CMD_INPUT;
> writel(val, reg_base + GPIO_CONTROL(gpio));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
>
> return 0;
> }
> @@ -232,7 +232,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip,
>
> kona_gpio = gpiochip_get_data(chip);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_CONTROL(gpio));
> val &= ~GPIO_GPCTR0_IOTR_MASK;
> @@ -244,7 +244,7 @@ static int bcm_kona_gpio_direction_output(struct gpio_chip *chip,
> val |= BIT(bit);
> writel(val, reg_base + reg_offset);
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
>
> return 0;
> }
> @@ -288,7 +288,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio,
> }
>
> /* spin lock for read-modify-write of the GPIO register */
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_CONTROL(gpio));
> val &= ~GPIO_GPCTR0_DBR_MASK;
> @@ -303,7 +303,7 @@ static int bcm_kona_gpio_set_debounce(struct gpio_chip *chip, unsigned gpio,
>
> writel(val, reg_base + GPIO_CONTROL(gpio));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
>
> return 0;
> }
> @@ -347,13 +347,13 @@ static void bcm_kona_gpio_irq_ack(struct irq_data *d)
>
> kona_gpio = irq_data_get_irq_chip_data(d);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_INT_STATUS(bank_id));
> val |= BIT(bit);
> writel(val, reg_base + GPIO_INT_STATUS(bank_id));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static void bcm_kona_gpio_irq_mask(struct irq_data *d)
> @@ -368,13 +368,13 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d)
>
> kona_gpio = irq_data_get_irq_chip_data(d);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_INT_MASK(bank_id));
> val |= BIT(bit);
> writel(val, reg_base + GPIO_INT_MASK(bank_id));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static void bcm_kona_gpio_irq_unmask(struct irq_data *d)
> @@ -389,13 +389,13 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d)
>
> kona_gpio = irq_data_get_irq_chip_data(d);
> reg_base = kona_gpio->reg_base;
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_INT_MSKCLR(bank_id));
> val |= BIT(bit);
> writel(val, reg_base + GPIO_INT_MSKCLR(bank_id));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
> }
>
> static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> @@ -431,14 +431,14 @@ static int bcm_kona_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> return -EINVAL;
> }
>
> - spin_lock_irqsave(&kona_gpio->lock, flags);
> + raw_spin_lock_irqsave(&kona_gpio->lock, flags);
>
> val = readl(reg_base + GPIO_CONTROL(gpio));
> val &= ~GPIO_GPCTR0_ITR_MASK;
> val |= lvl_type << GPIO_GPCTR0_ITR_SHIFT;
> writel(val, reg_base + GPIO_CONTROL(gpio));
>
> - spin_unlock_irqrestore(&kona_gpio->lock, flags);
> + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags);
>
> return 0;
> }
> @@ -655,7 +655,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
> bank);
> }
>
> - spin_lock_init(&kona_gpio->lock);
> + raw_spin_lock_init(&kona_gpio->lock);
>
> return 0;
>
>
On Fri, Mar 10, 2017 at 09:28:08AM -0800, Ray Jui wrote:
> Hi Julia/Linus,
>
> On 3/9/2017 8:21 AM, Julia Cartwright wrote:
> > The bcm-kona gpio driver currently implements an irq_chip for handling
> > interrupts; due to how irq_chip handling is done, it's necessary for the
> > irq_chip methods to be invoked from hardirq context, even on a a
> > real-time kernel. Because the spinlock_t type becomes a "sleeping"
> > spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
> >
> > A quick audit of the operations under the lock reveal that they do only
> > minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> This is new to me. But it seems like, for the vast majority cases, user
> can still continue to use spin_lock as it is without needing to worry
> about the underlying difference between standard or RT kernels.
If by "user" you mean, "driver developer", then yes. For most driver
authors, the distinction between raw and non-raw spinlocks is
irrelevant, they can use spinlocks and everything will work out just
fine w/ mainline and on RT.
> But in certain cases, e.g., irq_chips, extra care needs to be done,
> i.e., swtching to use raw spin lock to make sure that it is not
> blocking in the case of RT.
Correct, on RT the goal is to push as much as possible into a
preemptible context, including driver interrupts, etc. However, there
are still codepaths which necessarily need to be executed in hardirq
context, including anything necessary to support scheduling. This
includes: interrupt-dispatching (irq_chips), timers, and the scheduler
itself, which is why this "core" code must use the raw spinlock
variants.
> Is such API use change well accepted by the open source community
> already?
In what way is this an API change? The API isn't changing, what's
changing in this patch is to fix what is an irq_chip implementation
which is _currently broken_ on RT.
Julia
Hi Julia,
[auto build test ERROR on gpio/for-next]
[also build test ERROR on v4.11-rc1 next-20170309]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Julia-Cartwright/fixup-usage-of-non-raw-spinlocks-in-irqchips/20170312-015922
base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: alpha-alldefconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=alpha
All error/warnings (new ones prefixed by >>):
In file included from include/linux/mmzone.h:7:0,
from include/linux/gfp.h:5,
from include/linux/mm.h:9,
from arch/alpha/include/asm/io.h:7,
from arch/alpha/kernel/core_marvel.c:8:
arch/alpha/kernel/core_marvel.c: In function 'alloc_io7':
>> arch/alpha/kernel/core_marvel.c:121:17: error: passing argument 1 of 'spinlock_check' from incompatible pointer type [-Werror=incompatible-pointer-types]
spin_lock_init(&io7->irq_lock);
^
include/linux/spinlock.h:293:17: note: in definition of macro 'spin_lock_init'
spinlock_check(_lock); \
^~~~~
include/linux/spinlock.h:286:40: note: expected 'spinlock_t * {aka struct spinlock *}' but argument is of type 'raw_spinlock_t * {aka struct raw_spinlock *}'
static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
^~~~~~~~~~~~~~
In file included from include/linux/mmzone.h:7:0,
from include/linux/gfp.h:5,
from include/linux/mm.h:9,
from arch/alpha/include/asm/io.h:7,
from arch/alpha/kernel/core_marvel.c:8:
>> include/linux/spinlock.h:294:29: error: 'raw_spinlock_t {aka struct raw_spinlock}' has no member named 'rlock'; did you mean 'raw_lock'?
raw_spin_lock_init(&(_lock)->rlock); \
^
include/linux/spinlock.h:104:9: note: in definition of macro 'raw_spin_lock_init'
do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0)
^~~~
>> arch/alpha/kernel/core_marvel.c:121:2: note: in expansion of macro 'spin_lock_init'
spin_lock_init(&io7->irq_lock);
^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +294 include/linux/spinlock.h
c2f21ce2 Thomas Gleixner 2009-12-02 280 #endif
c2f21ce2 Thomas Gleixner 2009-12-02 281
c2f21ce2 Thomas Gleixner 2009-12-02 282 /*
c2f21ce2 Thomas Gleixner 2009-12-02 283 * Map the spin_lock functions to the raw variants for PREEMPT_RT=n
c2f21ce2 Thomas Gleixner 2009-12-02 284 */
c2f21ce2 Thomas Gleixner 2009-12-02 285
3490565b Denys Vlasenko 2015-07-13 @286 static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
c2f21ce2 Thomas Gleixner 2009-12-02 287 {
c2f21ce2 Thomas Gleixner 2009-12-02 288 return &lock->rlock;
c2f21ce2 Thomas Gleixner 2009-12-02 289 }
c2f21ce2 Thomas Gleixner 2009-12-02 290
c2f21ce2 Thomas Gleixner 2009-12-02 291 #define spin_lock_init(_lock) \
c2f21ce2 Thomas Gleixner 2009-12-02 292 do { \
c2f21ce2 Thomas Gleixner 2009-12-02 293 spinlock_check(_lock); \
c2f21ce2 Thomas Gleixner 2009-12-02 @294 raw_spin_lock_init(&(_lock)->rlock); \
c2f21ce2 Thomas Gleixner 2009-12-02 295 } while (0)
c2f21ce2 Thomas Gleixner 2009-12-02 296
3490565b Denys Vlasenko 2015-07-13 297 static __always_inline void spin_lock(spinlock_t *lock)
:::::: The code at line 294 was first introduced by commit
:::::: c2f21ce2e31286a0a32f8da0a7856e9ca1122ef3 locking: Implement new raw_spinlock
:::::: TO: Thomas Gleixner <[email protected]>
:::::: CC: Thomas Gleixner <[email protected]>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Thu, 9 Mar 2017 10:21:53 -0600
Julia Cartwright <[email protected]> wrote:
> The ath79 gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Acked-by: Aban Bedel <[email protected]>
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The following patchset introduces a new coccinelle patch,
> irq_chip_raw_spinlock.cocci, which is used to identify irq_chip implementors
> which acquire/release non-raw spinlocks, and in addition, a set of generated
> patches for most cases identified.
Wow that is really impressive. I expect to apply all that
are applicable to GPIO drivers. I guess this really lowers
the bar to run realtime on a whole slew of systems.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The altera gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a real-time
> kernel. Because the spinlock_t type becomes a "sleeping" spinlock w/ RT
> kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The 104-dio-48e gpio driver currently implements an irq_chip for
> handling interrupts; due to how irq_chip handling is done, it's
> necessary for the irq_chip methods to be invoked from hardirq context,
> even on a a real-time kernel. Because the spinlock_t type becomes a
> "sleeping" spinlock w/ RT kernels, it is not suitable to be used with
> irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied with Williams ACK.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The bcm-kona gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Fri, Mar 10, 2017 at 6:28 PM, Ray Jui <[email protected]> wrote:
> Is such API use change well accepted by the open source community already?
The raw_*spinlock APIs are in the kernel header files and used at several
sites in the kernel, so yes.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The ath79 gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied with Alban's ACK.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The etraxfs gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The pl061 gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The ws16c48 gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied with William's ACK.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:21 PM, Julia Cartwright <[email protected]> wrote:
> The zx gpio driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:22 PM, Julia Cartwright <[email protected]> wrote:
> The bcm pinctrl drivers currently implement an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:22 PM, Julia Cartwright <[email protected]> wrote:
> The amd pinctrl drivers currently implement an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:22 PM, Julia Cartwright <[email protected]> wrote:
> The sirf atlas7 pinctrl drivers currently implement an irq_chip for
> handling interrupts; due to how irq_chip handling is done, it's
> necessary for the irq_chip methods to be invoked from hardirq context,
> even on a a real-time kernel. Because the spinlock_t type becomes a
> "sleeping" spinlock w/ RT kernels, it is not suitable to be used with
> irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, Mar 9, 2017 at 5:22 PM, Julia Cartwright <[email protected]> wrote:
> The sunxi pinctrl driver currently implement an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied.
Yours,
Linus Walleij
On Thu, 09 Mar 2017, Julia Cartwright wrote:
> The t7l66xb mfd driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
> ---
> drivers/mfd/t7l66xb.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
Can the 3 MFD patches in this set be applied on their own, or is there
a dependency somewhere else in the set?
NB: It's normally a good idea to send the set to everyone, or at the
very least, the 00/00th patch.
> diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
> index 94bd89cb1f06..22c811396edc 100644
> --- a/drivers/mfd/t7l66xb.c
> +++ b/drivers/mfd/t7l66xb.c
> @@ -69,7 +69,7 @@ static const struct resource t7l66xb_mmc_resources[] = {
> struct t7l66xb {
> void __iomem *scr;
> /* Lock to protect registers requiring read/modify/write ops. */
> - spinlock_t lock;
> + raw_spinlock_t lock;
>
> struct resource rscr;
> struct clk *clk48m;
> @@ -89,13 +89,13 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc)
>
> clk_prepare_enable(t7l66xb->clk32k);
>
> - spin_lock_irqsave(&t7l66xb->lock, flags);
> + raw_spin_lock_irqsave(&t7l66xb->lock, flags);
>
> dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
> dev_ctl |= SCR_DEV_CTL_MMC;
> tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
>
> - spin_unlock_irqrestore(&t7l66xb->lock, flags);
> + raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
>
> tmio_core_mmc_enable(t7l66xb->scr + 0x200, 0,
> t7l66xb_mmc_resources[0].start & 0xfffe);
> @@ -110,13 +110,13 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
> unsigned long flags;
> u8 dev_ctl;
>
> - spin_lock_irqsave(&t7l66xb->lock, flags);
> + raw_spin_lock_irqsave(&t7l66xb->lock, flags);
>
> dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
> dev_ctl &= ~SCR_DEV_CTL_MMC;
> tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
>
> - spin_unlock_irqrestore(&t7l66xb->lock, flags);
> + raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
>
> clk_disable_unprepare(t7l66xb->clk32k);
>
> @@ -206,11 +206,11 @@ static void t7l66xb_irq_mask(struct irq_data *data)
> unsigned long flags;
> u8 imr;
>
> - spin_lock_irqsave(&t7l66xb->lock, flags);
> + raw_spin_lock_irqsave(&t7l66xb->lock, flags);
> imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
> imr |= 1 << (data->irq - t7l66xb->irq_base);
> tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
> - spin_unlock_irqrestore(&t7l66xb->lock, flags);
> + raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
> }
>
> static void t7l66xb_irq_unmask(struct irq_data *data)
> @@ -219,11 +219,11 @@ static void t7l66xb_irq_unmask(struct irq_data *data)
> unsigned long flags;
> u8 imr;
>
> - spin_lock_irqsave(&t7l66xb->lock, flags);
> + raw_spin_lock_irqsave(&t7l66xb->lock, flags);
> imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
> imr &= ~(1 << (data->irq - t7l66xb->irq_base));
> tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
> - spin_unlock_irqrestore(&t7l66xb->lock, flags);
> + raw_spin_unlock_irqrestore(&t7l66xb->lock, flags);
> }
>
> static struct irq_chip t7l66xb_chip = {
> @@ -321,7 +321,7 @@ static int t7l66xb_probe(struct platform_device *dev)
> if (!t7l66xb)
> return -ENOMEM;
>
> - spin_lock_init(&t7l66xb->lock);
> + raw_spin_lock_init(&t7l66xb->lock);
>
> platform_set_drvdata(dev, t7l66xb);
>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On Wed, Mar 15, 2017 at 11:17:44AM +0000, Lee Jones wrote:
> On Thu, 09 Mar 2017, Julia Cartwright wrote:
>
> > The t7l66xb mfd driver currently implements an irq_chip for handling
> > interrupts; due to how irq_chip handling is done, it's necessary for the
> > irq_chip methods to be invoked from hardirq context, even on a a
> > real-time kernel. Because the spinlock_t type becomes a "sleeping"
> > spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
> >
> > A quick audit of the operations under the lock reveal that they do only
> > minimal, bounded work, and are therefore safe to do under a raw spinlock.
> >
> > Signed-off-by: Julia Cartwright <[email protected]>
> > ---
> > drivers/mfd/t7l66xb.c | 20 ++++++++++----------
> > 1 file changed, 10 insertions(+), 10 deletions(-)
>
> Can the 3 MFD patches in this set be applied on their own, or is there
> a dependency somewhere else in the set?
All of the patches are completely independent, so may be applied on
their own.
> NB: It's normally a good idea to send the set to everyone, or at the
> very least, the 00/00th patch.
Sorry I neglected to CC. I'll be posting a v2 with the patches that
haven't yet hit next (as of tomorrow, likely), with a revised version of
the coccinelle patch, and will CC you on the coverletter.
Thanks!
Julia
On Wed, 15 Mar 2017, Julia Cartwright wrote:
> On Wed, Mar 15, 2017 at 11:17:44AM +0000, Lee Jones wrote:
> > On Thu, 09 Mar 2017, Julia Cartwright wrote:
> >
> > > The t7l66xb mfd driver currently implements an irq_chip for handling
> > > interrupts; due to how irq_chip handling is done, it's necessary for the
> > > irq_chip methods to be invoked from hardirq context, even on a a
> > > real-time kernel. Because the spinlock_t type becomes a "sleeping"
> > > spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
> > >
> > > A quick audit of the operations under the lock reveal that they do only
> > > minimal, bounded work, and are therefore safe to do under a raw spinlock.
> > >
> > > Signed-off-by: Julia Cartwright <[email protected]>
> > > ---
> > > drivers/mfd/t7l66xb.c | 20 ++++++++++----------
> > > 1 file changed, 10 insertions(+), 10 deletions(-)
> >
> > Can the 3 MFD patches in this set be applied on their own, or is there
> > a dependency somewhere else in the set?
>
> All of the patches are completely independent, so may be applied on
> their own.
>
> > NB: It's normally a good idea to send the set to everyone, or at the
> > very least, the 00/00th patch.
>
> Sorry I neglected to CC. I'll be posting a v2 with the patches that
> haven't yet hit next (as of tomorrow, likely), with a revised version of
> the coccinelle patch, and will CC you on the coverletter.
To save a clash of me applying and you submitting v2 I'll not apply
the MFD patches just yet. But if I have caught you in time, please
apply the following tag to them:
For my own reference:
Acked-for-MFD-by: Lee Jones <[email protected]>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On 2017-03-09 17:21, Julia Cartwright wrote:
> The pca954x i2c mux driver currently implements an irq_chip for handling
> interrupts; due to how irq_chip handling is done, it's necessary for the
> irq_chip methods to be invoked from hardirq context, even on a a
> real-time kernel. Because the spinlock_t type becomes a "sleeping"
> spinlock w/ RT kernels, it is not suitable to be used with irq_chips.
>
> A quick audit of the operations under the lock reveal that they do only
> minimal, bounded work, and are therefore safe to do under a raw spinlock.
>
> Signed-off-by: Julia Cartwright <[email protected]>
Patch applied to the i2c-mux repo. Thanks!
Cheers,
peda