From: Srinivas Neeli <srinivas.neeli@xilinx.com>
To: linus.walleij@linaro.org, bgolaszewski@baylibre.com,
michal.simek@xilinx.com, shubhrajyoti.datta@xilinx.com
Cc: linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, git@xilinx.com
Subject: [PATCH 2/8] gpio: zynq: protect direction in/out with a spinlock
Date: Thu, 26 Dec 2019 17:42:12 +0530 [thread overview]
Message-ID: <1577362338-28744-3-git-send-email-srinivas.neeli@xilinx.com> (raw)
In-Reply-To: <1577362338-28744-1-git-send-email-srinivas.neeli@xilinx.com>
From: Glenn Langedock <Glenn.Langedock@barco.com>
Fix race condition when changing the direction (in/out) of the GPIO pin.
The read-modify-write sequence (as coded in the driver) isn't atomic and
requires synchronization (spinlock).
Signed-off-by: Glenn Langedock <Glenn.Langedock@barco.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Srinivas Neeli <srinivas.neeli@xilinx.com>
---
drivers/gpio/gpio-zynq.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
index 05ba16fffdad..9c8b8a397a26 100644
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -10,6 +10,7 @@
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -116,6 +117,7 @@ struct gpio_regs {
* @irq: interrupt for the GPIO device
* @p_data: pointer to platform data
* @context: context registers
+ * @dirlock: lock used for direction in/out synchronization
*/
struct zynq_gpio {
struct gpio_chip chip;
@@ -124,6 +126,7 @@ struct zynq_gpio {
int irq;
const struct zynq_platform_data *p_data;
struct gpio_regs context;
+ spinlock_t dirlock; /*lock used for direction in/out synchronization */
};
/**
@@ -297,6 +300,7 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
{
u32 reg;
unsigned int bank_num, bank_pin_num;
+ unsigned long flags;
struct zynq_gpio *gpio = gpiochip_get_data(chip);
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
@@ -310,9 +314,11 @@ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
return -EINVAL;
/* clear the bit in direction mode reg to set the pin as input */
+ spin_lock_irqsave(&gpio->dirlock, flags);
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
reg &= ~BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+ spin_unlock_irqrestore(&gpio->dirlock, flags);
return 0;
}
@@ -334,11 +340,13 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
{
u32 reg;
unsigned int bank_num, bank_pin_num;
+ unsigned long flags;
struct zynq_gpio *gpio = gpiochip_get_data(chip);
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
/* set the GPIO pin as output */
+ spin_lock_irqsave(&gpio->dirlock, flags);
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
reg |= BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
@@ -347,6 +355,7 @@ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
reg |= BIT(bank_pin_num);
writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
+ spin_unlock_irqrestore(&gpio->dirlock, flags);
/* set the state of the pin */
zynq_gpio_set_value(chip, pin, state);
@@ -885,6 +894,8 @@ static int zynq_gpio_probe(struct platform_device *pdev)
return ret;
}
+ spin_lock_init(&gpio->dirlock);
+
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
--
2.7.4
next prev parent reply other threads:[~2019-12-26 12:12 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-26 12:12 [PATCH 0/8] gpio: zynq: Update on gpio-zynq driver Srinivas Neeli
2019-12-26 12:12 ` [PATCH 1/8] gpio: zynq: Fix for bug in zynq_gpio_restore_context API Srinivas Neeli
2020-01-07 10:25 ` Linus Walleij
2019-12-26 12:12 ` Srinivas Neeli [this message]
2020-01-02 17:40 ` [PATCH 2/8] gpio: zynq: protect direction in/out with a spinlock Bartosz Golaszewski
2019-12-26 12:12 ` [PATCH 3/8] dt-bindings: gpio: Add binding for Versal gpio Srinivas Neeli
2019-12-26 12:12 ` [PATCH 4/8] devicetree-binding: Add pmc gpio node Srinivas Neeli
2019-12-26 12:12 ` [PATCH 5/8] gpio: zynq: Add Versal support Srinivas Neeli
2020-01-02 17:41 ` Bartosz Golaszewski
2019-12-26 12:12 ` [PATCH 6/8] gpio: zynq: Disable the irq if it is not a wakeup source Srinivas Neeli
2019-12-26 12:12 ` [PATCH 7/8] gpio: zynq: Add pmc gpio support Srinivas Neeli
2020-01-02 17:55 ` Bartosz Golaszewski
2019-12-26 12:12 ` [PATCH 8/8] gpio: zynq: Remove error prints in EPROBE_DEFER Srinivas Neeli
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=1577362338-28744-3-git-send-email-srinivas.neeli@xilinx.com \
--to=srinivas.neeli@xilinx.com \
--cc=bgolaszewski@baylibre.com \
--cc=git@xilinx.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.simek@xilinx.com \
--cc=shubhrajyoti.datta@xilinx.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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®