From: Julia Cartwright <julia@ni.com> To: William Breathitt Gray <vilhelm.gray@gmail.com>, Linus Walleij <linus.walleij@linaro.org>, Alexandre Courbot <gnurou@gmail.com> Cc: linux-kernel@vger.kernel.org, Thomas Gleixner <tglx@linutronix.de>, linux-gpio@vger.kernel.org Subject: [PATCH 05/19] gpio: 104-dio-48e: make use of raw_spinlock variants Date: Thu, 9 Mar 2017 10:21:52 -0600 [thread overview] Message-ID: <b0ce23678fb1703f761a5b380746cb0412651f09.1489015238.git.julia@ni.com> (raw) In-Reply-To: <cover.1489015238.git.julia@ni.com> 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 <julia@ni.com> --- 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
WARNING: multiple messages have this Message-ID (diff)
From: Julia Cartwright <julia@ni.com> To: William Breathitt Gray <vilhelm.gray@gmail.com>, Linus Walleij <linus.walleij@linaro.org>, Alexandre Courbot <gnurou@gmail.com> Cc: <linux-kernel@vger.kernel.org>, Thomas Gleixner <tglx@linutronix.de>, <linux-gpio@vger.kernel.org> Subject: [PATCH 05/19] gpio: 104-dio-48e: make use of raw_spinlock variants Date: Thu, 9 Mar 2017 10:21:52 -0600 [thread overview] Message-ID: <b0ce23678fb1703f761a5b380746cb0412651f09.1489015238.git.julia@ni.com> (raw) In-Reply-To: <cover.1489015238.git.julia@ni.com> 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 <julia@ni.com> --- 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
next prev parent reply other threads:[~2017-03-09 16:21 UTC|newest] Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-03-09 16:21 [PATCH 00/19] fixup usage of non-raw spinlocks in irqchips Julia Cartwright 2017-03-09 16:21 ` [Cocci] " Julia Cartwright 2017-03-09 16:21 ` [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{,_irq,_irqsave}() in irqchip implementations Julia Cartwright 2017-03-09 16:21 ` [Cocci] [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{, _irq, _irqsave}() " Julia Cartwright 2017-03-09 20:15 ` [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{,_irq,_irqsave}() " Julia Lawall 2017-03-09 20:15 ` [Cocci] [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{, _irq, _irqsave}() " Julia Lawall 2017-03-09 21:37 ` [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{,_irq,_irqsave}() " Julia Cartwright 2017-03-09 21:37 ` [Cocci] [PATCH 01/19] Coccinelle: locks: identify callers of spin_lock{, _irq, _irqsave}() " Julia Cartwright 2017-03-09 16:21 ` [PATCH 02/19] gpio: altera: make use of raw_spinlock variants Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-15 9:53 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 03/19] alpha: marvel: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-12 2:58 ` kbuild test robot 2017-03-09 16:21 ` [PATCH 04/19] powerpc: mpc52xx_gpt: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright [this message] 2017-03-09 16:21 ` [PATCH 05/19] gpio: 104-dio-48e: " Julia Cartwright 2017-03-09 18:35 ` William Breathitt Gray 2017-03-15 9:54 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 06/19] gpio: ath79: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-13 19:51 ` Alban 2017-03-13 19:51 ` Alban 2017-03-15 9:59 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 07/19] gpio: bcm-kona: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-10 17:28 ` Ray Jui 2017-03-10 19:35 ` Julia Cartwright 2017-03-10 19:35 ` Julia Cartwright 2017-03-15 9:57 ` Linus Walleij 2017-03-15 9:56 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 08/19] gpio: etraxfs: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-15 10:00 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 09/19] gpio: pl061: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-15 10:01 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 10/19] gpio: ws16c48: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-09 18:36 ` William Breathitt Gray 2017-03-15 10:02 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 11/19] gpio: zx: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-15 10:03 ` Linus Walleij 2017-03-09 16:21 ` [PATCH 12/19] i2c: mux: pca954x: " Julia Cartwright 2017-03-09 16:21 ` Julia Cartwright 2017-03-16 19:38 ` Peter Rosin 2017-03-16 19:38 ` Peter Rosin 2017-03-09 16:22 ` [PATCH 13/19] mfd: asic3: " Julia Cartwright 2017-03-09 16:22 ` [PATCH 14/19] mfd: t7l66xb: " Julia Cartwright 2017-03-15 11:17 ` Lee Jones 2017-03-15 19:07 ` Julia Cartwright 2017-03-16 9:22 ` Lee Jones 2017-03-09 16:22 ` [PATCH 15/19] mfd: tc6393xb: " Julia Cartwright 2017-03-09 16:22 ` [PATCH 16/19] pinctrl: bcm: " Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-15 10:11 ` Linus Walleij 2017-03-15 10:11 ` Linus Walleij 2017-03-15 10:11 ` Linus Walleij 2017-03-09 16:22 ` [PATCH 17/19] pinctrl: amd: " Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-15 10:12 ` Linus Walleij 2017-03-09 16:22 ` [PATCH 18/19] pinctrl: sirf: atlas7: " Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-15 10:13 ` Linus Walleij 2017-03-15 10:13 ` Linus Walleij 2017-03-15 10:13 ` Linus Walleij 2017-03-09 16:22 ` [PATCH 19/19] pinctrl: sunxi: " Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-09 16:22 ` Julia Cartwright 2017-03-15 10:14 ` Linus Walleij 2017-03-15 10:14 ` Linus Walleij 2017-03-15 10:14 ` Linus Walleij 2017-03-15 9:51 ` [PATCH 00/19] fixup usage of non-raw spinlocks in irqchips Linus Walleij 2017-03-15 9:51 ` [Cocci] " Linus Walleij
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=b0ce23678fb1703f761a5b380746cb0412651f09.1489015238.git.julia@ni.com \ --to=julia@ni.com \ --cc=gnurou@gmail.com \ --cc=linus.walleij@linaro.org \ --cc=linux-gpio@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=tglx@linutronix.de \ --cc=vilhelm.gray@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.