From: Ben Dooks <ben-linux@fluff.org>
To: linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org
Cc: Ben Dooks <ben-linux@fluff.org>
Subject: [PATCH 1/6] ARM: SAMSUNG: Add spinlock locking to GPIO banks
Date: Mon, 17 May 2010 08:22:33 +0100 [thread overview]
Message-ID: <1274080958-369-1-git-send-email-ben-linux@fluff.org> (raw)
Add locking to each GPIO bank to allow for SMP capable code
to use the gpiolib functions. See the gpio-core.h header file
for more information.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
arch/arm/plat-samsung/gpio-config.c | 12 ++++++------
arch/arm/plat-samsung/gpio.c | 15 +++++++++------
arch/arm/plat-samsung/include/plat/gpio-core.h | 14 ++++++++++++++
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 3282db3..a76eef5 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -33,9 +33,9 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setcfg(chip, offset, config);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
return ret;
}
@@ -51,9 +51,9 @@ unsigned s3c_gpio_getcfg(unsigned int pin)
if (chip) {
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_getcfg(chip, offset);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
}
return ret;
@@ -72,9 +72,9 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setpull(chip, offset, pull);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
return ret;
}
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index 28d2ab8..b83a833 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/spinlock.h>
#include <plat/gpio-core.h>
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned long con;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
con = __raw_readl(base + 0x00);
con &= ~(3 << (offset * 2));
__raw_writel(con, base + 0x00);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
return 0;
}
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
unsigned long dat;
unsigned long con;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
__raw_writel(con, base + 0x00);
__raw_writel(dat, base + 0x04);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
return 0;
}
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
unsigned long flags;
unsigned long dat;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
dat |= 1 << offset;
__raw_writel(dat, base + 0x04);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
}
static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
BUG_ON(!gc->label);
BUG_ON(!gc->ngpio);
+ spin_lock_init(&chip->lock);
+
if (!gc->direction_input)
gc->direction_input = s3c_gpiolib_input;
if (!gc->direction_output)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index f0584f2..f3a68d1 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
* @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers.
* @config: special function and pull-resistor control information.
+ * @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
+ *
+ * The lock protects each gpio bank from multiple access of the shared
+ * configuration registers, or from reading of data whilst another thread
+ * is writing to the register set.
+ *
+ * Each chip has its own lock to avoid any contention between different
+ * CPU cores trying to get one lock for different GPIO banks, where each
+ * bank of GPIO has its own register space and configuration registers.
*/
struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
+ spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
@@ -138,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
#define __gpio_pm(x) NULL
#endif /* CONFIG_PM */
+
+/* locking wrappers to deal with multiple access to the same gpio bank */
+#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
--
1.6.3.3
WARNING: multiple messages have this Message-ID (diff)
From: ben-linux@fluff.org (Ben Dooks)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/6] ARM: SAMSUNG: Add spinlock locking to GPIO banks
Date: Mon, 17 May 2010 08:22:33 +0100 [thread overview]
Message-ID: <1274080958-369-1-git-send-email-ben-linux@fluff.org> (raw)
Add locking to each GPIO bank to allow for SMP capable code
to use the gpiolib functions. See the gpio-core.h header file
for more information.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
arch/arm/plat-samsung/gpio-config.c | 12 ++++++------
arch/arm/plat-samsung/gpio.c | 15 +++++++++------
arch/arm/plat-samsung/include/plat/gpio-core.h | 14 ++++++++++++++
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 3282db3..a76eef5 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -33,9 +33,9 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setcfg(chip, offset, config);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
return ret;
}
@@ -51,9 +51,9 @@ unsigned s3c_gpio_getcfg(unsigned int pin)
if (chip) {
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_getcfg(chip, offset);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
}
return ret;
@@ -72,9 +72,9 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
offset = pin - chip->chip.base;
- local_irq_save(flags);
+ s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setpull(chip, offset, pull);
- local_irq_restore(flags);
+ s3c_gpio_unlock(chip, flags);
return ret;
}
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index 28d2ab8..b83a833 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/spinlock.h>
#include <plat/gpio-core.h>
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned long con;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
con = __raw_readl(base + 0x00);
con &= ~(3 << (offset * 2));
__raw_writel(con, base + 0x00);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
return 0;
}
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
unsigned long dat;
unsigned long con;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
__raw_writel(con, base + 0x00);
__raw_writel(dat, base + 0x04);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
return 0;
}
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
unsigned long flags;
unsigned long dat;
- local_irq_save(flags);
+ s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
dat |= 1 << offset;
__raw_writel(dat, base + 0x04);
- local_irq_restore(flags);
+ s3c_gpio_unlock(ourchip, flags);
}
static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
BUG_ON(!gc->label);
BUG_ON(!gc->ngpio);
+ spin_lock_init(&chip->lock);
+
if (!gc->direction_input)
gc->direction_input = s3c_gpiolib_input;
if (!gc->direction_output)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index f0584f2..f3a68d1 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
* @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers.
* @config: special function and pull-resistor control information.
+ * @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
+ *
+ * The lock protects each gpio bank from multiple access of the shared
+ * configuration registers, or from reading of data whilst another thread
+ * is writing to the register set.
+ *
+ * Each chip has its own lock to avoid any contention between different
+ * CPU cores trying to get one lock for different GPIO banks, where each
+ * bank of GPIO has its own register space and configuration registers.
*/
struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
+ spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
@@ -138,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
#define __gpio_pm(x) NULL
#endif /* CONFIG_PM */
+
+/* locking wrappers to deal with multiple access to the same gpio bank */
+#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
--
1.6.3.3
next reply other threads:[~2010-05-17 7:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-17 7:22 Ben Dooks [this message]
2010-05-17 7:22 ` [PATCH 1/6] ARM: SAMSUNG: Add spinlock locking to GPIO banks Ben Dooks
2010-05-17 7:22 ` [PATCH 2/6] ARM: S3C244X: fix gpiolib port J support Ben Dooks
2010-05-17 7:22 ` Ben Dooks
2010-05-17 7:22 ` [PATCH 3/6] ARM: S3C24XX: Start cleanup of GPIO numbering Ben Dooks
2010-05-17 7:22 ` Ben Dooks
2010-05-17 7:22 ` [PATCH 4/6] ARM: S3C24XX: Update missed gpio calls to use gpiolib Ben Dooks
2010-05-17 7:22 ` Ben Dooks
2010-05-17 7:22 ` [PATCH 5/6] ARM: S3C24XX: Remove macros mapping GPIO number to base Ben Dooks
2010-05-17 7:22 ` Ben Dooks
2010-05-17 7:22 ` [PATCH 6/6] ARM: S3C24XX: Add note on GPIO bank sizes Ben Dooks
2010-05-17 7:22 ` Ben Dooks
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=1274080958-369-1-git-send-email-ben-linux@fluff.org \
--to=ben-linux@fluff.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-samsung-soc@vger.kernel.org \
/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 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.