All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] hwspinlock-next
@ 2011-09-12 16:46 ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

This series includes a new u8500 hwspinlock driver from Mathieu,
a core fix from Juan and several other cleanups/fixes
(some of which were reported by Arnd while reviewing Mathieu's
driver).

Maybe the most notable core change is the move to registering
a bank of hwspinlocks in a single API call, rather than the
existing approach which required drivers to register each
hwspinlock separately.

That also allowed eliminating 3 per-lock struct members
(dev and ops, which are now maintained per-bank, and id, which
is completely removed, and instead, derived from the array index
of the hwspinlock struct).

The result is ~20% code reduction in the hwspinlock drivers and
a smaller memory footprint.

Juan Gutierrez (1):
  hwspinlock/core: use a mutex to protect the radix tree

Mathieu J. Poirier (1):
  hwspinlock/u8500: add hwspinlock driver

Ohad Ben-Cohen (8):
  hwspinlock/core: simplify Kconfig
  hwspinlock/core: simplify 'owner' handling
  hwspinlock/omap: simplify allocation scheme
  hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
  hwspinlock/core: remove stubs for register/unregister
  hwspinlock/core: register a bank of hwspinlocks in a single API call
  hwspinlock/omap: omap_hwspinlock_remove should be __devexit
  hwspinlock: add MAINTAINERS entries

 Documentation/hwspinlock.txt             |   74 +++++++-----
 MAINTAINERS                              |   15 +++
 arch/arm/mach-omap2/hwspinlock.c         |    8 +-
 drivers/hwspinlock/Kconfig               |   27 +++--
 drivers/hwspinlock/Makefile              |    2 +
 drivers/hwspinlock/hwspinlock_core.c     |  204 +++++++++++++++++++-----------
 drivers/hwspinlock/hwspinlock_internal.h |   40 ++++--
 drivers/hwspinlock/omap_hwspinlock.c     |  127 +++++++------------
 drivers/hwspinlock/u8500_hsem.c          |  198 +++++++++++++++++++++++++++++
 include/linux/hwspinlock.h               |   46 +++++--
 10 files changed, 516 insertions(+), 225 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

-- 
1.7.4.1


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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-12 16:46 ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Ohad Ben-Cohen, Arnd Bergmann

This series includes a new u8500 hwspinlock driver from Mathieu,
a core fix from Juan and several other cleanups/fixes
(some of which were reported by Arnd while reviewing Mathieu's
driver).

Maybe the most notable core change is the move to registering
a bank of hwspinlocks in a single API call, rather than the
existing approach which required drivers to register each
hwspinlock separately.

That also allowed eliminating 3 per-lock struct members
(dev and ops, which are now maintained per-bank, and id, which
is completely removed, and instead, derived from the array index
of the hwspinlock struct).

The result is ~20% code reduction in the hwspinlock drivers and
a smaller memory footprint.

Juan Gutierrez (1):
  hwspinlock/core: use a mutex to protect the radix tree

Mathieu J. Poirier (1):
  hwspinlock/u8500: add hwspinlock driver

Ohad Ben-Cohen (8):
  hwspinlock/core: simplify Kconfig
  hwspinlock/core: simplify 'owner' handling
  hwspinlock/omap: simplify allocation scheme
  hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
  hwspinlock/core: remove stubs for register/unregister
  hwspinlock/core: register a bank of hwspinlocks in a single API call
  hwspinlock/omap: omap_hwspinlock_remove should be __devexit
  hwspinlock: add MAINTAINERS entries

 Documentation/hwspinlock.txt             |   74 +++++++-----
 MAINTAINERS                              |   15 +++
 arch/arm/mach-omap2/hwspinlock.c         |    8 +-
 drivers/hwspinlock/Kconfig               |   27 +++--
 drivers/hwspinlock/Makefile              |    2 +
 drivers/hwspinlock/hwspinlock_core.c     |  204 +++++++++++++++++++-----------
 drivers/hwspinlock/hwspinlock_internal.h |   40 ++++--
 drivers/hwspinlock/omap_hwspinlock.c     |  127 +++++++------------
 drivers/hwspinlock/u8500_hsem.c          |  198 +++++++++++++++++++++++++++++
 include/linux/hwspinlock.h               |   46 +++++--
 10 files changed, 516 insertions(+), 225 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

-- 
1.7.4.1

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-12 16:46 ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

This series includes a new u8500 hwspinlock driver from Mathieu,
a core fix from Juan and several other cleanups/fixes
(some of which were reported by Arnd while reviewing Mathieu's
driver).

Maybe the most notable core change is the move to registering
a bank of hwspinlocks in a single API call, rather than the
existing approach which required drivers to register each
hwspinlock separately.

That also allowed eliminating 3 per-lock struct members
(dev and ops, which are now maintained per-bank, and id, which
is completely removed, and instead, derived from the array index
of the hwspinlock struct).

The result is ~20% code reduction in the hwspinlock drivers and
a smaller memory footprint.

Juan Gutierrez (1):
  hwspinlock/core: use a mutex to protect the radix tree

Mathieu J. Poirier (1):
  hwspinlock/u8500: add hwspinlock driver

Ohad Ben-Cohen (8):
  hwspinlock/core: simplify Kconfig
  hwspinlock/core: simplify 'owner' handling
  hwspinlock/omap: simplify allocation scheme
  hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
  hwspinlock/core: remove stubs for register/unregister
  hwspinlock/core: register a bank of hwspinlocks in a single API call
  hwspinlock/omap: omap_hwspinlock_remove should be __devexit
  hwspinlock: add MAINTAINERS entries

 Documentation/hwspinlock.txt             |   74 +++++++-----
 MAINTAINERS                              |   15 +++
 arch/arm/mach-omap2/hwspinlock.c         |    8 +-
 drivers/hwspinlock/Kconfig               |   27 +++--
 drivers/hwspinlock/Makefile              |    2 +
 drivers/hwspinlock/hwspinlock_core.c     |  204 +++++++++++++++++++-----------
 drivers/hwspinlock/hwspinlock_internal.h |   40 ++++--
 drivers/hwspinlock/omap_hwspinlock.c     |  127 +++++++------------
 drivers/hwspinlock/u8500_hsem.c          |  198 +++++++++++++++++++++++++++++
 include/linux/hwspinlock.h               |   46 +++++--
 10 files changed, 516 insertions(+), 225 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

-- 
1.7.4.1

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

* [PATCH 01/10] hwspinlock/core: simplify Kconfig
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Simplify hwspinlock's Kconfig by making the global CONFIG_HWSPINLOCK
entry invisible; users will just select it when needed.

This also prepares the ground for adding hwspinlock support for other
platforms (the 'depends on ARCH_OMAP4' was rather hideous, and while
we're at it, a dedicated menu is added).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index 1f29bab..c8e7bda 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -2,22 +2,20 @@
 # Generic HWSPINLOCK framework
 #
 
+# HWSPINLOCK always gets selected by whoever wants it.
 config HWSPINLOCK
-	tristate "Generic Hardware Spinlock framework"
-	depends on ARCH_OMAP4
-	help
-	  Say y here to support the generic hardware spinlock framework.
-	  You only need to enable this if you have hardware spinlock module
-	  on your system (usually only relevant if your system has remote slave
-	  coprocessors).
+	tristate
 
-	  If unsure, say N.
+menu "Hardware Spinlock drivers"
 
 config HWSPINLOCK_OMAP
 	tristate "OMAP Hardware Spinlock device"
-	depends on HWSPINLOCK && ARCH_OMAP4
+	depends on ARCH_OMAP4
+	select HWSPINLOCK
 	help
 	  Say y here to support the OMAP Hardware Spinlock device (firstly
 	  introduced in OMAP4).
 
 	  If unsure, say N.
+
+endmenu
-- 
1.7.4.1


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

* [PATCH 01/10] hwspinlock/core: simplify Kconfig
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Ohad Ben-Cohen, Arnd Bergmann

Simplify hwspinlock's Kconfig by making the global CONFIG_HWSPINLOCK
entry invisible; users will just select it when needed.

This also prepares the ground for adding hwspinlock support for other
platforms (the 'depends on ARCH_OMAP4' was rather hideous, and while
we're at it, a dedicated menu is added).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index 1f29bab..c8e7bda 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -2,22 +2,20 @@
 # Generic HWSPINLOCK framework
 #
 
+# HWSPINLOCK always gets selected by whoever wants it.
 config HWSPINLOCK
-	tristate "Generic Hardware Spinlock framework"
-	depends on ARCH_OMAP4
-	help
-	  Say y here to support the generic hardware spinlock framework.
-	  You only need to enable this if you have hardware spinlock module
-	  on your system (usually only relevant if your system has remote slave
-	  coprocessors).
+	tristate
 
-	  If unsure, say N.
+menu "Hardware Spinlock drivers"
 
 config HWSPINLOCK_OMAP
 	tristate "OMAP Hardware Spinlock device"
-	depends on HWSPINLOCK && ARCH_OMAP4
+	depends on ARCH_OMAP4
+	select HWSPINLOCK
 	help
 	  Say y here to support the OMAP Hardware Spinlock device (firstly
 	  introduced in OMAP4).
 
 	  If unsure, say N.
+
+endmenu
-- 
1.7.4.1

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

* [PATCH 01/10] hwspinlock/core: simplify Kconfig
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

Simplify hwspinlock's Kconfig by making the global CONFIG_HWSPINLOCK
entry invisible; users will just select it when needed.

This also prepares the ground for adding hwspinlock support for other
platforms (the 'depends on ARCH_OMAP4' was rather hideous, and while
we're at it, a dedicated menu is added).

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index 1f29bab..c8e7bda 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -2,22 +2,20 @@
 # Generic HWSPINLOCK framework
 #
 
+# HWSPINLOCK always gets selected by whoever wants it.
 config HWSPINLOCK
-	tristate "Generic Hardware Spinlock framework"
-	depends on ARCH_OMAP4
-	help
-	  Say y here to support the generic hardware spinlock framework.
-	  You only need to enable this if you have hardware spinlock module
-	  on your system (usually only relevant if your system has remote slave
-	  coprocessors).
+	tristate
 
-	  If unsure, say N.
+menu "Hardware Spinlock drivers"
 
 config HWSPINLOCK_OMAP
 	tristate "OMAP Hardware Spinlock device"
-	depends on HWSPINLOCK && ARCH_OMAP4
+	depends on ARCH_OMAP4
+	select HWSPINLOCK
 	help
 	  Say y here to support the OMAP Hardware Spinlock device (firstly
 	  introduced in OMAP4).
 
 	  If unsure, say N.
+
+endmenu
-- 
1.7.4.1

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

* [PATCH 02/10] hwspinlock/core: simplify 'owner' handling
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Use struct device_driver's owner member instead of asking drivers to
explicitly pass the owner again.

This simplifies drivers and also save some memory, since there's no
point now in maintaining a separate owner pointer per hwspinlock.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |    6 ++----
 drivers/hwspinlock/hwspinlock_core.c     |    4 ++--
 drivers/hwspinlock/hwspinlock_internal.h |    4 +---
 drivers/hwspinlock/omap_hwspinlock.c     |    2 +-
 4 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 7dcd1a4..bbaa464 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -256,18 +256,16 @@ underlying hwspinlock implementation using the hwspin_lock_register() API.
  * @ops: vendor-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  */
 struct hwspinlock {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
-The underlying implementation is responsible to assign the dev, ops, id and
-owner members. The lock member, OTOH, is initialized and used by the hwspinlock
+The underlying implementation is responsible to assign the dev, ops and id
+members. The lock member, OTOH, is initialized and used by the hwspinlock
 core.
 
 6. Implementation callbacks
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 43a6271..af5175c 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -352,7 +352,7 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->owner)) {
+	if (!try_module_get(hwlock->dev->driver->owner)) {
 		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
@@ -535,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->owner);
+	module_put(hwlock->dev->driver->owner);
 
 out:
 	spin_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index 69935e6..fb25830 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -44,10 +44,9 @@ struct hwspinlock_ops {
  * @ops: platform-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  *
  * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping the dev, ops and owner members in a single
+ * memory bytes by grouping dev, ops in a single
  * per-platform struct, and have all hwspinlocks point at it.
  */
 struct hwspinlock {
@@ -55,7 +54,6 @@ struct hwspinlock {
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index a8f0273..1d19fe9 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -143,7 +143,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		}
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.owner = THIS_MODULE;
 		omap_lock->lock.id = i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
@@ -208,6 +207,7 @@ static struct platform_driver omap_hwspinlock_driver = {
 	.remove		= omap_hwspinlock_remove,
 	.driver		= {
 		.name	= "omap_hwspinlock",
+		.owner	= THIS_MODULE,
 	},
 };
 
-- 
1.7.4.1


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

* [PATCH 02/10] hwspinlock/core: simplify 'owner' handling
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Use struct device_driver's owner member instead of asking drivers to
explicitly pass the owner again.

This simplifies drivers and also save some memory, since there's no
point now in maintaining a separate owner pointer per hwspinlock.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |    6 ++----
 drivers/hwspinlock/hwspinlock_core.c     |    4 ++--
 drivers/hwspinlock/hwspinlock_internal.h |    4 +---
 drivers/hwspinlock/omap_hwspinlock.c     |    2 +-
 4 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 7dcd1a4..bbaa464 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -256,18 +256,16 @@ underlying hwspinlock implementation using the hwspin_lock_register() API.
  * @ops: vendor-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  */
 struct hwspinlock {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
-The underlying implementation is responsible to assign the dev, ops, id and
-owner members. The lock member, OTOH, is initialized and used by the hwspinlock
+The underlying implementation is responsible to assign the dev, ops and id
+members. The lock member, OTOH, is initialized and used by the hwspinlock
 core.
 
 6. Implementation callbacks
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 43a6271..af5175c 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -352,7 +352,7 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->owner)) {
+	if (!try_module_get(hwlock->dev->driver->owner)) {
 		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
@@ -535,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->owner);
+	module_put(hwlock->dev->driver->owner);
 
 out:
 	spin_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index 69935e6..fb25830 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -44,10 +44,9 @@ struct hwspinlock_ops {
  * @ops: platform-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  *
  * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping the dev, ops and owner members in a single
+ * memory bytes by grouping dev, ops in a single
  * per-platform struct, and have all hwspinlocks point at it.
  */
 struct hwspinlock {
@@ -55,7 +54,6 @@ struct hwspinlock {
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index a8f0273..1d19fe9 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -143,7 +143,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		}
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.owner = THIS_MODULE;
 		omap_lock->lock.id = i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
@@ -208,6 +207,7 @@ static struct platform_driver omap_hwspinlock_driver = {
 	.remove		= omap_hwspinlock_remove,
 	.driver		= {
 		.name	= "omap_hwspinlock",
+		.owner	= THIS_MODULE,
 	},
 };
 
-- 
1.7.4.1

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

* [PATCH 02/10] hwspinlock/core: simplify 'owner' handling
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

Use struct device_driver's owner member instead of asking drivers to
explicitly pass the owner again.

This simplifies drivers and also save some memory, since there's no
point now in maintaining a separate owner pointer per hwspinlock.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |    6 ++----
 drivers/hwspinlock/hwspinlock_core.c     |    4 ++--
 drivers/hwspinlock/hwspinlock_internal.h |    4 +---
 drivers/hwspinlock/omap_hwspinlock.c     |    2 +-
 4 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 7dcd1a4..bbaa464 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -256,18 +256,16 @@ underlying hwspinlock implementation using the hwspin_lock_register() API.
  * @ops: vendor-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  */
 struct hwspinlock {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
-The underlying implementation is responsible to assign the dev, ops, id and
-owner members. The lock member, OTOH, is initialized and used by the hwspinlock
+The underlying implementation is responsible to assign the dev, ops and id
+members. The lock member, OTOH, is initialized and used by the hwspinlock
 core.
 
 6. Implementation callbacks
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 43a6271..af5175c 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -352,7 +352,7 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock)
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->owner)) {
+	if (!try_module_get(hwlock->dev->driver->owner)) {
 		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
@@ -535,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->owner);
+	module_put(hwlock->dev->driver->owner);
 
 out:
 	spin_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index 69935e6..fb25830 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -44,10 +44,9 @@ struct hwspinlock_ops {
  * @ops: platform-specific hwspinlock handlers
  * @id: a global, unique, system-wide, index of the lock.
  * @lock: initialized and used by hwspinlock core
- * @owner: underlying implementation module, used to maintain module ref count
  *
  * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping the dev, ops and owner members in a single
+ * memory bytes by grouping dev, ops in a single
  * per-platform struct, and have all hwspinlocks point at it.
  */
 struct hwspinlock {
@@ -55,7 +54,6 @@ struct hwspinlock {
 	const struct hwspinlock_ops *ops;
 	int id;
 	spinlock_t lock;
-	struct module *owner;
 };
 
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index a8f0273..1d19fe9 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -143,7 +143,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		}
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.owner = THIS_MODULE;
 		omap_lock->lock.id = i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
@@ -208,6 +207,7 @@ static struct platform_driver omap_hwspinlock_driver = {
 	.remove		= omap_hwspinlock_remove,
 	.driver		= {
 		.name	= "omap_hwspinlock",
+		.owner	= THIS_MODULE,
 	},
 };
 
-- 
1.7.4.1

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

* [PATCH 03/10] hwspinlock/omap: simplify allocation scheme
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Instead of allocating every hwspinlock separately, allocate
them all in one shot.

This both simplifies the driver and helps achieving better
slab utilization.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |   51 +++++++++++----------------------
 1 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 1d19fe9..d058348 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -52,6 +52,7 @@ struct omap_hwspinlock {
 struct omap_hwspinlock_state {
 	int num_locks;			/* Total number of locks in system */
 	void __iomem *io_base;		/* Mapped base address */
+	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
 };
 
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
@@ -95,7 +96,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
-	struct hwspinlock *lock;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
@@ -104,15 +104,9 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
 	io_base = ioremap(res->start, resource_size(res));
-	if (!io_base) {
-		ret = -ENOMEM;
-		goto free_state;
-	}
+	if (!io_base)
+		return -ENOMEM;
 
 	/* Determine number of locks */
 	i = readl(io_base + SYSSTATUS_OFFSET);
@@ -124,7 +118,15 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	state->num_locks = i * 32;
+	i *= 32; /* actual number of locks in this device */
+
+	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
+	if (!state) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	state->num_locks = i;
 	state->io_base = io_base;
 
 	platform_set_drvdata(pdev, state);
@@ -136,11 +138,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 
 	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = kzalloc(sizeof(*omap_lock), GFP_KERNEL);
-		if (!omap_lock) {
-			ret = -ENOMEM;
-			goto free_locks;
-		}
+		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
 		omap_lock->lock.id = i;
@@ -148,30 +146,19 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret) {
-			kfree(omap_lock);
+		if (ret)
 			goto free_locks;
-		}
 	}
 
 	return 0;
 
 free_locks:
-	while (--i >= 0) {
-		lock = hwspin_lock_unregister(i);
-		/* this should't happen, but let's give our best effort */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: cleanups failed\n", __func__);
-			continue;
-		}
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
-	}
+	while (--i >= 0)
+		hwspin_lock_unregister(i);
 	pm_runtime_disable(&pdev->dev);
+	kfree(state);
 iounmap_base:
 	iounmap(io_base);
-free_state:
-	kfree(state);
 	return ret;
 }
 
@@ -179,7 +166,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
 	struct hwspinlock *lock;
-	struct omap_hwspinlock *omap_lock;
 	int i;
 
 	for (i = 0; i < state->num_locks; i++) {
@@ -190,9 +176,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
 			return -EBUSY;
 		}
-
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
 	}
 
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.4.1


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

* [PATCH 03/10] hwspinlock/omap: simplify allocation scheme
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Ohad Ben-Cohen, Arnd Bergmann

Instead of allocating every hwspinlock separately, allocate
them all in one shot.

This both simplifies the driver and helps achieving better
slab utilization.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |   51 +++++++++++----------------------
 1 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 1d19fe9..d058348 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -52,6 +52,7 @@ struct omap_hwspinlock {
 struct omap_hwspinlock_state {
 	int num_locks;			/* Total number of locks in system */
 	void __iomem *io_base;		/* Mapped base address */
+	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
 };
 
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
@@ -95,7 +96,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
-	struct hwspinlock *lock;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
@@ -104,15 +104,9 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
 	io_base = ioremap(res->start, resource_size(res));
-	if (!io_base) {
-		ret = -ENOMEM;
-		goto free_state;
-	}
+	if (!io_base)
+		return -ENOMEM;
 
 	/* Determine number of locks */
 	i = readl(io_base + SYSSTATUS_OFFSET);
@@ -124,7 +118,15 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	state->num_locks = i * 32;
+	i *= 32; /* actual number of locks in this device */
+
+	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
+	if (!state) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	state->num_locks = i;
 	state->io_base = io_base;
 
 	platform_set_drvdata(pdev, state);
@@ -136,11 +138,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 
 	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = kzalloc(sizeof(*omap_lock), GFP_KERNEL);
-		if (!omap_lock) {
-			ret = -ENOMEM;
-			goto free_locks;
-		}
+		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
 		omap_lock->lock.id = i;
@@ -148,30 +146,19 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret) {
-			kfree(omap_lock);
+		if (ret)
 			goto free_locks;
-		}
 	}
 
 	return 0;
 
 free_locks:
-	while (--i >= 0) {
-		lock = hwspin_lock_unregister(i);
-		/* this should't happen, but let's give our best effort */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: cleanups failed\n", __func__);
-			continue;
-		}
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
-	}
+	while (--i >= 0)
+		hwspin_lock_unregister(i);
 	pm_runtime_disable(&pdev->dev);
+	kfree(state);
 iounmap_base:
 	iounmap(io_base);
-free_state:
-	kfree(state);
 	return ret;
 }
 
@@ -179,7 +166,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
 	struct hwspinlock *lock;
-	struct omap_hwspinlock *omap_lock;
 	int i;
 
 	for (i = 0; i < state->num_locks; i++) {
@@ -190,9 +176,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
 			return -EBUSY;
 		}
-
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
 	}
 
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.4.1

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

* [PATCH 03/10] hwspinlock/omap: simplify allocation scheme
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of allocating every hwspinlock separately, allocate
them all in one shot.

This both simplifies the driver and helps achieving better
slab utilization.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |   51 +++++++++++----------------------
 1 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 1d19fe9..d058348 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -52,6 +52,7 @@ struct omap_hwspinlock {
 struct omap_hwspinlock_state {
 	int num_locks;			/* Total number of locks in system */
 	void __iomem *io_base;		/* Mapped base address */
+	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
 };
 
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
@@ -95,7 +96,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
-	struct hwspinlock *lock;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
@@ -104,15 +104,9 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
 	io_base = ioremap(res->start, resource_size(res));
-	if (!io_base) {
-		ret = -ENOMEM;
-		goto free_state;
-	}
+	if (!io_base)
+		return -ENOMEM;
 
 	/* Determine number of locks */
 	i = readl(io_base + SYSSTATUS_OFFSET);
@@ -124,7 +118,15 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	state->num_locks = i * 32;
+	i *= 32; /* actual number of locks in this device */
+
+	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
+	if (!state) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	state->num_locks = i;
 	state->io_base = io_base;
 
 	platform_set_drvdata(pdev, state);
@@ -136,11 +138,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 
 	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = kzalloc(sizeof(*omap_lock), GFP_KERNEL);
-		if (!omap_lock) {
-			ret = -ENOMEM;
-			goto free_locks;
-		}
+		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
 		omap_lock->lock.id = i;
@@ -148,30 +146,19 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret) {
-			kfree(omap_lock);
+		if (ret)
 			goto free_locks;
-		}
 	}
 
 	return 0;
 
 free_locks:
-	while (--i >= 0) {
-		lock = hwspin_lock_unregister(i);
-		/* this should't happen, but let's give our best effort */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: cleanups failed\n", __func__);
-			continue;
-		}
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
-	}
+	while (--i >= 0)
+		hwspin_lock_unregister(i);
 	pm_runtime_disable(&pdev->dev);
+	kfree(state);
 iounmap_base:
 	iounmap(io_base);
-free_state:
-	kfree(state);
 	return ret;
 }
 
@@ -179,7 +166,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
 	struct hwspinlock *lock;
-	struct omap_hwspinlock *omap_lock;
 	int i;
 
 	for (i = 0; i < state->num_locks; i++) {
@@ -190,9 +176,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
 			return -EBUSY;
 		}
-
-		omap_lock = to_omap_hwspinlock(lock);
-		kfree(omap_lock);
 	}
 
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.4.1

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

* [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

hwspinlock devices provide system-wide hardware locks that are used
by remote processors that have no other way to achieve synchronization.

For that to work, each physical lock must have a system-wide unique id
number that all processors are familiar with, otherwise they can't
possibly assume they're using the same hardware lock.

Usually SoCs have a single hwspinlock device, which provides several
hwspinlocks, and in this case, they can be trivially numbered 0 to
(num-of-locks - 1).

In case boards have several hwspinlocks devices (each of which
providing numerous hardware spinlocks) a different base id should be
used for each hwspinlock device (they can't all use 0 as a starting
id!).

While this is certainly not common, it's just plain wrong to just
silently use 0 as a base id whenever the hwspinlock driver is probed.

This patch provides a hwspinlock_pdata structure, that boards can use
to set a different base id for each of the hwspinlock devices they may
have, and demonstrates how to use it with the omap hwspinlock driver
(ultimately it will be DT which will supply this base_id information).

While we're at it, make sure the hwspinlock core prints an explicit
error message in case an hwspinlock is registered with an id number
that already exists; this will help users catch such base id issues.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/hwspinlock.c     |    8 +++++++-
 drivers/hwspinlock/hwspinlock_core.c |    2 ++
 drivers/hwspinlock/omap_hwspinlock.c |    6 +++++-
 include/linux/hwspinlock.h           |   28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 06d4a80..eb7e509 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -19,10 +19,15 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/hwspinlock.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
+	.base_id = 0,
+};
+
 struct omap_device_pm_latency omap_spinlock_latency[] = {
 	{
 		.deactivate_func = omap_device_idle_hwmods,
@@ -48,7 +53,8 @@ int __init hwspinlocks_init(void)
 	if (oh == NULL)
 		return -EINVAL;
 
-	od = omap_device_build(dev_name, 0, oh, NULL, 0,
+	od = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
+				sizeof(struct hwspinlock_pdata),
 				omap_spinlock_latency,
 				ARRAY_SIZE(omap_spinlock_latency), false);
 	if (IS_ERR(od)) {
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index af5175c..4eb85b4 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -282,6 +282,8 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	spin_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
+	if (ret == -EEXIST)
+		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
 	if (ret)
 		goto out;
 
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index d058348..2044d18 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -94,12 +94,16 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
 
+	if (!pdata)
+		return -ENODEV;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
@@ -141,7 +145,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = i;
+		omap_lock->lock.id = pdata->base_id + i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 8390efc..f85cef5 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -27,6 +27,34 @@
 
 struct hwspinlock;
 
+/**
+ * struct hwspinlock_pdata - platform data for hwspinlock drivers
+ * @base_id: base id for this hwspinlock device
+ *
+ * hwspinlock devices provide system-wide hardware locks that are used
+ * by remote processors that have no other way to achieve synchronization.
+ *
+ * To achieve that, each physical lock must have a system-wide id number
+ * that is agreed upon, otherwise remote processors can't possibly assume
+ * they're using the same hardware lock.
+ *
+ * Usually boards have a single hwspinlock device, which provides several
+ * hwspinlocks, and in this case, they can be trivially numbered 0 to
+ * (num-of-locks - 1).
+ *
+ * In case boards have several hwspinlocks devices, a different base id
+ * should be used for each hwspinlock device (they can't all use 0 as
+ * a starting id!).
+ *
+ * This platform data structure should be used to provide the base id
+ * for each device (which is trivially 0 when only a single hwspinlock
+ * device exists). It can be shared between different platforms, hence
+ * its location.
+ */
+struct hwspinlock_pdata {
+	int base_id;
+};
+
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
 int hwspin_lock_register(struct hwspinlock *lock);
-- 
1.7.4.1


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

* [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

hwspinlock devices provide system-wide hardware locks that are used
by remote processors that have no other way to achieve synchronization.

For that to work, each physical lock must have a system-wide unique id
number that all processors are familiar with, otherwise they can't
possibly assume they're using the same hardware lock.

Usually SoCs have a single hwspinlock device, which provides several
hwspinlocks, and in this case, they can be trivially numbered 0 to
(num-of-locks - 1).

In case boards have several hwspinlocks devices (each of which
providing numerous hardware spinlocks) a different base id should be
used for each hwspinlock device (they can't all use 0 as a starting
id!).

While this is certainly not common, it's just plain wrong to just
silently use 0 as a base id whenever the hwspinlock driver is probed.

This patch provides a hwspinlock_pdata structure, that boards can use
to set a different base id for each of the hwspinlock devices they may
have, and demonstrates how to use it with the omap hwspinlock driver
(ultimately it will be DT which will supply this base_id information).

While we're at it, make sure the hwspinlock core prints an explicit
error message in case an hwspinlock is registered with an id number
that already exists; this will help users catch such base id issues.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/hwspinlock.c     |    8 +++++++-
 drivers/hwspinlock/hwspinlock_core.c |    2 ++
 drivers/hwspinlock/omap_hwspinlock.c |    6 +++++-
 include/linux/hwspinlock.h           |   28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 06d4a80..eb7e509 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -19,10 +19,15 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/hwspinlock.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
+	.base_id = 0,
+};
+
 struct omap_device_pm_latency omap_spinlock_latency[] = {
 	{
 		.deactivate_func = omap_device_idle_hwmods,
@@ -48,7 +53,8 @@ int __init hwspinlocks_init(void)
 	if (oh == NULL)
 		return -EINVAL;
 
-	od = omap_device_build(dev_name, 0, oh, NULL, 0,
+	od = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
+				sizeof(struct hwspinlock_pdata),
 				omap_spinlock_latency,
 				ARRAY_SIZE(omap_spinlock_latency), false);
 	if (IS_ERR(od)) {
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index af5175c..4eb85b4 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -282,6 +282,8 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	spin_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
+	if (ret == -EEXIST)
+		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
 	if (ret)
 		goto out;
 
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index d058348..2044d18 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -94,12 +94,16 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
 
+	if (!pdata)
+		return -ENODEV;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
@@ -141,7 +145,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = i;
+		omap_lock->lock.id = pdata->base_id + i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 8390efc..f85cef5 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -27,6 +27,34 @@
 
 struct hwspinlock;
 
+/**
+ * struct hwspinlock_pdata - platform data for hwspinlock drivers
+ * @base_id: base id for this hwspinlock device
+ *
+ * hwspinlock devices provide system-wide hardware locks that are used
+ * by remote processors that have no other way to achieve synchronization.
+ *
+ * To achieve that, each physical lock must have a system-wide id number
+ * that is agreed upon, otherwise remote processors can't possibly assume
+ * they're using the same hardware lock.
+ *
+ * Usually boards have a single hwspinlock device, which provides several
+ * hwspinlocks, and in this case, they can be trivially numbered 0 to
+ * (num-of-locks - 1).
+ *
+ * In case boards have several hwspinlocks devices, a different base id
+ * should be used for each hwspinlock device (they can't all use 0 as
+ * a starting id!).
+ *
+ * This platform data structure should be used to provide the base id
+ * for each device (which is trivially 0 when only a single hwspinlock
+ * device exists). It can be shared between different platforms, hence
+ * its location.
+ */
+struct hwspinlock_pdata {
+	int base_id;
+};
+
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
 int hwspin_lock_register(struct hwspinlock *lock);
-- 
1.7.4.1

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

* [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
@ 2011-09-12 16:46   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

hwspinlock devices provide system-wide hardware locks that are used
by remote processors that have no other way to achieve synchronization.

For that to work, each physical lock must have a system-wide unique id
number that all processors are familiar with, otherwise they can't
possibly assume they're using the same hardware lock.

Usually SoCs have a single hwspinlock device, which provides several
hwspinlocks, and in this case, they can be trivially numbered 0 to
(num-of-locks - 1).

In case boards have several hwspinlocks devices (each of which
providing numerous hardware spinlocks) a different base id should be
used for each hwspinlock device (they can't all use 0 as a starting
id!).

While this is certainly not common, it's just plain wrong to just
silently use 0 as a base id whenever the hwspinlock driver is probed.

This patch provides a hwspinlock_pdata structure, that boards can use
to set a different base id for each of the hwspinlock devices they may
have, and demonstrates how to use it with the omap hwspinlock driver
(ultimately it will be DT which will supply this base_id information).

While we're at it, make sure the hwspinlock core prints an explicit
error message in case an hwspinlock is registered with an id number
that already exists; this will help users catch such base id issues.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 arch/arm/mach-omap2/hwspinlock.c     |    8 +++++++-
 drivers/hwspinlock/hwspinlock_core.c |    2 ++
 drivers/hwspinlock/omap_hwspinlock.c |    6 +++++-
 include/linux/hwspinlock.h           |   28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 06d4a80..eb7e509 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -19,10 +19,15 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/hwspinlock.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
+	.base_id = 0,
+};
+
 struct omap_device_pm_latency omap_spinlock_latency[] = {
 	{
 		.deactivate_func = omap_device_idle_hwmods,
@@ -48,7 +53,8 @@ int __init hwspinlocks_init(void)
 	if (oh == NULL)
 		return -EINVAL;
 
-	od = omap_device_build(dev_name, 0, oh, NULL, 0,
+	od = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
+				sizeof(struct hwspinlock_pdata),
 				omap_spinlock_latency,
 				ARRAY_SIZE(omap_spinlock_latency), false);
 	if (IS_ERR(od)) {
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index af5175c..4eb85b4 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -282,6 +282,8 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	spin_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
+	if (ret == -EEXIST)
+		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
 	if (ret)
 		goto out;
 
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index d058348..2044d18 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -94,12 +94,16 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
 	struct omap_hwspinlock *omap_lock;
 	struct omap_hwspinlock_state *state;
 	struct resource *res;
 	void __iomem *io_base;
 	int i, ret;
 
+	if (!pdata)
+		return -ENODEV;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
@@ -141,7 +145,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		omap_lock = &state->lock[i];
 
 		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = i;
+		omap_lock->lock.id = pdata->base_id + i;
 		omap_lock->lock.ops = &omap_hwspinlock_ops;
 		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 8390efc..f85cef5 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -27,6 +27,34 @@
 
 struct hwspinlock;
 
+/**
+ * struct hwspinlock_pdata - platform data for hwspinlock drivers
+ * @base_id: base id for this hwspinlock device
+ *
+ * hwspinlock devices provide system-wide hardware locks that are used
+ * by remote processors that have no other way to achieve synchronization.
+ *
+ * To achieve that, each physical lock must have a system-wide id number
+ * that is agreed upon, otherwise remote processors can't possibly assume
+ * they're using the same hardware lock.
+ *
+ * Usually boards have a single hwspinlock device, which provides several
+ * hwspinlocks, and in this case, they can be trivially numbered 0 to
+ * (num-of-locks - 1).
+ *
+ * In case boards have several hwspinlocks devices, a different base id
+ * should be used for each hwspinlock device (they can't all use 0 as
+ * a starting id!).
+ *
+ * This platform data structure should be used to provide the base id
+ * for each device (which is trivially 0 when only a single hwspinlock
+ * device exists). It can be shared between different platforms, hence
+ * its location.
+ */
+struct hwspinlock_pdata {
+	int base_id;
+};
+
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
 int hwspin_lock_register(struct hwspinlock *lock);
-- 
1.7.4.1

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

* [PATCH 05/10] hwspinlock/core: use a mutex to protect the radix tree
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Juan Gutierrez, Ohad Ben-Cohen

From: Juan Gutierrez <jgutierrez@ti.com>

Since we're using non-atomic radix tree allocations, we
should be protecting the tree using a mutex and not a
spinlock.

Non-atomic allocations and process context locking is good enough,
as the tree is manipulated only when locks are registered/
unregistered/requested/freed.

The locks themselves are still protected by spinlocks of course,
and mutexes are not involved in the locking/unlocking paths.

Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
[ohad@wizery.com: rewrite the commit log, #include mutex.h, add minor
commentary]
[ohad@wizery.com: update register/unregister parts in hwspinlock.txt]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt         |   18 +++++--------
 drivers/hwspinlock/hwspinlock_core.c |   45 +++++++++++++++-------------------
 2 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index bbaa464..9171f91 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -39,23 +39,20 @@ independent, drivers.
      in case an unused hwspinlock isn't available. Users of this
      API will usually want to communicate the lock's id to the remote core
      before it can be used to achieve synchronization.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
    - assign a specific hwspinlock id and return its address, or NULL
      if that hwspinlock is already in use. Usually board code will
      be calling this function in order to reserve specific hwspinlock
      ids for predefined purposes.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_free(struct hwspinlock *hwlock);
    - free a previously-assigned hwspinlock; returns 0 on success, or an
      appropriate error code on failure (e.g. -EINVAL if the hwspinlock
      is already free).
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
    - lock a previously-assigned hwspinlock with a timeout limit (specified in
@@ -232,15 +229,14 @@ int hwspinlock_example2(void)
 
   int hwspin_lock_register(struct hwspinlock *hwlock);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Can be called from an atomic
-     context (this function will not sleep) but not from within interrupt
-     context. Returns 0 on success, or appropriate error code on failure.
+     order to register a new hwspinlock instance. Should be called from
+     a process context (this function might sleep).
+     Returns 0 on success, or appropriate error code on failure.
 
   struct hwspinlock *hwspin_lock_unregister(unsigned int id);
    - to be called from the underlying vendor-specific implementation, in order
      to unregister an existing (and unused) hwspinlock instance.
-     Can be called from an atomic context (will not sleep) but not from
-     within interrupt context.
+     Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 4eb85b4..0d20b82 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -26,6 +26,7 @@
 #include <linux/radix-tree.h>
 #include <linux/hwspinlock.h>
 #include <linux/pm_runtime.h>
+#include <linux/mutex.h>
 
 #include "hwspinlock_internal.h"
 
@@ -52,10 +53,12 @@
 static RADIX_TREE(hwspinlock_tree, GFP_KERNEL);
 
 /*
- * Synchronization of access to the tree is achieved using this spinlock,
+ * Synchronization of access to the tree is achieved using this mutex,
  * as the radix-tree API requires that users provide all synchronisation.
+ * A mutex is needed because we're using non-atomic radix tree allocations.
  */
-static DEFINE_SPINLOCK(hwspinlock_tree_lock);
+static DEFINE_MUTEX(hwspinlock_tree_lock);
+
 
 /**
  * __hwspin_trylock() - attempt to lock a specific hwspinlock
@@ -261,8 +264,7 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock);
  * This function should be called from the underlying platform-specific
  * implementation, to register a new hwspinlock instance.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -279,7 +281,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 
 	spin_lock_init(&hwlock->lock);
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
 	if (ret == -EEXIST)
@@ -295,7 +297,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	WARN_ON(tmp != hwlock);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_register);
@@ -307,8 +309,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register);
  * This function should be called from the underlying platform-specific
  * implementation, to unregister an existing (and unused) hwspinlock.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of hwspinlock @id on success, or NULL on failure
  */
@@ -317,7 +318,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	struct hwspinlock *hwlock = NULL;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is not in use (tag is set) */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -333,7 +334,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	}
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
@@ -402,9 +403,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
  * to the remote core before it can be used for synchronization (to get the
  * id of a given hwlock, use hwspin_lock_get_id()).
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -413,7 +412,7 @@ struct hwspinlock *hwspin_lock_request(void)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* look for an unused lock */
 	ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock,
@@ -433,7 +432,7 @@ struct hwspinlock *hwspin_lock_request(void)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request);
@@ -447,9 +446,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request);
  * Usually early board code will be calling this function in order to
  * reserve specific hwspinlock ids for predefined purposes.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -458,7 +455,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure this hwspinlock exists */
 	hwlock = radix_tree_lookup(&hwspinlock_tree, id);
@@ -484,7 +481,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
@@ -497,9 +494,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  * Should only be called with an @hwlock that was retrieved from
  * an earlier call to omap_hwspin_lock_request{_specific}.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -513,7 +508,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
 	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
@@ -540,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	module_put(hwlock->dev->driver->owner);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_free);
-- 
1.7.4.1


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

* [PATCH 05/10] hwspinlock/core: use a mutex to protect the radix tree
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Juan Gutierrez, Ohad Ben-Cohen

From: Juan Gutierrez <jgutierrez@ti.com>

Since we're using non-atomic radix tree allocations, we
should be protecting the tree using a mutex and not a
spinlock.

Non-atomic allocations and process context locking is good enough,
as the tree is manipulated only when locks are registered/
unregistered/requested/freed.

The locks themselves are still protected by spinlocks of course,
and mutexes are not involved in the locking/unlocking paths.

Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
[ohad@wizery.com: rewrite the commit log, #include mutex.h, add minor
commentary]
[ohad@wizery.com: update register/unregister parts in hwspinlock.txt]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt         |   18 +++++--------
 drivers/hwspinlock/hwspinlock_core.c |   45 +++++++++++++++-------------------
 2 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index bbaa464..9171f91 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -39,23 +39,20 @@ independent, drivers.
      in case an unused hwspinlock isn't available. Users of this
      API will usually want to communicate the lock's id to the remote core
      before it can be used to achieve synchronization.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
    - assign a specific hwspinlock id and return its address, or NULL
      if that hwspinlock is already in use. Usually board code will
      be calling this function in order to reserve specific hwspinlock
      ids for predefined purposes.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_free(struct hwspinlock *hwlock);
    - free a previously-assigned hwspinlock; returns 0 on success, or an
      appropriate error code on failure (e.g. -EINVAL if the hwspinlock
      is already free).
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
    - lock a previously-assigned hwspinlock with a timeout limit (specified in
@@ -232,15 +229,14 @@ int hwspinlock_example2(void)
 
   int hwspin_lock_register(struct hwspinlock *hwlock);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Can be called from an atomic
-     context (this function will not sleep) but not from within interrupt
-     context. Returns 0 on success, or appropriate error code on failure.
+     order to register a new hwspinlock instance. Should be called from
+     a process context (this function might sleep).
+     Returns 0 on success, or appropriate error code on failure.
 
   struct hwspinlock *hwspin_lock_unregister(unsigned int id);
    - to be called from the underlying vendor-specific implementation, in order
      to unregister an existing (and unused) hwspinlock instance.
-     Can be called from an atomic context (will not sleep) but not from
-     within interrupt context.
+     Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 4eb85b4..0d20b82 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -26,6 +26,7 @@
 #include <linux/radix-tree.h>
 #include <linux/hwspinlock.h>
 #include <linux/pm_runtime.h>
+#include <linux/mutex.h>
 
 #include "hwspinlock_internal.h"
 
@@ -52,10 +53,12 @@
 static RADIX_TREE(hwspinlock_tree, GFP_KERNEL);
 
 /*
- * Synchronization of access to the tree is achieved using this spinlock,
+ * Synchronization of access to the tree is achieved using this mutex,
  * as the radix-tree API requires that users provide all synchronisation.
+ * A mutex is needed because we're using non-atomic radix tree allocations.
  */
-static DEFINE_SPINLOCK(hwspinlock_tree_lock);
+static DEFINE_MUTEX(hwspinlock_tree_lock);
+
 
 /**
  * __hwspin_trylock() - attempt to lock a specific hwspinlock
@@ -261,8 +264,7 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock);
  * This function should be called from the underlying platform-specific
  * implementation, to register a new hwspinlock instance.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -279,7 +281,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 
 	spin_lock_init(&hwlock->lock);
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
 	if (ret == -EEXIST)
@@ -295,7 +297,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	WARN_ON(tmp != hwlock);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_register);
@@ -307,8 +309,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register);
  * This function should be called from the underlying platform-specific
  * implementation, to unregister an existing (and unused) hwspinlock.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of hwspinlock @id on success, or NULL on failure
  */
@@ -317,7 +318,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	struct hwspinlock *hwlock = NULL;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is not in use (tag is set) */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -333,7 +334,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	}
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
@@ -402,9 +403,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
  * to the remote core before it can be used for synchronization (to get the
  * id of a given hwlock, use hwspin_lock_get_id()).
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -413,7 +412,7 @@ struct hwspinlock *hwspin_lock_request(void)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* look for an unused lock */
 	ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock,
@@ -433,7 +432,7 @@ struct hwspinlock *hwspin_lock_request(void)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request);
@@ -447,9 +446,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request);
  * Usually early board code will be calling this function in order to
  * reserve specific hwspinlock ids for predefined purposes.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -458,7 +455,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure this hwspinlock exists */
 	hwlock = radix_tree_lookup(&hwspinlock_tree, id);
@@ -484,7 +481,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
@@ -497,9 +494,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  * Should only be called with an @hwlock that was retrieved from
  * an earlier call to omap_hwspin_lock_request{_specific}.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -513,7 +508,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
 	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
@@ -540,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	module_put(hwlock->dev->driver->owner);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_free);
-- 
1.7.4.1

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

* [PATCH 05/10] hwspinlock/core: use a mutex to protect the radix tree
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Juan Gutierrez <jgutierrez@ti.com>

Since we're using non-atomic radix tree allocations, we
should be protecting the tree using a mutex and not a
spinlock.

Non-atomic allocations and process context locking is good enough,
as the tree is manipulated only when locks are registered/
unregistered/requested/freed.

The locks themselves are still protected by spinlocks of course,
and mutexes are not involved in the locking/unlocking paths.

Signed-off-by: Juan Gutierrez <jgutierrez@ti.com>
[ohad at wizery.com: rewrite the commit log, #include mutex.h, add minor
commentary]
[ohad at wizery.com: update register/unregister parts in hwspinlock.txt]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt         |   18 +++++--------
 drivers/hwspinlock/hwspinlock_core.c |   45 +++++++++++++++-------------------
 2 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index bbaa464..9171f91 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -39,23 +39,20 @@ independent, drivers.
      in case an unused hwspinlock isn't available. Users of this
      API will usually want to communicate the lock's id to the remote core
      before it can be used to achieve synchronization.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
    - assign a specific hwspinlock id and return its address, or NULL
      if that hwspinlock is already in use. Usually board code will
      be calling this function in order to reserve specific hwspinlock
      ids for predefined purposes.
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_free(struct hwspinlock *hwlock);
    - free a previously-assigned hwspinlock; returns 0 on success, or an
      appropriate error code on failure (e.g. -EINVAL if the hwspinlock
      is already free).
-     Can be called from an atomic context (this function will not sleep) but
-     not from within interrupt context.
+     Should be called from a process context (might sleep).
 
   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
    - lock a previously-assigned hwspinlock with a timeout limit (specified in
@@ -232,15 +229,14 @@ int hwspinlock_example2(void)
 
   int hwspin_lock_register(struct hwspinlock *hwlock);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Can be called from an atomic
-     context (this function will not sleep) but not from within interrupt
-     context. Returns 0 on success, or appropriate error code on failure.
+     order to register a new hwspinlock instance. Should be called from
+     a process context (this function might sleep).
+     Returns 0 on success, or appropriate error code on failure.
 
   struct hwspinlock *hwspin_lock_unregister(unsigned int id);
    - to be called from the underlying vendor-specific implementation, in order
      to unregister an existing (and unused) hwspinlock instance.
-     Can be called from an atomic context (will not sleep) but not from
-     within interrupt context.
+     Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 4eb85b4..0d20b82 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -26,6 +26,7 @@
 #include <linux/radix-tree.h>
 #include <linux/hwspinlock.h>
 #include <linux/pm_runtime.h>
+#include <linux/mutex.h>
 
 #include "hwspinlock_internal.h"
 
@@ -52,10 +53,12 @@
 static RADIX_TREE(hwspinlock_tree, GFP_KERNEL);
 
 /*
- * Synchronization of access to the tree is achieved using this spinlock,
+ * Synchronization of access to the tree is achieved using this mutex,
  * as the radix-tree API requires that users provide all synchronisation.
+ * A mutex is needed because we're using non-atomic radix tree allocations.
  */
-static DEFINE_SPINLOCK(hwspinlock_tree_lock);
+static DEFINE_MUTEX(hwspinlock_tree_lock);
+
 
 /**
  * __hwspin_trylock() - attempt to lock a specific hwspinlock
@@ -261,8 +264,7 @@ EXPORT_SYMBOL_GPL(__hwspin_unlock);
  * This function should be called from the underlying platform-specific
  * implementation, to register a new hwspinlock instance.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -279,7 +281,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 
 	spin_lock_init(&hwlock->lock);
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
 	if (ret == -EEXIST)
@@ -295,7 +297,7 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
 	WARN_ON(tmp != hwlock);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_register);
@@ -307,8 +309,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_register);
  * This function should be called from the underlying platform-specific
  * implementation, to unregister an existing (and unused) hwspinlock.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context.
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of hwspinlock @id on success, or NULL on failure
  */
@@ -317,7 +318,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	struct hwspinlock *hwlock = NULL;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is not in use (tag is set) */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -333,7 +334,7 @@ struct hwspinlock *hwspin_lock_unregister(unsigned int id)
 	}
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
@@ -402,9 +403,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
  * to the remote core before it can be used for synchronization (to get the
  * id of a given hwlock, use hwspin_lock_get_id()).
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -413,7 +412,7 @@ struct hwspinlock *hwspin_lock_request(void)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* look for an unused lock */
 	ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock,
@@ -433,7 +432,7 @@ struct hwspinlock *hwspin_lock_request(void)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request);
@@ -447,9 +446,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request);
  * Usually early board code will be calling this function in order to
  * reserve specific hwspinlock ids for predefined purposes.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns the address of the assigned hwspinlock, or NULL on error
  */
@@ -458,7 +455,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	struct hwspinlock *hwlock;
 	int ret;
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure this hwspinlock exists */
 	hwlock = radix_tree_lookup(&hwspinlock_tree, id);
@@ -484,7 +481,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 		hwlock = NULL;
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
@@ -497,9 +494,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  * Should only be called with an @hwlock that was retrieved from
  * an earlier call to omap_hwspin_lock_request{_specific}.
  *
- * Can be called from an atomic context (will not sleep) but not from
- * within interrupt context (simply because there is no use case for
- * that yet).
+ * Should be called from a process context (might sleep)
  *
  * Returns 0 on success, or an appropriate error code on failure
  */
@@ -513,7 +508,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	spin_lock(&hwspinlock_tree_lock);
+	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
 	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
@@ -540,7 +535,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	module_put(hwlock->dev->driver->owner);
 
 out:
-	spin_unlock(&hwspinlock_tree_lock);
+	mutex_unlock(&hwspinlock_tree_lock);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_free);
-- 
1.7.4.1

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

* [PATCH 06/10] hwspinlock/core: remove stubs for register/unregister
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

hwspinlock drivers must anyway select CONFIG_HWSPINLOCK,
so there's no point in having register/unregister stubs.

Removing those stubs will only make it easier for developers
to catch CONFIG_HWSPINLOCK mis-.config-urations.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 include/linux/hwspinlock.h |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index f85cef5..c246522 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -122,16 +122,6 @@ static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
 	return 0;
 }
 
-static inline int hwspin_lock_register(struct hwspinlock *hwlock)
-{
-	return -ENODEV;
-}
-
-static inline struct hwspinlock *hwspin_lock_unregister(unsigned int id)
-{
-	return NULL;
-}
-
 #endif /* !CONFIG_HWSPINLOCK */
 
 /**
-- 
1.7.4.1


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

* [PATCH 06/10] hwspinlock/core: remove stubs for register/unregister
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

hwspinlock drivers must anyway select CONFIG_HWSPINLOCK,
so there's no point in having register/unregister stubs.

Removing those stubs will only make it easier for developers
to catch CONFIG_HWSPINLOCK mis-.config-urations.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 include/linux/hwspinlock.h |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index f85cef5..c246522 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -122,16 +122,6 @@ static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
 	return 0;
 }
 
-static inline int hwspin_lock_register(struct hwspinlock *hwlock)
-{
-	return -ENODEV;
-}
-
-static inline struct hwspinlock *hwspin_lock_unregister(unsigned int id)
-{
-	return NULL;
-}
-
 #endif /* !CONFIG_HWSPINLOCK */
 
 /**
-- 
1.7.4.1

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

* [PATCH 06/10] hwspinlock/core: remove stubs for register/unregister
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

hwspinlock drivers must anyway select CONFIG_HWSPINLOCK,
so there's no point in having register/unregister stubs.

Removing those stubs will only make it easier for developers
to catch CONFIG_HWSPINLOCK mis-.config-urations.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 include/linux/hwspinlock.h |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index f85cef5..c246522 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -122,16 +122,6 @@ static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
 	return 0;
 }
 
-static inline int hwspin_lock_register(struct hwspinlock *hwlock)
-{
-	return -ENODEV;
-}
-
-static inline struct hwspinlock *hwspin_lock_unregister(unsigned int id)
-{
-	return NULL;
-}
-
 #endif /* !CONFIG_HWSPINLOCK */
 
 /**
-- 
1.7.4.1

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

* [PATCH 07/10] hwspinlock/core: register a bank of hwspinlocks in a single API call
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Hardware Spinlock devices usually contain numerous locks (known
devices today support between 32 to 256 locks).

Originally hwspinlock core required drivers to register (and later,
when needed, unregister) each lock separately.

That worked, but required hwspinlocks drivers to do a bit extra work
when they were probed/removed.

This patch changes hwspin_lock_{un}register() to allow a bank of
hwspinlocks to be {un}registered in a single invocation.

A new 'struct hwspinlock_device', which contains an array of 'struct
hwspinlock's is now being passed to the core upon registration (so
instead of wrapping each struct hwspinlock, a priv member has been added
to allow drivers to piggyback their private data with each hwspinlock).

While at it, several per-lock members were moved to be per-device:
1. struct device *dev
2. struct hwspinlock_ops *ops

In addition, now that the array of locks is handled by the core,
there's no reason to maintain a per-lock 'int id' member: the id of the
lock anyway equals to its index in the bank's array plus the bank's
base_id.
Remove this per-lock id member too, and instead use a simple pointers
arithmetic to derive it.

As a result of this change, hwspinlocks drivers are now simpler and smaller
(about %20 code reduction) and the memory footprint of the hwspinlock
framework is reduced.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |   58 +++++++----
 drivers/hwspinlock/hwspinlock_core.c     |  165 ++++++++++++++++++++----------
 drivers/hwspinlock/hwspinlock_internal.h |   38 +++++--
 drivers/hwspinlock/omap_hwspinlock.c     |   86 +++++----------
 include/linux/hwspinlock.h               |    8 +-
 5 files changed, 211 insertions(+), 144 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 9171f91..a903ee5 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -227,42 +227,62 @@ int hwspinlock_example2(void)
 
 4. API for implementors
 
-  int hwspin_lock_register(struct hwspinlock *hwlock);
+  int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Should be called from
-     a process context (this function might sleep).
+     order to register a new hwspinlock device (which is usually a bank of
+     numerous locks). Should be called from a process context (this function
+     might sleep).
      Returns 0 on success, or appropriate error code on failure.
 
-  struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+  int hwspin_lock_unregister(struct hwspinlock_device *bank);
    - to be called from the underlying vendor-specific implementation, in order
-     to unregister an existing (and unused) hwspinlock instance.
+     to unregister an hwspinlock device (which is usually a bank of numerous
+     locks).
      Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
-5. struct hwspinlock
+5. Important structs
 
-This struct represents an hwspinlock instance. It is registered by the
-underlying hwspinlock implementation using the hwspin_lock_register() API.
+struct hwspinlock_device is a device which usually contains a bank
+of hardware locks. It is registered by the underlying hwspinlock
+implementation using the hwspin_lock_register() API.
 
 /**
- * struct hwspinlock - vendor-specific hwspinlock implementation
- *
- * @dev: underlying device, will be used with runtime PM api
- * @ops: vendor-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
- * @lock: initialized and used by hwspinlock core
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
  */
-struct hwspinlock {
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
+};
+
+struct hwspinlock_device contains an array of hwspinlock structs, each
+of which represents a single hardware lock:
+
+/**
+ * struct hwspinlock - this struct represents a single hwspinlock instance
+ * @bank: the hwspinlock_device structure which owns this lock
+ * @lock: initialized and used by hwspinlock core
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
+ */
+struct hwspinlock {
+	struct hwspinlock_device *bank;
 	spinlock_t lock;
+	void *priv;
 };
 
-The underlying implementation is responsible to assign the dev, ops and id
-members. The lock member, OTOH, is initialized and used by the hwspinlock
-core.
+When registering a bank of locks, the hwspinlock driver only needs to
+set the priv members of the locks. The rest of the members are set and
+initialized by the hwspinlock core itself.
 
 6. Implementation callbacks
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 0d20b82..61c9cf1 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -117,7 +117,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 		return -EBUSY;
 
 	/* try to take the hwspinlock device */
-	ret = hwlock->ops->trylock(hwlock);
+	ret = hwlock->bank->ops->trylock(hwlock);
 
 	/* if hwlock is already taken, undo spin_trylock_* and exit */
 	if (!ret) {
@@ -199,8 +199,8 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
 		 * Allow platform-specific relax handlers to prevent
 		 * hogging the interconnect (no sleeping, though)
 		 */
-		if (hwlock->ops->relax)
-			hwlock->ops->relax(hwlock);
+		if (hwlock->bank->ops->relax)
+			hwlock->bank->ops->relax(hwlock);
 	}
 
 	return ret;
@@ -245,7 +245,7 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 	 */
 	mb();
 
-	hwlock->ops->unlock(hwlock);
+	hwlock->bank->ops->unlock(hwlock);
 
 	/* Undo the spin_trylock{_irq, _irqsave} called while locking */
 	if (mode == HWLOCK_IRQSTATE)
@@ -257,63 +257,32 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 }
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
-/**
- * hwspin_lock_register() - register a new hw spinlock
- * @hwlock: hwspinlock to register.
- *
- * This function should be called from the underlying platform-specific
- * implementation, to register a new hwspinlock instance.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns 0 on success, or an appropriate error code on failure
- */
-int hwspin_lock_register(struct hwspinlock *hwlock)
+static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
 {
 	struct hwspinlock *tmp;
 	int ret;
 
-	if (!hwlock || !hwlock->ops ||
-		!hwlock->ops->trylock || !hwlock->ops->unlock) {
-		pr_err("invalid parameters\n");
-		return -EINVAL;
-	}
-
-	spin_lock_init(&hwlock->lock);
-
 	mutex_lock(&hwspinlock_tree_lock);
 
-	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
-	if (ret == -EEXIST)
-		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
-	if (ret)
+	ret = radix_tree_insert(&hwspinlock_tree, id, hwlock);
+	if (ret) {
+		if (ret == -EEXIST)
+			pr_err("hwspinlock id %d already exists!\n", id);
 		goto out;
+	}
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
-							HWSPINLOCK_UNUSED);
+	tmp = radix_tree_tag_set(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
 
 	/* self-sanity check which should never fail */
 	WARN_ON(tmp != hwlock);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
-	return ret;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(hwspin_lock_register);
 
-/**
- * hwspin_lock_unregister() - unregister an hw spinlock
- * @id: index of the specific hwspinlock to unregister
- *
- * This function should be called from the underlying platform-specific
- * implementation, to unregister an existing (and unused) hwspinlock.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns the address of hwspinlock @id on success, or NULL on failure
- */
-struct hwspinlock *hwspin_lock_unregister(unsigned int id)
+static struct hwspinlock *hwspin_lock_unregister_single(unsigned int id)
 {
 	struct hwspinlock *hwlock = NULL;
 	int ret;
@@ -337,6 +306,88 @@ out:
 	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
+
+/**
+ * hwspin_lock_register() - register a new hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ * @dev: the backing device
+ * @ops: hwspinlock handlers for this device
+ * @base_id: id of the first hardware spinlock in this bank
+ * @num_locks: number of hwspinlocks provided by this device
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to register a new hwspinlock device instance.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks)
+{
+	struct hwspinlock *hwlock;
+	int ret = 0, i;
+
+	if (!bank || !ops || !dev || !num_locks || !ops->trylock ||
+							!ops->unlock) {
+		pr_err("invalid parameters\n");
+		return -EINVAL;
+	}
+
+	bank->dev = dev;
+	bank->ops = ops;
+	bank->base_id = base_id;
+	bank->num_locks = num_locks;
+
+	for (i = 0; i < num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		spin_lock_init(&hwlock->lock);
+		hwlock->bank = bank;
+
+		ret = hwspin_lock_register_single(hwlock, i);
+		if (ret)
+			goto reg_failed;
+	}
+
+	return 0;
+
+reg_failed:
+	while (--i >= 0)
+		hwspin_lock_unregister_single(i);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hwspin_lock_register);
+
+/**
+ * hwspin_lock_unregister() - unregister an hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to unregister an existing (and unused) hwspinlock.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_unregister(struct hwspinlock_device *bank)
+{
+	struct hwspinlock *hwlock, *tmp;
+	int i;
+
+	for (i = 0; i < bank->num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		tmp = hwspin_lock_unregister_single(bank->base_id + i);
+		if (!tmp)
+			return -EBUSY;
+
+		/* self-sanity check that should never fail */
+		WARN_ON(tmp != hwlock);
+	}
+
+	return 0;
+}
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
 
 /**
@@ -351,24 +402,25 @@ EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
  */
 static int __hwspin_lock_request(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->dev->driver->owner)) {
-		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
+	if (!try_module_get(dev->driver->owner)) {
+		dev_err(dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
 
 	/* notify PM core that power is now needed */
-	ret = pm_runtime_get_sync(hwlock->dev);
+	ret = pm_runtime_get_sync(dev);
 	if (ret < 0) {
-		dev_err(hwlock->dev, "%s: can't power on device\n", __func__);
+		dev_err(dev, "%s: can't power on device\n", __func__);
 		return ret;
 	}
 
 	/* mark hwspinlock as used, should not fail */
-	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* self-sanity check that should never fail */
@@ -390,7 +442,7 @@ int hwspin_lock_get_id(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	return hwlock->id;
+	return hwlock_to_id(hwlock);
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
 
@@ -465,7 +517,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	}
 
 	/* sanity check (this shouldn't happen) */
-	WARN_ON(hwlock->id != id);
+	WARN_ON(hwlock_to_id(hwlock) != id);
 
 	/* make sure this hwspinlock is unused */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -500,6 +552,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  */
 int hwspin_lock_free(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
@@ -511,28 +564,28 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
-	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
+	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 	if (ret == 1) {
-		dev_err(hwlock->dev, "%s: hwlock is already free\n", __func__);
+		dev_err(dev, "%s: hwlock is already free\n", __func__);
 		dump_stack();
 		ret = -EINVAL;
 		goto out;
 	}
 
 	/* notify the underlying device that power is not needed */
-	ret = pm_runtime_put(hwlock->dev);
+	ret = pm_runtime_put(dev);
 	if (ret < 0)
 		goto out;
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->dev->driver->owner);
+	module_put(dev->driver->owner);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index fb25830..d26f78b 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,8 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
+struct hwspinlock_device;
+
 /**
  * struct hwspinlock_ops - platform-specific hwspinlock handlers
  *
@@ -39,21 +41,37 @@ struct hwspinlock_ops {
 
 /**
  * struct hwspinlock - this struct represents a single hwspinlock instance
- *
- * @dev: underlying device, will be used to invoke runtime PM api
- * @ops: platform-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
+ * @bank: the hwspinlock_device structure which owns this lock
  * @lock: initialized and used by hwspinlock core
- *
- * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping dev, ops in a single
- * per-platform struct, and have all hwspinlocks point at it.
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
  */
 struct hwspinlock {
+	struct hwspinlock_device *bank;
+	spinlock_t lock;
+	void *priv;
+};
+
+/**
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
+ */
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
-	spinlock_t lock;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
 };
 
+static inline int hwlock_to_id(struct hwspinlock *hwlock)
+{
+	int local_id = hwlock - &hwlock->bank->lock[0];
+
+	return hwlock->bank->base_id + local_id;
+}
+
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 2044d18..aec3006 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -41,34 +41,20 @@
 #define SPINLOCK_NOTTAKEN		(0)	/* free */
 #define SPINLOCK_TAKEN			(1)	/* locked */
 
-#define to_omap_hwspinlock(lock)	\
-	container_of(lock, struct omap_hwspinlock, lock)
-
-struct omap_hwspinlock {
-	struct hwspinlock lock;
-	void __iomem *addr;
-};
-
-struct omap_hwspinlock_state {
-	int num_locks;			/* Total number of locks in system */
-	void __iomem *io_base;		/* Mapped base address */
-	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
-};
-
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* attempt to acquire the lock by reading its value */
-	return (SPINLOCK_NOTTAKEN == readl(omap_lock->addr));
+	return (SPINLOCK_NOTTAKEN == readl(lock_addr));
 }
 
 static void omap_hwspinlock_unlock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* release the lock by writing 0 to it */
-	writel(SPINLOCK_NOTTAKEN, omap_lock->addr);
+	writel(SPINLOCK_NOTTAKEN, lock_addr);
 }
 
 /*
@@ -95,11 +81,11 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
-	struct omap_hwspinlock *omap_lock;
-	struct omap_hwspinlock_state *state;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
 	struct resource *res;
 	void __iomem *io_base;
-	int i, ret;
+	int num_locks, i, ret;
 
 	if (!pdata)
 		return -ENODEV;
@@ -122,18 +108,18 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	i *= 32; /* actual number of locks in this device */
+	num_locks = i * 32; /* actual number of locks in this device */
 
-	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
-	if (!state) {
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
 		ret = -ENOMEM;
 		goto iounmap_base;
 	}
 
-	state->num_locks = i;
-	state->io_base = io_base;
+	platform_set_drvdata(pdev, bank);
 
-	platform_set_drvdata(pdev, state);
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 	/*
 	 * runtime PM will make sure the clock of this module is
@@ -141,26 +127,16 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_enable(&pdev->dev);
 
-	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = &state->lock[i];
-
-		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = pdata->base_id + i;
-		omap_lock->lock.ops = &omap_hwspinlock_ops;
-		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
-
-		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret)
-			goto free_locks;
-	}
+	ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
 
 	return 0;
 
-free_locks:
-	while (--i >= 0)
-		hwspin_lock_unregister(i);
+reg_fail:
 	pm_runtime_disable(&pdev->dev);
-	kfree(state);
+	kfree(bank);
 iounmap_base:
 	iounmap(io_base);
 	return ret;
@@ -168,23 +144,19 @@ iounmap_base:
 
 static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
-	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
-	struct hwspinlock *lock;
-	int i;
-
-	for (i = 0; i < state->num_locks; i++) {
-		lock = hwspin_lock_unregister(i);
-		/* this shouldn't happen at this point. if it does, at least
-		 * don't continue with the remove */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
-			return -EBUSY;
-		}
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
+	int ret;
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
 	}
 
 	pm_runtime_disable(&pdev->dev);
-	iounmap(state->io_base);
-	kfree(state);
+	iounmap(io_base);
+	kfree(bank);
 
 	return 0;
 }
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index c246522..08a2fee 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -20,12 +20,15 @@
 
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 
 /* hwspinlock mode argument */
 #define HWLOCK_IRQSTATE	0x01	/* Disable interrupts, save state */
 #define HWLOCK_IRQ	0x02	/* Disable interrupts, don't save state */
 
 struct hwspinlock;
+struct hwspinlock_device;
+struct hwspinlock_ops;
 
 /**
  * struct hwspinlock_pdata - platform data for hwspinlock drivers
@@ -57,8 +60,9 @@ struct hwspinlock_pdata {
 
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
-int hwspin_lock_register(struct hwspinlock *lock);
-struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
+int hwspin_lock_unregister(struct hwspinlock_device *bank);
 struct hwspinlock *hwspin_lock_request(void);
 struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
 int hwspin_lock_free(struct hwspinlock *hwlock);
-- 
1.7.4.1


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

* [PATCH 07/10] hwspinlock/core: register a bank of hwspinlocks in a single API call
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Hardware Spinlock devices usually contain numerous locks (known
devices today support between 32 to 256 locks).

Originally hwspinlock core required drivers to register (and later,
when needed, unregister) each lock separately.

That worked, but required hwspinlocks drivers to do a bit extra work
when they were probed/removed.

This patch changes hwspin_lock_{un}register() to allow a bank of
hwspinlocks to be {un}registered in a single invocation.

A new 'struct hwspinlock_device', which contains an array of 'struct
hwspinlock's is now being passed to the core upon registration (so
instead of wrapping each struct hwspinlock, a priv member has been added
to allow drivers to piggyback their private data with each hwspinlock).

While at it, several per-lock members were moved to be per-device:
1. struct device *dev
2. struct hwspinlock_ops *ops

In addition, now that the array of locks is handled by the core,
there's no reason to maintain a per-lock 'int id' member: the id of the
lock anyway equals to its index in the bank's array plus the bank's
base_id.
Remove this per-lock id member too, and instead use a simple pointers
arithmetic to derive it.

As a result of this change, hwspinlocks drivers are now simpler and smaller
(about %20 code reduction) and the memory footprint of the hwspinlock
framework is reduced.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |   58 +++++++----
 drivers/hwspinlock/hwspinlock_core.c     |  165 ++++++++++++++++++++----------
 drivers/hwspinlock/hwspinlock_internal.h |   38 +++++--
 drivers/hwspinlock/omap_hwspinlock.c     |   86 +++++----------
 include/linux/hwspinlock.h               |    8 +-
 5 files changed, 211 insertions(+), 144 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 9171f91..a903ee5 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -227,42 +227,62 @@ int hwspinlock_example2(void)
 
 4. API for implementors
 
-  int hwspin_lock_register(struct hwspinlock *hwlock);
+  int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Should be called from
-     a process context (this function might sleep).
+     order to register a new hwspinlock device (which is usually a bank of
+     numerous locks). Should be called from a process context (this function
+     might sleep).
      Returns 0 on success, or appropriate error code on failure.
 
-  struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+  int hwspin_lock_unregister(struct hwspinlock_device *bank);
    - to be called from the underlying vendor-specific implementation, in order
-     to unregister an existing (and unused) hwspinlock instance.
+     to unregister an hwspinlock device (which is usually a bank of numerous
+     locks).
      Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
-5. struct hwspinlock
+5. Important structs
 
-This struct represents an hwspinlock instance. It is registered by the
-underlying hwspinlock implementation using the hwspin_lock_register() API.
+struct hwspinlock_device is a device which usually contains a bank
+of hardware locks. It is registered by the underlying hwspinlock
+implementation using the hwspin_lock_register() API.
 
 /**
- * struct hwspinlock - vendor-specific hwspinlock implementation
- *
- * @dev: underlying device, will be used with runtime PM api
- * @ops: vendor-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
- * @lock: initialized and used by hwspinlock core
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
  */
-struct hwspinlock {
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
+};
+
+struct hwspinlock_device contains an array of hwspinlock structs, each
+of which represents a single hardware lock:
+
+/**
+ * struct hwspinlock - this struct represents a single hwspinlock instance
+ * @bank: the hwspinlock_device structure which owns this lock
+ * @lock: initialized and used by hwspinlock core
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
+ */
+struct hwspinlock {
+	struct hwspinlock_device *bank;
 	spinlock_t lock;
+	void *priv;
 };
 
-The underlying implementation is responsible to assign the dev, ops and id
-members. The lock member, OTOH, is initialized and used by the hwspinlock
-core.
+When registering a bank of locks, the hwspinlock driver only needs to
+set the priv members of the locks. The rest of the members are set and
+initialized by the hwspinlock core itself.
 
 6. Implementation callbacks
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 0d20b82..61c9cf1 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -117,7 +117,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 		return -EBUSY;
 
 	/* try to take the hwspinlock device */
-	ret = hwlock->ops->trylock(hwlock);
+	ret = hwlock->bank->ops->trylock(hwlock);
 
 	/* if hwlock is already taken, undo spin_trylock_* and exit */
 	if (!ret) {
@@ -199,8 +199,8 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
 		 * Allow platform-specific relax handlers to prevent
 		 * hogging the interconnect (no sleeping, though)
 		 */
-		if (hwlock->ops->relax)
-			hwlock->ops->relax(hwlock);
+		if (hwlock->bank->ops->relax)
+			hwlock->bank->ops->relax(hwlock);
 	}
 
 	return ret;
@@ -245,7 +245,7 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 	 */
 	mb();
 
-	hwlock->ops->unlock(hwlock);
+	hwlock->bank->ops->unlock(hwlock);
 
 	/* Undo the spin_trylock{_irq, _irqsave} called while locking */
 	if (mode == HWLOCK_IRQSTATE)
@@ -257,63 +257,32 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 }
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
-/**
- * hwspin_lock_register() - register a new hw spinlock
- * @hwlock: hwspinlock to register.
- *
- * This function should be called from the underlying platform-specific
- * implementation, to register a new hwspinlock instance.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns 0 on success, or an appropriate error code on failure
- */
-int hwspin_lock_register(struct hwspinlock *hwlock)
+static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
 {
 	struct hwspinlock *tmp;
 	int ret;
 
-	if (!hwlock || !hwlock->ops ||
-		!hwlock->ops->trylock || !hwlock->ops->unlock) {
-		pr_err("invalid parameters\n");
-		return -EINVAL;
-	}
-
-	spin_lock_init(&hwlock->lock);
-
 	mutex_lock(&hwspinlock_tree_lock);
 
-	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
-	if (ret == -EEXIST)
-		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
-	if (ret)
+	ret = radix_tree_insert(&hwspinlock_tree, id, hwlock);
+	if (ret) {
+		if (ret == -EEXIST)
+			pr_err("hwspinlock id %d already exists!\n", id);
 		goto out;
+	}
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
-							HWSPINLOCK_UNUSED);
+	tmp = radix_tree_tag_set(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
 
 	/* self-sanity check which should never fail */
 	WARN_ON(tmp != hwlock);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
-	return ret;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(hwspin_lock_register);
 
-/**
- * hwspin_lock_unregister() - unregister an hw spinlock
- * @id: index of the specific hwspinlock to unregister
- *
- * This function should be called from the underlying platform-specific
- * implementation, to unregister an existing (and unused) hwspinlock.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns the address of hwspinlock @id on success, or NULL on failure
- */
-struct hwspinlock *hwspin_lock_unregister(unsigned int id)
+static struct hwspinlock *hwspin_lock_unregister_single(unsigned int id)
 {
 	struct hwspinlock *hwlock = NULL;
 	int ret;
@@ -337,6 +306,88 @@ out:
 	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
+
+/**
+ * hwspin_lock_register() - register a new hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ * @dev: the backing device
+ * @ops: hwspinlock handlers for this device
+ * @base_id: id of the first hardware spinlock in this bank
+ * @num_locks: number of hwspinlocks provided by this device
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to register a new hwspinlock device instance.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks)
+{
+	struct hwspinlock *hwlock;
+	int ret = 0, i;
+
+	if (!bank || !ops || !dev || !num_locks || !ops->trylock ||
+							!ops->unlock) {
+		pr_err("invalid parameters\n");
+		return -EINVAL;
+	}
+
+	bank->dev = dev;
+	bank->ops = ops;
+	bank->base_id = base_id;
+	bank->num_locks = num_locks;
+
+	for (i = 0; i < num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		spin_lock_init(&hwlock->lock);
+		hwlock->bank = bank;
+
+		ret = hwspin_lock_register_single(hwlock, i);
+		if (ret)
+			goto reg_failed;
+	}
+
+	return 0;
+
+reg_failed:
+	while (--i >= 0)
+		hwspin_lock_unregister_single(i);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hwspin_lock_register);
+
+/**
+ * hwspin_lock_unregister() - unregister an hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to unregister an existing (and unused) hwspinlock.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_unregister(struct hwspinlock_device *bank)
+{
+	struct hwspinlock *hwlock, *tmp;
+	int i;
+
+	for (i = 0; i < bank->num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		tmp = hwspin_lock_unregister_single(bank->base_id + i);
+		if (!tmp)
+			return -EBUSY;
+
+		/* self-sanity check that should never fail */
+		WARN_ON(tmp != hwlock);
+	}
+
+	return 0;
+}
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
 
 /**
@@ -351,24 +402,25 @@ EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
  */
 static int __hwspin_lock_request(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->dev->driver->owner)) {
-		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
+	if (!try_module_get(dev->driver->owner)) {
+		dev_err(dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
 
 	/* notify PM core that power is now needed */
-	ret = pm_runtime_get_sync(hwlock->dev);
+	ret = pm_runtime_get_sync(dev);
 	if (ret < 0) {
-		dev_err(hwlock->dev, "%s: can't power on device\n", __func__);
+		dev_err(dev, "%s: can't power on device\n", __func__);
 		return ret;
 	}
 
 	/* mark hwspinlock as used, should not fail */
-	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* self-sanity check that should never fail */
@@ -390,7 +442,7 @@ int hwspin_lock_get_id(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	return hwlock->id;
+	return hwlock_to_id(hwlock);
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
 
@@ -465,7 +517,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	}
 
 	/* sanity check (this shouldn't happen) */
-	WARN_ON(hwlock->id != id);
+	WARN_ON(hwlock_to_id(hwlock) != id);
 
 	/* make sure this hwspinlock is unused */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -500,6 +552,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  */
 int hwspin_lock_free(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
@@ -511,28 +564,28 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
-	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
+	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 	if (ret == 1) {
-		dev_err(hwlock->dev, "%s: hwlock is already free\n", __func__);
+		dev_err(dev, "%s: hwlock is already free\n", __func__);
 		dump_stack();
 		ret = -EINVAL;
 		goto out;
 	}
 
 	/* notify the underlying device that power is not needed */
-	ret = pm_runtime_put(hwlock->dev);
+	ret = pm_runtime_put(dev);
 	if (ret < 0)
 		goto out;
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->dev->driver->owner);
+	module_put(dev->driver->owner);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index fb25830..d26f78b 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,8 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
+struct hwspinlock_device;
+
 /**
  * struct hwspinlock_ops - platform-specific hwspinlock handlers
  *
@@ -39,21 +41,37 @@ struct hwspinlock_ops {
 
 /**
  * struct hwspinlock - this struct represents a single hwspinlock instance
- *
- * @dev: underlying device, will be used to invoke runtime PM api
- * @ops: platform-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
+ * @bank: the hwspinlock_device structure which owns this lock
  * @lock: initialized and used by hwspinlock core
- *
- * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping dev, ops in a single
- * per-platform struct, and have all hwspinlocks point at it.
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
  */
 struct hwspinlock {
+	struct hwspinlock_device *bank;
+	spinlock_t lock;
+	void *priv;
+};
+
+/**
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
+ */
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
-	spinlock_t lock;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
 };
 
+static inline int hwlock_to_id(struct hwspinlock *hwlock)
+{
+	int local_id = hwlock - &hwlock->bank->lock[0];
+
+	return hwlock->bank->base_id + local_id;
+}
+
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 2044d18..aec3006 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -41,34 +41,20 @@
 #define SPINLOCK_NOTTAKEN		(0)	/* free */
 #define SPINLOCK_TAKEN			(1)	/* locked */
 
-#define to_omap_hwspinlock(lock)	\
-	container_of(lock, struct omap_hwspinlock, lock)
-
-struct omap_hwspinlock {
-	struct hwspinlock lock;
-	void __iomem *addr;
-};
-
-struct omap_hwspinlock_state {
-	int num_locks;			/* Total number of locks in system */
-	void __iomem *io_base;		/* Mapped base address */
-	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
-};
-
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* attempt to acquire the lock by reading its value */
-	return (SPINLOCK_NOTTAKEN == readl(omap_lock->addr));
+	return (SPINLOCK_NOTTAKEN == readl(lock_addr));
 }
 
 static void omap_hwspinlock_unlock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* release the lock by writing 0 to it */
-	writel(SPINLOCK_NOTTAKEN, omap_lock->addr);
+	writel(SPINLOCK_NOTTAKEN, lock_addr);
 }
 
 /*
@@ -95,11 +81,11 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
-	struct omap_hwspinlock *omap_lock;
-	struct omap_hwspinlock_state *state;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
 	struct resource *res;
 	void __iomem *io_base;
-	int i, ret;
+	int num_locks, i, ret;
 
 	if (!pdata)
 		return -ENODEV;
@@ -122,18 +108,18 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	i *= 32; /* actual number of locks in this device */
+	num_locks = i * 32; /* actual number of locks in this device */
 
-	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
-	if (!state) {
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
 		ret = -ENOMEM;
 		goto iounmap_base;
 	}
 
-	state->num_locks = i;
-	state->io_base = io_base;
+	platform_set_drvdata(pdev, bank);
 
-	platform_set_drvdata(pdev, state);
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 	/*
 	 * runtime PM will make sure the clock of this module is
@@ -141,26 +127,16 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_enable(&pdev->dev);
 
-	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = &state->lock[i];
-
-		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = pdata->base_id + i;
-		omap_lock->lock.ops = &omap_hwspinlock_ops;
-		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
-
-		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret)
-			goto free_locks;
-	}
+	ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
 
 	return 0;
 
-free_locks:
-	while (--i >= 0)
-		hwspin_lock_unregister(i);
+reg_fail:
 	pm_runtime_disable(&pdev->dev);
-	kfree(state);
+	kfree(bank);
 iounmap_base:
 	iounmap(io_base);
 	return ret;
@@ -168,23 +144,19 @@ iounmap_base:
 
 static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
-	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
-	struct hwspinlock *lock;
-	int i;
-
-	for (i = 0; i < state->num_locks; i++) {
-		lock = hwspin_lock_unregister(i);
-		/* this shouldn't happen at this point. if it does, at least
-		 * don't continue with the remove */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
-			return -EBUSY;
-		}
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
+	int ret;
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
 	}
 
 	pm_runtime_disable(&pdev->dev);
-	iounmap(state->io_base);
-	kfree(state);
+	iounmap(io_base);
+	kfree(bank);
 
 	return 0;
 }
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index c246522..08a2fee 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -20,12 +20,15 @@
 
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 
 /* hwspinlock mode argument */
 #define HWLOCK_IRQSTATE	0x01	/* Disable interrupts, save state */
 #define HWLOCK_IRQ	0x02	/* Disable interrupts, don't save state */
 
 struct hwspinlock;
+struct hwspinlock_device;
+struct hwspinlock_ops;
 
 /**
  * struct hwspinlock_pdata - platform data for hwspinlock drivers
@@ -57,8 +60,9 @@ struct hwspinlock_pdata {
 
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
-int hwspin_lock_register(struct hwspinlock *lock);
-struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
+int hwspin_lock_unregister(struct hwspinlock_device *bank);
 struct hwspinlock *hwspin_lock_request(void);
 struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
 int hwspin_lock_free(struct hwspinlock *hwlock);
-- 
1.7.4.1

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

* [PATCH 07/10] hwspinlock/core: register a bank of hwspinlocks in a single API call
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hardware Spinlock devices usually contain numerous locks (known
devices today support between 32 to 256 locks).

Originally hwspinlock core required drivers to register (and later,
when needed, unregister) each lock separately.

That worked, but required hwspinlocks drivers to do a bit extra work
when they were probed/removed.

This patch changes hwspin_lock_{un}register() to allow a bank of
hwspinlocks to be {un}registered in a single invocation.

A new 'struct hwspinlock_device', which contains an array of 'struct
hwspinlock's is now being passed to the core upon registration (so
instead of wrapping each struct hwspinlock, a priv member has been added
to allow drivers to piggyback their private data with each hwspinlock).

While at it, several per-lock members were moved to be per-device:
1. struct device *dev
2. struct hwspinlock_ops *ops

In addition, now that the array of locks is handled by the core,
there's no reason to maintain a per-lock 'int id' member: the id of the
lock anyway equals to its index in the bank's array plus the bank's
base_id.
Remove this per-lock id member too, and instead use a simple pointers
arithmetic to derive it.

As a result of this change, hwspinlocks drivers are now simpler and smaller
(about %20 code reduction) and the memory footprint of the hwspinlock
framework is reduced.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 Documentation/hwspinlock.txt             |   58 +++++++----
 drivers/hwspinlock/hwspinlock_core.c     |  165 ++++++++++++++++++++----------
 drivers/hwspinlock/hwspinlock_internal.h |   38 +++++--
 drivers/hwspinlock/omap_hwspinlock.c     |   86 +++++----------
 include/linux/hwspinlock.h               |    8 +-
 5 files changed, 211 insertions(+), 144 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 9171f91..a903ee5 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -227,42 +227,62 @@ int hwspinlock_example2(void)
 
 4. API for implementors
 
-  int hwspin_lock_register(struct hwspinlock *hwlock);
+  int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
    - to be called from the underlying platform-specific implementation, in
-     order to register a new hwspinlock instance. Should be called from
-     a process context (this function might sleep).
+     order to register a new hwspinlock device (which is usually a bank of
+     numerous locks). Should be called from a process context (this function
+     might sleep).
      Returns 0 on success, or appropriate error code on failure.
 
-  struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+  int hwspin_lock_unregister(struct hwspinlock_device *bank);
    - to be called from the underlying vendor-specific implementation, in order
-     to unregister an existing (and unused) hwspinlock instance.
+     to unregister an hwspinlock device (which is usually a bank of numerous
+     locks).
      Should be called from a process context (this function might sleep).
      Returns the address of hwspinlock on success, or NULL on error (e.g.
      if the hwspinlock is sill in use).
 
-5. struct hwspinlock
+5. Important structs
 
-This struct represents an hwspinlock instance. It is registered by the
-underlying hwspinlock implementation using the hwspin_lock_register() API.
+struct hwspinlock_device is a device which usually contains a bank
+of hardware locks. It is registered by the underlying hwspinlock
+implementation using the hwspin_lock_register() API.
 
 /**
- * struct hwspinlock - vendor-specific hwspinlock implementation
- *
- * @dev: underlying device, will be used with runtime PM api
- * @ops: vendor-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
- * @lock: initialized and used by hwspinlock core
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
  */
-struct hwspinlock {
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
+};
+
+struct hwspinlock_device contains an array of hwspinlock structs, each
+of which represents a single hardware lock:
+
+/**
+ * struct hwspinlock - this struct represents a single hwspinlock instance
+ * @bank: the hwspinlock_device structure which owns this lock
+ * @lock: initialized and used by hwspinlock core
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
+ */
+struct hwspinlock {
+	struct hwspinlock_device *bank;
 	spinlock_t lock;
+	void *priv;
 };
 
-The underlying implementation is responsible to assign the dev, ops and id
-members. The lock member, OTOH, is initialized and used by the hwspinlock
-core.
+When registering a bank of locks, the hwspinlock driver only needs to
+set the priv members of the locks. The rest of the members are set and
+initialized by the hwspinlock core itself.
 
 6. Implementation callbacks
 
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 0d20b82..61c9cf1 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -117,7 +117,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 		return -EBUSY;
 
 	/* try to take the hwspinlock device */
-	ret = hwlock->ops->trylock(hwlock);
+	ret = hwlock->bank->ops->trylock(hwlock);
 
 	/* if hwlock is already taken, undo spin_trylock_* and exit */
 	if (!ret) {
@@ -199,8 +199,8 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
 		 * Allow platform-specific relax handlers to prevent
 		 * hogging the interconnect (no sleeping, though)
 		 */
-		if (hwlock->ops->relax)
-			hwlock->ops->relax(hwlock);
+		if (hwlock->bank->ops->relax)
+			hwlock->bank->ops->relax(hwlock);
 	}
 
 	return ret;
@@ -245,7 +245,7 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 	 */
 	mb();
 
-	hwlock->ops->unlock(hwlock);
+	hwlock->bank->ops->unlock(hwlock);
 
 	/* Undo the spin_trylock{_irq, _irqsave} called while locking */
 	if (mode == HWLOCK_IRQSTATE)
@@ -257,63 +257,32 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 }
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
-/**
- * hwspin_lock_register() - register a new hw spinlock
- * @hwlock: hwspinlock to register.
- *
- * This function should be called from the underlying platform-specific
- * implementation, to register a new hwspinlock instance.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns 0 on success, or an appropriate error code on failure
- */
-int hwspin_lock_register(struct hwspinlock *hwlock)
+static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
 {
 	struct hwspinlock *tmp;
 	int ret;
 
-	if (!hwlock || !hwlock->ops ||
-		!hwlock->ops->trylock || !hwlock->ops->unlock) {
-		pr_err("invalid parameters\n");
-		return -EINVAL;
-	}
-
-	spin_lock_init(&hwlock->lock);
-
 	mutex_lock(&hwspinlock_tree_lock);
 
-	ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
-	if (ret == -EEXIST)
-		pr_err("hwspinlock id %d already exists!\n", hwlock->id);
-	if (ret)
+	ret = radix_tree_insert(&hwspinlock_tree, id, hwlock);
+	if (ret) {
+		if (ret == -EEXIST)
+			pr_err("hwspinlock id %d already exists!\n", id);
 		goto out;
+	}
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
-							HWSPINLOCK_UNUSED);
+	tmp = radix_tree_tag_set(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
 
 	/* self-sanity check which should never fail */
 	WARN_ON(tmp != hwlock);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
-	return ret;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(hwspin_lock_register);
 
-/**
- * hwspin_lock_unregister() - unregister an hw spinlock
- * @id: index of the specific hwspinlock to unregister
- *
- * This function should be called from the underlying platform-specific
- * implementation, to unregister an existing (and unused) hwspinlock.
- *
- * Should be called from a process context (might sleep)
- *
- * Returns the address of hwspinlock @id on success, or NULL on failure
- */
-struct hwspinlock *hwspin_lock_unregister(unsigned int id)
+static struct hwspinlock *hwspin_lock_unregister_single(unsigned int id)
 {
 	struct hwspinlock *hwlock = NULL;
 	int ret;
@@ -337,6 +306,88 @@ out:
 	mutex_unlock(&hwspinlock_tree_lock);
 	return hwlock;
 }
+
+/**
+ * hwspin_lock_register() - register a new hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ * @dev: the backing device
+ * @ops: hwspinlock handlers for this device
+ * @base_id: id of the first hardware spinlock in this bank
+ * @num_locks: number of hwspinlocks provided by this device
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to register a new hwspinlock device instance.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks)
+{
+	struct hwspinlock *hwlock;
+	int ret = 0, i;
+
+	if (!bank || !ops || !dev || !num_locks || !ops->trylock ||
+							!ops->unlock) {
+		pr_err("invalid parameters\n");
+		return -EINVAL;
+	}
+
+	bank->dev = dev;
+	bank->ops = ops;
+	bank->base_id = base_id;
+	bank->num_locks = num_locks;
+
+	for (i = 0; i < num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		spin_lock_init(&hwlock->lock);
+		hwlock->bank = bank;
+
+		ret = hwspin_lock_register_single(hwlock, i);
+		if (ret)
+			goto reg_failed;
+	}
+
+	return 0;
+
+reg_failed:
+	while (--i >= 0)
+		hwspin_lock_unregister_single(i);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hwspin_lock_register);
+
+/**
+ * hwspin_lock_unregister() - unregister an hw spinlock device
+ * @bank: the hwspinlock device, which usually provides numerous hw locks
+ *
+ * This function should be called from the underlying platform-specific
+ * implementation, to unregister an existing (and unused) hwspinlock.
+ *
+ * Should be called from a process context (might sleep)
+ *
+ * Returns 0 on success, or an appropriate error code on failure
+ */
+int hwspin_lock_unregister(struct hwspinlock_device *bank)
+{
+	struct hwspinlock *hwlock, *tmp;
+	int i;
+
+	for (i = 0; i < bank->num_locks; i++) {
+		hwlock = &bank->lock[i];
+
+		tmp = hwspin_lock_unregister_single(bank->base_id + i);
+		if (!tmp)
+			return -EBUSY;
+
+		/* self-sanity check that should never fail */
+		WARN_ON(tmp != hwlock);
+	}
+
+	return 0;
+}
 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
 
 /**
@@ -351,24 +402,25 @@ EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
  */
 static int __hwspin_lock_request(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
 	/* prevent underlying implementation from being removed */
-	if (!try_module_get(hwlock->dev->driver->owner)) {
-		dev_err(hwlock->dev, "%s: can't get owner\n", __func__);
+	if (!try_module_get(dev->driver->owner)) {
+		dev_err(dev, "%s: can't get owner\n", __func__);
 		return -EINVAL;
 	}
 
 	/* notify PM core that power is now needed */
-	ret = pm_runtime_get_sync(hwlock->dev);
+	ret = pm_runtime_get_sync(dev);
 	if (ret < 0) {
-		dev_err(hwlock->dev, "%s: can't power on device\n", __func__);
+		dev_err(dev, "%s: can't power on device\n", __func__);
 		return ret;
 	}
 
 	/* mark hwspinlock as used, should not fail */
-	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* self-sanity check that should never fail */
@@ -390,7 +442,7 @@ int hwspin_lock_get_id(struct hwspinlock *hwlock)
 		return -EINVAL;
 	}
 
-	return hwlock->id;
+	return hwlock_to_id(hwlock);
 }
 EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
 
@@ -465,7 +517,7 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
 	}
 
 	/* sanity check (this shouldn't happen) */
-	WARN_ON(hwlock->id != id);
+	WARN_ON(hwlock_to_id(hwlock) != id);
 
 	/* make sure this hwspinlock is unused */
 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
@@ -500,6 +552,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
  */
 int hwspin_lock_free(struct hwspinlock *hwlock)
 {
+	struct device *dev = hwlock->bank->dev;
 	struct hwspinlock *tmp;
 	int ret;
 
@@ -511,28 +564,28 @@ int hwspin_lock_free(struct hwspinlock *hwlock)
 	mutex_lock(&hwspinlock_tree_lock);
 
 	/* make sure the hwspinlock is used */
-	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id,
+	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 	if (ret == 1) {
-		dev_err(hwlock->dev, "%s: hwlock is already free\n", __func__);
+		dev_err(dev, "%s: hwlock is already free\n", __func__);
 		dump_stack();
 		ret = -EINVAL;
 		goto out;
 	}
 
 	/* notify the underlying device that power is not needed */
-	ret = pm_runtime_put(hwlock->dev);
+	ret = pm_runtime_put(dev);
 	if (ret < 0)
 		goto out;
 
 	/* mark this hwspinlock as available */
-	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id,
+	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock),
 							HWSPINLOCK_UNUSED);
 
 	/* sanity check (this shouldn't happen) */
 	WARN_ON(tmp != hwlock);
 
-	module_put(hwlock->dev->driver->owner);
+	module_put(dev->driver->owner);
 
 out:
 	mutex_unlock(&hwspinlock_tree_lock);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index fb25830..d26f78b 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,8 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
+struct hwspinlock_device;
+
 /**
  * struct hwspinlock_ops - platform-specific hwspinlock handlers
  *
@@ -39,21 +41,37 @@ struct hwspinlock_ops {
 
 /**
  * struct hwspinlock - this struct represents a single hwspinlock instance
- *
- * @dev: underlying device, will be used to invoke runtime PM api
- * @ops: platform-specific hwspinlock handlers
- * @id: a global, unique, system-wide, index of the lock.
+ * @bank: the hwspinlock_device structure which owns this lock
  * @lock: initialized and used by hwspinlock core
- *
- * Note: currently simplicity was opted for, but later we can squeeze some
- * memory bytes by grouping dev, ops in a single
- * per-platform struct, and have all hwspinlocks point at it.
+ * @priv: private data, owned by the underlying platform-specific hwspinlock drv
  */
 struct hwspinlock {
+	struct hwspinlock_device *bank;
+	spinlock_t lock;
+	void *priv;
+};
+
+/**
+ * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
+ * @dev: underlying device, will be used to invoke runtime PM api
+ * @ops: platform-specific hwspinlock handlers
+ * @base_id: id index of the first lock in this device
+ * @num_locks: number of locks in this device
+ * @lock: dynamically allocated array of 'struct hwspinlock'
+ */
+struct hwspinlock_device {
 	struct device *dev;
 	const struct hwspinlock_ops *ops;
-	int id;
-	spinlock_t lock;
+	int base_id;
+	int num_locks;
+	struct hwspinlock lock[0];
 };
 
+static inline int hwlock_to_id(struct hwspinlock *hwlock)
+{
+	int local_id = hwlock - &hwlock->bank->lock[0];
+
+	return hwlock->bank->base_id + local_id;
+}
+
 #endif /* __HWSPINLOCK_HWSPINLOCK_H */
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index 2044d18..aec3006 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -41,34 +41,20 @@
 #define SPINLOCK_NOTTAKEN		(0)	/* free */
 #define SPINLOCK_TAKEN			(1)	/* locked */
 
-#define to_omap_hwspinlock(lock)	\
-	container_of(lock, struct omap_hwspinlock, lock)
-
-struct omap_hwspinlock {
-	struct hwspinlock lock;
-	void __iomem *addr;
-};
-
-struct omap_hwspinlock_state {
-	int num_locks;			/* Total number of locks in system */
-	void __iomem *io_base;		/* Mapped base address */
-	struct omap_hwspinlock lock[0];	/* Array of 'num_locks' locks */
-};
-
 static int omap_hwspinlock_trylock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* attempt to acquire the lock by reading its value */
-	return (SPINLOCK_NOTTAKEN == readl(omap_lock->addr));
+	return (SPINLOCK_NOTTAKEN == readl(lock_addr));
 }
 
 static void omap_hwspinlock_unlock(struct hwspinlock *lock)
 {
-	struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock);
+	void __iomem *lock_addr = lock->priv;
 
 	/* release the lock by writing 0 to it */
-	writel(SPINLOCK_NOTTAKEN, omap_lock->addr);
+	writel(SPINLOCK_NOTTAKEN, lock_addr);
 }
 
 /*
@@ -95,11 +81,11 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
 	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
-	struct omap_hwspinlock *omap_lock;
-	struct omap_hwspinlock_state *state;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
 	struct resource *res;
 	void __iomem *io_base;
-	int i, ret;
+	int num_locks, i, ret;
 
 	if (!pdata)
 		return -ENODEV;
@@ -122,18 +108,18 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 		goto iounmap_base;
 	}
 
-	i *= 32; /* actual number of locks in this device */
+	num_locks = i * 32; /* actual number of locks in this device */
 
-	state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL);
-	if (!state) {
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
 		ret = -ENOMEM;
 		goto iounmap_base;
 	}
 
-	state->num_locks = i;
-	state->io_base = io_base;
+	platform_set_drvdata(pdev, bank);
 
-	platform_set_drvdata(pdev, state);
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 	/*
 	 * runtime PM will make sure the clock of this module is
@@ -141,26 +127,16 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_enable(&pdev->dev);
 
-	for (i = 0; i < state->num_locks; i++) {
-		omap_lock = &state->lock[i];
-
-		omap_lock->lock.dev = &pdev->dev;
-		omap_lock->lock.id = pdata->base_id + i;
-		omap_lock->lock.ops = &omap_hwspinlock_ops;
-		omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
-
-		ret = hwspin_lock_register(&omap_lock->lock);
-		if (ret)
-			goto free_locks;
-	}
+	ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
 
 	return 0;
 
-free_locks:
-	while (--i >= 0)
-		hwspin_lock_unregister(i);
+reg_fail:
 	pm_runtime_disable(&pdev->dev);
-	kfree(state);
+	kfree(bank);
 iounmap_base:
 	iounmap(io_base);
 	return ret;
@@ -168,23 +144,19 @@ iounmap_base:
 
 static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
-	struct omap_hwspinlock_state *state = platform_get_drvdata(pdev);
-	struct hwspinlock *lock;
-	int i;
-
-	for (i = 0; i < state->num_locks; i++) {
-		lock = hwspin_lock_unregister(i);
-		/* this shouldn't happen at this point. if it does, at least
-		 * don't continue with the remove */
-		if (!lock) {
-			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
-			return -EBUSY;
-		}
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
+	int ret;
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
 	}
 
 	pm_runtime_disable(&pdev->dev);
-	iounmap(state->io_base);
-	kfree(state);
+	iounmap(io_base);
+	kfree(bank);
 
 	return 0;
 }
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index c246522..08a2fee 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -20,12 +20,15 @@
 
 #include <linux/err.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 
 /* hwspinlock mode argument */
 #define HWLOCK_IRQSTATE	0x01	/* Disable interrupts, save state */
 #define HWLOCK_IRQ	0x02	/* Disable interrupts, don't save state */
 
 struct hwspinlock;
+struct hwspinlock_device;
+struct hwspinlock_ops;
 
 /**
  * struct hwspinlock_pdata - platform data for hwspinlock drivers
@@ -57,8 +60,9 @@ struct hwspinlock_pdata {
 
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
-int hwspin_lock_register(struct hwspinlock *lock);
-struct hwspinlock *hwspin_lock_unregister(unsigned int id);
+int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
+		const struct hwspinlock_ops *ops, int base_id, int num_locks);
+int hwspin_lock_unregister(struct hwspinlock_device *bank);
 struct hwspinlock *hwspin_lock_request(void);
 struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
 int hwspin_lock_free(struct hwspinlock *hwlock);
-- 
1.7.4.1

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

* [PATCH 08/10] hwspinlock/u8500: add hwspinlock driver
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Mathieu J. Poirier, Ohad Ben-Cohen

From: Mathieu J. Poirier <mathieu.poirier@linaro.org>

Add hwspinlock driver for U8500's Hsem hardware.

At this point only HSem's protocol 1 is used (i.e. no interrupts).

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
[ohad@wizery.com: adopt recent hwspin_lock_{un}register API changes]
[ohad@wizery.com: set the owner member of the driver]
[ohad@wizery.com: mark ->remove() function as __devexit]
[ohad@wizery.com: write commit log]
[ohad@wizery.com: small cleanups]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig      |   11 ++
 drivers/hwspinlock/Makefile     |    2 +
 drivers/hwspinlock/u8500_hsem.c |  198 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 211 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index c8e7bda..c7c3128 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -18,4 +18,15 @@ config HWSPINLOCK_OMAP
 
 	  If unsure, say N.
 
+config HSEM_U8500
+	tristate "STE Hardware Semaphore functionality"
+	depends on ARCH_U8500
+	select HWSPINLOCK
+	help
+	  Say y here to support the STE Hardware Semaphore functionality, which
+	  provides a synchronisation mechanism for the various processor on the
+	  SoC.
+
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 5729a3f..d1aeea7 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
 obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
+obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
new file mode 100644
index 0000000..f749fcf
--- /dev/null
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -0,0 +1,198 @@
+/*
+ * u8500 HWSEM driver
+ *
+ * Copyright (C) 2010-2011 ST-Ericsson
+ *
+ * Implements u8500 semaphore handling for protocol 1, no interrupts.
+ *
+ * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
+ * Heavily borrowed from the work of :
+ *   Simon Que <sque@ti.com>
+ *   Hari Kanigeri <h-kanigeri2@ti.com>
+ *   Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/hwspinlock.h>
+#include <linux/platform_device.h>
+
+#include "hwspinlock_internal.h"
+
+/*
+ * Implementation of STE's HSem protocol 1 without interrutps.
+ * The only masterID we allow is '0x01' to force people to use
+ * HSems for synchronisation between processors rather than processes
+ * on the ARM core.
+ */
+
+#define U8500_MAX_SEMAPHORE		32	/* a total of 32 semaphore */
+#define RESET_SEMAPHORE			(0)	/* free */
+
+/*
+ * CPU ID for master running u8500 kernel.
+ * Hswpinlocks should only be used to synchonise operations
+ * between the Cortex A9 core and the other CPUs.  Hence
+ * forcing the masterID to a preset value.
+ */
+#define HSEM_MASTER_ID			0x01
+
+#define HSEM_REGISTER_OFFSET		0x08
+
+#define HSEM_CTRL_REG			0x00
+#define HSEM_ICRALL			0x90
+#define HSEM_PROTOCOL_1			0x01
+
+static int u8500_hsem_trylock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	writel(HSEM_MASTER_ID, lock_addr);
+
+	/* get only first 4 bit and compare to masterID.
+	 * if equal, we have the semaphore, otherwise
+	 * someone else has it.
+	 */
+	return (HSEM_MASTER_ID == (0x0F & readl(lock_addr)));
+}
+
+static void u8500_hsem_unlock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	/* release the lock by writing 0 to it */
+	writel(RESET_SEMAPHORE, lock_addr);
+}
+
+/*
+ * u8500: what value is recommended here ?
+ */
+static void u8500_hsem_relax(struct hwspinlock *lock)
+{
+	ndelay(50);
+}
+
+static const struct hwspinlock_ops u8500_hwspinlock_ops = {
+	.trylock	= u8500_hsem_trylock,
+	.unlock		= u8500_hsem_unlock,
+	.relax		= u8500_hsem_relax,
+};
+
+static int __devinit u8500_hsem_probe(struct platform_device *pdev)
+{
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
+	struct resource *res;
+	void __iomem *io_base;
+	int i, ret, num_locks = U8500_MAX_SEMAPHORE;
+	ulong val;
+
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	io_base = ioremap(res->start, resource_size(res));
+	if (!io_base) {
+		ret = -ENOMEM;
+		goto free_state;
+	}
+
+	/* make sure protocol 1 is selected */
+	val = readl(io_base + HSEM_CTRL_REG);
+	writel((val & ~HSEM_PROTOCOL_1), io_base + HSEM_CTRL_REG);
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	platform_set_drvdata(pdev, bank);
+
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + HSEM_REGISTER_OFFSET + sizeof(u32) * i;
+
+	/* no pm needed for HSem but required to comply with hwspilock core */
+	pm_runtime_enable(&pdev->dev);
+
+	ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
+
+	return 0;
+
+reg_fail:
+	pm_runtime_disable(&pdev->dev);
+	kfree(bank);
+iounmap_base:
+	iounmap(io_base);
+	return ret;
+}
+
+static int __devexit u8500_hsem_remove(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET;
+	int ret;
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	pm_runtime_disable(&pdev->dev);
+	iounmap(io_base);
+	kfree(bank);
+
+	return 0;
+}
+
+static struct platform_driver u8500_hsem_driver = {
+	.probe		= u8500_hsem_probe,
+	.remove		= __devexit_p(u8500_hsem_remove),
+	.driver		= {
+		.name	= "u8500_hsem",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init u8500_hsem_init(void)
+{
+	return platform_driver_register(&u8500_hsem_driver);
+}
+/* board init code might need to reserve hwspinlocks for predefined purposes */
+postcore_initcall(u8500_hsem_init);
+
+static void __exit u8500_hsem_exit(void)
+{
+	platform_driver_unregister(&u8500_hsem_driver);
+}
+module_exit(u8500_hsem_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware Spinlock driver for u8500");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
-- 
1.7.4.1


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

* [PATCH 08/10] hwspinlock/u8500: add hwspinlock driver
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Mathieu J. Poirier, Ohad Ben-Cohen

From: Mathieu J. Poirier <mathieu.poirier@linaro.org>

Add hwspinlock driver for U8500's Hsem hardware.

At this point only HSem's protocol 1 is used (i.e. no interrupts).

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
[ohad@wizery.com: adopt recent hwspin_lock_{un}register API changes]
[ohad@wizery.com: set the owner member of the driver]
[ohad@wizery.com: mark ->remove() function as __devexit]
[ohad@wizery.com: write commit log]
[ohad@wizery.com: small cleanups]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig      |   11 ++
 drivers/hwspinlock/Makefile     |    2 +
 drivers/hwspinlock/u8500_hsem.c |  198 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 211 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index c8e7bda..c7c3128 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -18,4 +18,15 @@ config HWSPINLOCK_OMAP
 
 	  If unsure, say N.
 
+config HSEM_U8500
+	tristate "STE Hardware Semaphore functionality"
+	depends on ARCH_U8500
+	select HWSPINLOCK
+	help
+	  Say y here to support the STE Hardware Semaphore functionality, which
+	  provides a synchronisation mechanism for the various processor on the
+	  SoC.
+
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 5729a3f..d1aeea7 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
 obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
+obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
new file mode 100644
index 0000000..f749fcf
--- /dev/null
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -0,0 +1,198 @@
+/*
+ * u8500 HWSEM driver
+ *
+ * Copyright (C) 2010-2011 ST-Ericsson
+ *
+ * Implements u8500 semaphore handling for protocol 1, no interrupts.
+ *
+ * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
+ * Heavily borrowed from the work of :
+ *   Simon Que <sque@ti.com>
+ *   Hari Kanigeri <h-kanigeri2@ti.com>
+ *   Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/hwspinlock.h>
+#include <linux/platform_device.h>
+
+#include "hwspinlock_internal.h"
+
+/*
+ * Implementation of STE's HSem protocol 1 without interrutps.
+ * The only masterID we allow is '0x01' to force people to use
+ * HSems for synchronisation between processors rather than processes
+ * on the ARM core.
+ */
+
+#define U8500_MAX_SEMAPHORE		32	/* a total of 32 semaphore */
+#define RESET_SEMAPHORE			(0)	/* free */
+
+/*
+ * CPU ID for master running u8500 kernel.
+ * Hswpinlocks should only be used to synchonise operations
+ * between the Cortex A9 core and the other CPUs.  Hence
+ * forcing the masterID to a preset value.
+ */
+#define HSEM_MASTER_ID			0x01
+
+#define HSEM_REGISTER_OFFSET		0x08
+
+#define HSEM_CTRL_REG			0x00
+#define HSEM_ICRALL			0x90
+#define HSEM_PROTOCOL_1			0x01
+
+static int u8500_hsem_trylock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	writel(HSEM_MASTER_ID, lock_addr);
+
+	/* get only first 4 bit and compare to masterID.
+	 * if equal, we have the semaphore, otherwise
+	 * someone else has it.
+	 */
+	return (HSEM_MASTER_ID == (0x0F & readl(lock_addr)));
+}
+
+static void u8500_hsem_unlock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	/* release the lock by writing 0 to it */
+	writel(RESET_SEMAPHORE, lock_addr);
+}
+
+/*
+ * u8500: what value is recommended here ?
+ */
+static void u8500_hsem_relax(struct hwspinlock *lock)
+{
+	ndelay(50);
+}
+
+static const struct hwspinlock_ops u8500_hwspinlock_ops = {
+	.trylock	= u8500_hsem_trylock,
+	.unlock		= u8500_hsem_unlock,
+	.relax		= u8500_hsem_relax,
+};
+
+static int __devinit u8500_hsem_probe(struct platform_device *pdev)
+{
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
+	struct resource *res;
+	void __iomem *io_base;
+	int i, ret, num_locks = U8500_MAX_SEMAPHORE;
+	ulong val;
+
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	io_base = ioremap(res->start, resource_size(res));
+	if (!io_base) {
+		ret = -ENOMEM;
+		goto free_state;
+	}
+
+	/* make sure protocol 1 is selected */
+	val = readl(io_base + HSEM_CTRL_REG);
+	writel((val & ~HSEM_PROTOCOL_1), io_base + HSEM_CTRL_REG);
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	platform_set_drvdata(pdev, bank);
+
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + HSEM_REGISTER_OFFSET + sizeof(u32) * i;
+
+	/* no pm needed for HSem but required to comply with hwspilock core */
+	pm_runtime_enable(&pdev->dev);
+
+	ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
+
+	return 0;
+
+reg_fail:
+	pm_runtime_disable(&pdev->dev);
+	kfree(bank);
+iounmap_base:
+	iounmap(io_base);
+	return ret;
+}
+
+static int __devexit u8500_hsem_remove(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET;
+	int ret;
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	pm_runtime_disable(&pdev->dev);
+	iounmap(io_base);
+	kfree(bank);
+
+	return 0;
+}
+
+static struct platform_driver u8500_hsem_driver = {
+	.probe		= u8500_hsem_probe,
+	.remove		= __devexit_p(u8500_hsem_remove),
+	.driver		= {
+		.name	= "u8500_hsem",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init u8500_hsem_init(void)
+{
+	return platform_driver_register(&u8500_hsem_driver);
+}
+/* board init code might need to reserve hwspinlocks for predefined purposes */
+postcore_initcall(u8500_hsem_init);
+
+static void __exit u8500_hsem_exit(void)
+{
+	platform_driver_unregister(&u8500_hsem_driver);
+}
+module_exit(u8500_hsem_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware Spinlock driver for u8500");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
-- 
1.7.4.1

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

* [PATCH 08/10] hwspinlock/u8500: add hwspinlock driver
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mathieu J. Poirier <mathieu.poirier@linaro.org>

Add hwspinlock driver for U8500's Hsem hardware.

At this point only HSem's protocol 1 is used (i.e. no interrupts).

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
[ohad at wizery.com: adopt recent hwspin_lock_{un}register API changes]
[ohad at wizery.com: set the owner member of the driver]
[ohad at wizery.com: mark ->remove() function as __devexit]
[ohad at wizery.com: write commit log]
[ohad at wizery.com: small cleanups]
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/Kconfig      |   11 ++
 drivers/hwspinlock/Makefile     |    2 +
 drivers/hwspinlock/u8500_hsem.c |  198 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 211 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwspinlock/u8500_hsem.c

diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index c8e7bda..c7c3128 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -18,4 +18,15 @@ config HWSPINLOCK_OMAP
 
 	  If unsure, say N.
 
+config HSEM_U8500
+	tristate "STE Hardware Semaphore functionality"
+	depends on ARCH_U8500
+	select HWSPINLOCK
+	help
+	  Say y here to support the STE Hardware Semaphore functionality, which
+	  provides a synchronisation mechanism for the various processor on the
+	  SoC.
+
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 5729a3f..d1aeea7 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
 obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
+obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c
new file mode 100644
index 0000000..f749fcf
--- /dev/null
+++ b/drivers/hwspinlock/u8500_hsem.c
@@ -0,0 +1,198 @@
+/*
+ * u8500 HWSEM driver
+ *
+ * Copyright (C) 2010-2011 ST-Ericsson
+ *
+ * Implements u8500 semaphore handling for protocol 1, no interrupts.
+ *
+ * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
+ * Heavily borrowed from the work of :
+ *   Simon Que <sque@ti.com>
+ *   Hari Kanigeri <h-kanigeri2@ti.com>
+ *   Ohad Ben-Cohen <ohad@wizery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/hwspinlock.h>
+#include <linux/platform_device.h>
+
+#include "hwspinlock_internal.h"
+
+/*
+ * Implementation of STE's HSem protocol 1 without interrutps.
+ * The only masterID we allow is '0x01' to force people to use
+ * HSems for synchronisation between processors rather than processes
+ * on the ARM core.
+ */
+
+#define U8500_MAX_SEMAPHORE		32	/* a total of 32 semaphore */
+#define RESET_SEMAPHORE			(0)	/* free */
+
+/*
+ * CPU ID for master running u8500 kernel.
+ * Hswpinlocks should only be used to synchonise operations
+ * between the Cortex A9 core and the other CPUs.  Hence
+ * forcing the masterID to a preset value.
+ */
+#define HSEM_MASTER_ID			0x01
+
+#define HSEM_REGISTER_OFFSET		0x08
+
+#define HSEM_CTRL_REG			0x00
+#define HSEM_ICRALL			0x90
+#define HSEM_PROTOCOL_1			0x01
+
+static int u8500_hsem_trylock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	writel(HSEM_MASTER_ID, lock_addr);
+
+	/* get only first 4 bit and compare to masterID.
+	 * if equal, we have the semaphore, otherwise
+	 * someone else has it.
+	 */
+	return (HSEM_MASTER_ID == (0x0F & readl(lock_addr)));
+}
+
+static void u8500_hsem_unlock(struct hwspinlock *lock)
+{
+	void __iomem *lock_addr = lock->priv;
+
+	/* release the lock by writing 0 to it */
+	writel(RESET_SEMAPHORE, lock_addr);
+}
+
+/*
+ * u8500: what value is recommended here ?
+ */
+static void u8500_hsem_relax(struct hwspinlock *lock)
+{
+	ndelay(50);
+}
+
+static const struct hwspinlock_ops u8500_hwspinlock_ops = {
+	.trylock	= u8500_hsem_trylock,
+	.unlock		= u8500_hsem_unlock,
+	.relax		= u8500_hsem_relax,
+};
+
+static int __devinit u8500_hsem_probe(struct platform_device *pdev)
+{
+	struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
+	struct hwspinlock_device *bank;
+	struct hwspinlock *hwlock;
+	struct resource *res;
+	void __iomem *io_base;
+	int i, ret, num_locks = U8500_MAX_SEMAPHORE;
+	ulong val;
+
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	io_base = ioremap(res->start, resource_size(res));
+	if (!io_base) {
+		ret = -ENOMEM;
+		goto free_state;
+	}
+
+	/* make sure protocol 1 is selected */
+	val = readl(io_base + HSEM_CTRL_REG);
+	writel((val & ~HSEM_PROTOCOL_1), io_base + HSEM_CTRL_REG);
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	bank = kzalloc(sizeof(*bank) + num_locks * sizeof(*hwlock), GFP_KERNEL);
+	if (!bank) {
+		ret = -ENOMEM;
+		goto iounmap_base;
+	}
+
+	platform_set_drvdata(pdev, bank);
+
+	for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+		hwlock->priv = io_base + HSEM_REGISTER_OFFSET + sizeof(u32) * i;
+
+	/* no pm needed for HSem but required to comply with hwspilock core */
+	pm_runtime_enable(&pdev->dev);
+
+	ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops,
+						pdata->base_id, num_locks);
+	if (ret)
+		goto reg_fail;
+
+	return 0;
+
+reg_fail:
+	pm_runtime_disable(&pdev->dev);
+	kfree(bank);
+iounmap_base:
+	iounmap(io_base);
+	return ret;
+}
+
+static int __devexit u8500_hsem_remove(struct platform_device *pdev)
+{
+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
+	void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET;
+	int ret;
+
+	/* clear all interrupts */
+	writel(0xFFFF, io_base + HSEM_ICRALL);
+
+	ret = hwspin_lock_unregister(bank);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	pm_runtime_disable(&pdev->dev);
+	iounmap(io_base);
+	kfree(bank);
+
+	return 0;
+}
+
+static struct platform_driver u8500_hsem_driver = {
+	.probe		= u8500_hsem_probe,
+	.remove		= __devexit_p(u8500_hsem_remove),
+	.driver		= {
+		.name	= "u8500_hsem",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init u8500_hsem_init(void)
+{
+	return platform_driver_register(&u8500_hsem_driver);
+}
+/* board init code might need to reserve hwspinlocks for predefined purposes */
+postcore_initcall(u8500_hsem_init);
+
+static void __exit u8500_hsem_exit(void)
+{
+	platform_driver_unregister(&u8500_hsem_driver);
+}
+module_exit(u8500_hsem_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware Spinlock driver for u8500");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
-- 
1.7.4.1

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

* [PATCH 09/10] hwspinlock/omap: omap_hwspinlock_remove should be __devexit
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Mark omap_hwspinlock_remove with __devexit (and use __devexit_p
appropriately) so the function can be discarded when the conditions are met.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index aec3006..887d34e 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -142,7 +142,7 @@ iounmap_base:
 	return ret;
 }
 
-static int omap_hwspinlock_remove(struct platform_device *pdev)
+static int __devexit omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
 	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
@@ -163,7 +163,7 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_hwspinlock_driver = {
 	.probe		= omap_hwspinlock_probe,
-	.remove		= omap_hwspinlock_remove,
+	.remove		= __devexit_p(omap_hwspinlock_remove),
 	.driver		= {
 		.name	= "omap_hwspinlock",
 		.owner	= THIS_MODULE,
-- 
1.7.4.1


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

* [PATCH 09/10] hwspinlock/omap: omap_hwspinlock_remove should be __devexit
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Mark omap_hwspinlock_remove with __devexit (and use __devexit_p
appropriately) so the function can be discarded when the conditions are met.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index aec3006..887d34e 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -142,7 +142,7 @@ iounmap_base:
 	return ret;
 }
 
-static int omap_hwspinlock_remove(struct platform_device *pdev)
+static int __devexit omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
 	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
@@ -163,7 +163,7 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_hwspinlock_driver = {
 	.probe		= omap_hwspinlock_probe,
-	.remove		= omap_hwspinlock_remove,
+	.remove		= __devexit_p(omap_hwspinlock_remove),
 	.driver		= {
 		.name	= "omap_hwspinlock",
 		.owner	= THIS_MODULE,
-- 
1.7.4.1

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

* [PATCH 09/10] hwspinlock/omap: omap_hwspinlock_remove should be __devexit
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

Mark omap_hwspinlock_remove with __devexit (and use __devexit_p
appropriately) so the function can be discarded when the conditions are met.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/hwspinlock/omap_hwspinlock.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index aec3006..887d34e 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -142,7 +142,7 @@ iounmap_base:
 	return ret;
 }
 
-static int omap_hwspinlock_remove(struct platform_device *pdev)
+static int __devexit omap_hwspinlock_remove(struct platform_device *pdev)
 {
 	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
 	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
@@ -163,7 +163,7 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
 
 static struct platform_driver omap_hwspinlock_driver = {
 	.probe		= omap_hwspinlock_probe,
-	.remove		= omap_hwspinlock_remove,
+	.remove		= __devexit_p(omap_hwspinlock_remove),
 	.driver		= {
 		.name	= "omap_hwspinlock",
 		.owner	= THIS_MODULE,
-- 
1.7.4.1

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

* [PATCH 10/10] hwspinlock: add MAINTAINERS entries
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
files.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 MAINTAINERS |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 28f65c2..92cee8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
 F:	drivers/char/hw_random/
 F:	include/linux/hw_random.h
 
+HARDWARE SPINLOCK CORE
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+S:	Maintained
+F:	Documentation/hwspinlock.h
+F:	drivers/hwspinlock/hwspinlock_core.c
+F:	drivers/hwspinlock/hwspinlock_internal.h
+F:	include/linux/hwspinlock.h
+
 HARMONY SOUND DRIVER
 M:	Kyle McMartin <kyle@mcmartin.ca>
 L:	linux-parisc@vger.kernel.org
@@ -4625,6 +4633,13 @@ S:	Maintained
 F:	drivers/video/omap2/
 F:	Documentation/arm/OMAP/DSS
 
+OMAP HARDWARE SPINLOCK SUPPORT
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+L:	linux-omap@vger.kernel.org
+S:	Maintained
+F:	drivers/hwspinlock/omap_hwspinlock.c
+F:	arch/arm/mach-omap2/hwspinlock.c
+
 OMAP MMC SUPPORT
 M:	Jarkko Lavinen <jarkko.lavinen@nokia.com>
 L:	linux-omap@vger.kernel.org
-- 
1.7.4.1


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

* [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-omap, linux-kernel, linux-arm-kernel
  Cc: Tony Lindgren, Arnd Bergmann, Ohad Ben-Cohen

Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
files.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 MAINTAINERS |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 28f65c2..92cee8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
 F:	drivers/char/hw_random/
 F:	include/linux/hw_random.h
 
+HARDWARE SPINLOCK CORE
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+S:	Maintained
+F:	Documentation/hwspinlock.h
+F:	drivers/hwspinlock/hwspinlock_core.c
+F:	drivers/hwspinlock/hwspinlock_internal.h
+F:	include/linux/hwspinlock.h
+
 HARMONY SOUND DRIVER
 M:	Kyle McMartin <kyle@mcmartin.ca>
 L:	linux-parisc@vger.kernel.org
@@ -4625,6 +4633,13 @@ S:	Maintained
 F:	drivers/video/omap2/
 F:	Documentation/arm/OMAP/DSS
 
+OMAP HARDWARE SPINLOCK SUPPORT
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+L:	linux-omap@vger.kernel.org
+S:	Maintained
+F:	drivers/hwspinlock/omap_hwspinlock.c
+F:	arch/arm/mach-omap2/hwspinlock.c
+
 OMAP MMC SUPPORT
 M:	Jarkko Lavinen <jarkko.lavinen@nokia.com>
 L:	linux-omap@vger.kernel.org
-- 
1.7.4.1

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

* [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 16:47   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
files.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 MAINTAINERS |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 28f65c2..92cee8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
 F:	drivers/char/hw_random/
 F:	include/linux/hw_random.h
 
+HARDWARE SPINLOCK CORE
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+S:	Maintained
+F:	Documentation/hwspinlock.h
+F:	drivers/hwspinlock/hwspinlock_core.c
+F:	drivers/hwspinlock/hwspinlock_internal.h
+F:	include/linux/hwspinlock.h
+
 HARMONY SOUND DRIVER
 M:	Kyle McMartin <kyle@mcmartin.ca>
 L:	linux-parisc at vger.kernel.org
@@ -4625,6 +4633,13 @@ S:	Maintained
 F:	drivers/video/omap2/
 F:	Documentation/arm/OMAP/DSS
 
+OMAP HARDWARE SPINLOCK SUPPORT
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+L:	linux-omap at vger.kernel.org
+S:	Maintained
+F:	drivers/hwspinlock/omap_hwspinlock.c
+F:	arch/arm/mach-omap2/hwspinlock.c
+
 OMAP MMC SUPPORT
 M:	Jarkko Lavinen <jarkko.lavinen@nokia.com>
 L:	linux-omap at vger.kernel.org
-- 
1.7.4.1

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

* Re: [PATCH 10/10] hwspinlock: add MAINTAINERS entries
  2011-09-12 16:47   ` Ohad Ben-Cohen
  (?)
@ 2011-09-12 16:58     ` Joe Perches
  -1 siblings, 0 replies; 67+ messages in thread
From: Joe Perches @ 2011-09-12 16:58 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: linux-omap, linux-kernel, linux-arm-kernel, Tony Lindgren, Arnd Bergmann

On Mon, 2011-09-12 at 19:47 +0300, Ohad Ben-Cohen wrote:
> Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
> files.

trivial:

> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> @@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
[]
> +HARDWARE SPINLOCK CORE
> +M:	Ohad Ben-Cohen <ohad@wizery.com>
> +S:	Maintained
> +F:	Documentation/hwspinlock.h

F:	Documentation/hwspinlock.txt

> +F:	drivers/hwspinlock/hwspinlock_core.c
> +F:	drivers/hwspinlock/hwspinlock_internal.h

Maybe
F:	drivers/hwspinlock/hwspinlock_*

> +F:	include/linux/hwspinlock.h



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

* Re: [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 16:58     ` Joe Perches
  0 siblings, 0 replies; 67+ messages in thread
From: Joe Perches @ 2011-09-12 16:58 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Tony Lindgren, linux-omap, Arnd Bergmann, linux-kernel, linux-arm-kernel

On Mon, 2011-09-12 at 19:47 +0300, Ohad Ben-Cohen wrote:
> Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
> files.

trivial:

> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> @@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
[]
> +HARDWARE SPINLOCK CORE
> +M:	Ohad Ben-Cohen <ohad@wizery.com>
> +S:	Maintained
> +F:	Documentation/hwspinlock.h

F:	Documentation/hwspinlock.txt

> +F:	drivers/hwspinlock/hwspinlock_core.c
> +F:	drivers/hwspinlock/hwspinlock_internal.h

Maybe
F:	drivers/hwspinlock/hwspinlock_*

> +F:	include/linux/hwspinlock.h

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

* [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 16:58     ` Joe Perches
  0 siblings, 0 replies; 67+ messages in thread
From: Joe Perches @ 2011-09-12 16:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2011-09-12 at 19:47 +0300, Ohad Ben-Cohen wrote:
> Update MAINTAINERS with entries for hwspinlock/core and hwspinlock/omap
> files.

trivial:

> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> @@ -2953,6 +2953,14 @@ F:	Documentation/hw_random.txt
[]
> +HARDWARE SPINLOCK CORE
> +M:	Ohad Ben-Cohen <ohad@wizery.com>
> +S:	Maintained
> +F:	Documentation/hwspinlock.h

F:	Documentation/hwspinlock.txt

> +F:	drivers/hwspinlock/hwspinlock_core.c
> +F:	drivers/hwspinlock/hwspinlock_internal.h

Maybe
F:	drivers/hwspinlock/hwspinlock_*

> +F:	include/linux/hwspinlock.h

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

* Re: [PATCH 10/10] hwspinlock: add MAINTAINERS entries
  2011-09-12 16:58     ` Joe Perches
  (?)
@ 2011-09-12 17:01       ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 17:01 UTC (permalink / raw)
  To: Joe Perches
  Cc: linux-omap, linux-kernel, linux-arm-kernel, Tony Lindgren, Arnd Bergmann

On Mon, Sep 12, 2011 at 7:58 PM, Joe Perches <joe@perches.com> wrote:
>> +F:   Documentation/hwspinlock.h
>
> F:      Documentation/hwspinlock.txt

thanks :)

> Maybe
> F:      drivers/hwspinlock/hwspinlock_*

ok, why not.

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

* Re: [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 17:01       ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 17:01 UTC (permalink / raw)
  To: Joe Perches
  Cc: Tony Lindgren, linux-omap, Arnd Bergmann, linux-kernel, linux-arm-kernel

On Mon, Sep 12, 2011 at 7:58 PM, Joe Perches <joe@perches.com> wrote:
>> +F:   Documentation/hwspinlock.h
>
> F:      Documentation/hwspinlock.txt

thanks :)

> Maybe
> F:      drivers/hwspinlock/hwspinlock_*

ok, why not.

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

* [PATCH 10/10] hwspinlock: add MAINTAINERS entries
@ 2011-09-12 17:01       ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-12 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 7:58 PM, Joe Perches <joe@perches.com> wrote:
>> +F: ? Documentation/hwspinlock.h
>
> F: ? ? ?Documentation/hwspinlock.txt

thanks :)

> Maybe
> F: ? ? ?drivers/hwspinlock/hwspinlock_*

ok, why not.

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-12 16:46 ` Ohad Ben-Cohen
  (?)
@ 2011-09-20  9:07   ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-20  9:07 UTC (permalink / raw)
  To: Andrew Morton, Greg KH, Tony Lindgren, Arnd Bergmann, Russell King
  Cc: linux-omap, linux-kernel, linux-arm-kernel, Linus Walleij,
	Linus Torvalds, Nicolas Pitre, Thomas Gleixner, Stephen Rothwell,
	Grant Likely

On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> This series includes a new u8500 hwspinlock driver from Mathieu,
> a core fix from Juan and several other cleanups/fixes
> (some of which were reported by Arnd while reviewing Mathieu's
> driver).
...
>  Documentation/hwspinlock.txt             |   74 +++++++-----
>  MAINTAINERS                              |   15 +++
>  arch/arm/mach-omap2/hwspinlock.c         |    8 +-
>  drivers/hwspinlock/Kconfig               |   27 +++--
>  drivers/hwspinlock/Makefile              |    2 +
>  drivers/hwspinlock/hwspinlock_core.c     |  204 +++++++++++++++++++-----------
>  drivers/hwspinlock/hwspinlock_internal.h |   40 ++++--
>  drivers/hwspinlock/omap_hwspinlock.c     |  127 +++++++------------
>  drivers/hwspinlock/u8500_hsem.c          |  198 +++++++++++++++++++++++++++++
>  include/linux/hwspinlock.h               |   46 +++++--
>  10 files changed, 516 insertions(+), 225 deletions(-)

I'm wondering how hwspinlock updates like this should go upstream.

The first hwspinlock batch was picked by Tony, because it involved a
bulk of OMAP changes.

Hwspinlock isn't OMAP-specific anymore though (we gained support for
STE's u8500) and the vast majority of changes are in drivers/. We're
still very much ARM-related, though this may change too at some point
(c6x has a similar "hardware semaphore" peripheral like the u8500
does).

Tony, if you're still willing to pick up these updates I'd be happy to
send you pull requests of course.

Otherwise, I'll appreciate if anyone has any suggestions ?

I'll of course set up a tree for this and ask Stephen to take it to
linux-next as expected (unless someone just prefers to pick up the
acked patches into his tree).

Thanks,
Ohad.

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

* Re: [PATCH 00/10] hwspinlock-next
@ 2011-09-20  9:07   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-20  9:07 UTC (permalink / raw)
  To: Andrew Morton, Greg KH, Tony Lindgren, Arnd Bergmann, Russell King
  Cc: linux-omap, linux-kernel, linux-arm-kernel, Linus Walleij,
	Linus Torvalds, Nicolas Pitre, Thomas Gleixner, Stephen Rothwell,
	Grant Likely

On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> This series includes a new u8500 hwspinlock driver from Mathieu,
> a core fix from Juan and several other cleanups/fixes
> (some of which were reported by Arnd while reviewing Mathieu's
> driver).
...
>  Documentation/hwspinlock.txt             |   74 +++++++-----
>  MAINTAINERS                              |   15 +++
>  arch/arm/mach-omap2/hwspinlock.c         |    8 +-
>  drivers/hwspinlock/Kconfig               |   27 +++--
>  drivers/hwspinlock/Makefile              |    2 +
>  drivers/hwspinlock/hwspinlock_core.c     |  204 +++++++++++++++++++-----------
>  drivers/hwspinlock/hwspinlock_internal.h |   40 ++++--
>  drivers/hwspinlock/omap_hwspinlock.c     |  127 +++++++------------
>  drivers/hwspinlock/u8500_hsem.c          |  198 +++++++++++++++++++++++++++++
>  include/linux/hwspinlock.h               |   46 +++++--
>  10 files changed, 516 insertions(+), 225 deletions(-)

I'm wondering how hwspinlock updates like this should go upstream.

The first hwspinlock batch was picked by Tony, because it involved a
bulk of OMAP changes.

Hwspinlock isn't OMAP-specific anymore though (we gained support for
STE's u8500) and the vast majority of changes are in drivers/. We're
still very much ARM-related, though this may change too at some point
(c6x has a similar "hardware semaphore" peripheral like the u8500
does).

Tony, if you're still willing to pick up these updates I'd be happy to
send you pull requests of course.

Otherwise, I'll appreciate if anyone has any suggestions ?

I'll of course set up a tree for this and ask Stephen to take it to
linux-next as expected (unless someone just prefers to pick up the
acked patches into his tree).

Thanks,
Ohad.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-20  9:07   ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-20  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> This series includes a new u8500 hwspinlock driver from Mathieu,
> a core fix from Juan and several other cleanups/fixes
> (some of which were reported by Arnd while reviewing Mathieu's
> driver).
...
> ?Documentation/hwspinlock.txt ? ? ? ? ? ? | ? 74 +++++++-----
> ?MAINTAINERS ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 15 +++
> ?arch/arm/mach-omap2/hwspinlock.c ? ? ? ? | ? ?8 +-
> ?drivers/hwspinlock/Kconfig ? ? ? ? ? ? ? | ? 27 +++--
> ?drivers/hwspinlock/Makefile ? ? ? ? ? ? ?| ? ?2 +
> ?drivers/hwspinlock/hwspinlock_core.c ? ? | ?204 +++++++++++++++++++-----------
> ?drivers/hwspinlock/hwspinlock_internal.h | ? 40 ++++--
> ?drivers/hwspinlock/omap_hwspinlock.c ? ? | ?127 +++++++------------
> ?drivers/hwspinlock/u8500_hsem.c ? ? ? ? ?| ?198 +++++++++++++++++++++++++++++
> ?include/linux/hwspinlock.h ? ? ? ? ? ? ? | ? 46 +++++--
> ?10 files changed, 516 insertions(+), 225 deletions(-)

I'm wondering how hwspinlock updates like this should go upstream.

The first hwspinlock batch was picked by Tony, because it involved a
bulk of OMAP changes.

Hwspinlock isn't OMAP-specific anymore though (we gained support for
STE's u8500) and the vast majority of changes are in drivers/. We're
still very much ARM-related, though this may change too at some point
(c6x has a similar "hardware semaphore" peripheral like the u8500
does).

Tony, if you're still willing to pick up these updates I'd be happy to
send you pull requests of course.

Otherwise, I'll appreciate if anyone has any suggestions ?

I'll of course set up a tree for this and ask Stephen to take it to
linux-next as expected (unless someone just prefers to pick up the
acked patches into his tree).

Thanks,
Ohad.

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-20  9:07   ` Ohad Ben-Cohen
@ 2011-09-20 23:13     ` Tony Lindgren
  -1 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-20 23:13 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Andrew Morton, Greg KH, Arnd Bergmann, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Walleij, Linus Torvalds,
	Nicolas Pitre, Thomas Gleixner, Stephen Rothwell, Grant Likely

* Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> 
> I'm wondering how hwspinlock updates like this should go upstream.
> 
> The first hwspinlock batch was picked by Tony, because it involved a
> bulk of OMAP changes.
> 
> Hwspinlock isn't OMAP-specific anymore though (we gained support for
> STE's u8500) and the vast majority of changes are in drivers/. We're
> still very much ARM-related, though this may change too at some point
> (c6x has a similar "hardware semaphore" peripheral like the u8500
> does).
> 
> Tony, if you're still willing to pick up these updates I'd be happy to
> send you pull requests of course.

I'd prefer for Greg to take these as these are drivers.

If he's not taking it at this point based on it being ARM only,
I can take it then.

Regards,

Tony

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-20 23:13     ` Tony Lindgren
  0 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-20 23:13 UTC (permalink / raw)
  To: linux-arm-kernel

* Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> 
> I'm wondering how hwspinlock updates like this should go upstream.
> 
> The first hwspinlock batch was picked by Tony, because it involved a
> bulk of OMAP changes.
> 
> Hwspinlock isn't OMAP-specific anymore though (we gained support for
> STE's u8500) and the vast majority of changes are in drivers/. We're
> still very much ARM-related, though this may change too at some point
> (c6x has a similar "hardware semaphore" peripheral like the u8500
> does).
> 
> Tony, if you're still willing to pick up these updates I'd be happy to
> send you pull requests of course.

I'd prefer for Greg to take these as these are drivers.

If he's not taking it at this point based on it being ARM only,
I can take it then.

Regards,

Tony

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-20 23:13     ` Tony Lindgren
@ 2011-09-20 23:45       ` Greg KH
  -1 siblings, 0 replies; 67+ messages in thread
From: Greg KH @ 2011-09-20 23:45 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Ohad Ben-Cohen, Andrew Morton, Arnd Bergmann, Russell King,
	linux-omap, linux-kernel, linux-arm-kernel, Linus Walleij,
	Linus Torvalds, Nicolas Pitre, Thomas Gleixner, Stephen Rothwell,
	Grant Likely

On Tue, Sep 20, 2011 at 04:13:40PM -0700, Tony Lindgren wrote:
> * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > 
> > I'm wondering how hwspinlock updates like this should go upstream.
> > 
> > The first hwspinlock batch was picked by Tony, because it involved a
> > bulk of OMAP changes.
> > 
> > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > STE's u8500) and the vast majority of changes are in drivers/. We're
> > still very much ARM-related, though this may change too at some point
> > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > does).
> > 
> > Tony, if you're still willing to pick up these updates I'd be happy to
> > send you pull requests of course.
> 
> I'd prefer for Greg to take these as these are drivers.

What, am I the catch-all for drivers these days?

Oh, right, it looks like I am :)

> If he's not taking it at this point based on it being ARM only,
> I can take it then.

Please do, I don't even have the ability to build them here, as I don't
have an arm cross-compiler on this travel laptop.

greg k-h

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-20 23:45       ` Greg KH
  0 siblings, 0 replies; 67+ messages in thread
From: Greg KH @ 2011-09-20 23:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 20, 2011 at 04:13:40PM -0700, Tony Lindgren wrote:
> * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > 
> > I'm wondering how hwspinlock updates like this should go upstream.
> > 
> > The first hwspinlock batch was picked by Tony, because it involved a
> > bulk of OMAP changes.
> > 
> > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > STE's u8500) and the vast majority of changes are in drivers/. We're
> > still very much ARM-related, though this may change too at some point
> > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > does).
> > 
> > Tony, if you're still willing to pick up these updates I'd be happy to
> > send you pull requests of course.
> 
> I'd prefer for Greg to take these as these are drivers.

What, am I the catch-all for drivers these days?

Oh, right, it looks like I am :)

> If he's not taking it at this point based on it being ARM only,
> I can take it then.

Please do, I don't even have the ability to build them here, as I don't
have an arm cross-compiler on this travel laptop.

greg k-h

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-20 23:13     ` Tony Lindgren
@ 2011-09-21 14:12       ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2011-09-21 14:12 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Ohad Ben-Cohen, Andrew Morton, Greg KH, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Walleij, Linus Torvalds,
	Nicolas Pitre, Thomas Gleixner, Stephen Rothwell, Grant Likely

On Wednesday 21 September 2011, Tony Lindgren wrote:
> * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > 
> > I'm wondering how hwspinlock updates like this should go upstream.
> > 
> > The first hwspinlock batch was picked by Tony, because it involved a
> > bulk of OMAP changes.
> > 
> > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > STE's u8500) and the vast majority of changes are in drivers/. We're
> > still very much ARM-related, though this may change too at some point
> > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > does).
> > 
> > Tony, if you're still willing to pick up these updates I'd be happy to
> > send you pull requests of course.
> 
> I'd prefer for Greg to take these as these are drivers.
> 
> If he's not taking it at this point based on it being ARM only,
> I can take it then.

Sorry for replying late, I had accidentally ignored the entire thread.

My feeling is that it would be best for Ohad to send these directly
to Linus, since it's basically a standalone subsystem and he's listed
as the maintainer (well, after this series at least).

I'm also fine with any of the other paths like

ohad->GregKH->torvalds
ohad->arnd->torvalds
ohad->tmlind->torvalds
ohad->tmlind->arnd->torvalds

	Arnd

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 14:12       ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2011-09-21 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 21 September 2011, Tony Lindgren wrote:
> * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > 
> > I'm wondering how hwspinlock updates like this should go upstream.
> > 
> > The first hwspinlock batch was picked by Tony, because it involved a
> > bulk of OMAP changes.
> > 
> > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > STE's u8500) and the vast majority of changes are in drivers/. We're
> > still very much ARM-related, though this may change too at some point
> > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > does).
> > 
> > Tony, if you're still willing to pick up these updates I'd be happy to
> > send you pull requests of course.
> 
> I'd prefer for Greg to take these as these are drivers.
> 
> If he's not taking it at this point based on it being ARM only,
> I can take it then.

Sorry for replying late, I had accidentally ignored the entire thread.

My feeling is that it would be best for Ohad to send these directly
to Linus, since it's basically a standalone subsystem and he's listed
as the maintainer (well, after this series at least).

I'm also fine with any of the other paths like

ohad->GregKH->torvalds
ohad->arnd->torvalds
ohad->tmlind->torvalds
ohad->tmlind->arnd->torvalds

	Arnd

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-20 23:45       ` Greg KH
@ 2011-09-21 15:24         ` Tony Lindgren
  -1 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 15:24 UTC (permalink / raw)
  To: Greg KH
  Cc: Ohad Ben-Cohen, Andrew Morton, Arnd Bergmann, Russell King,
	linux-omap, linux-kernel, linux-arm-kernel, Linus Walleij,
	Linus Torvalds, Nicolas Pitre, Thomas Gleixner, Stephen Rothwell,
	Grant Likely

* Greg KH <greg@kroah.com> [110921 07:27]:
> On Tue, Sep 20, 2011 at 04:13:40PM -0700, Tony Lindgren wrote:
> > * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > > 
> > > I'm wondering how hwspinlock updates like this should go upstream.
> > > 
> > > The first hwspinlock batch was picked by Tony, because it involved a
> > > bulk of OMAP changes.
> > > 
> > > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > > STE's u8500) and the vast majority of changes are in drivers/. We're
> > > still very much ARM-related, though this may change too at some point
> > > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > > does).
> > > 
> > > Tony, if you're still willing to pick up these updates I'd be happy to
> > > send you pull requests of course.
> > 
> > I'd prefer for Greg to take these as these are drivers.
> 
> What, am I the catch-all for drivers these days?
> 
> Oh, right, it looks like I am :)
> 
> > If he's not taking it at this point based on it being ARM only,
> > I can take it then.
> 
> Please do, I don't even have the ability to build them here, as I don't
> have an arm cross-compiler on this travel laptop.

OK so you're off the hook then :) Now we still need to sort out the
remaining options posted by Arnd.

Tony

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 15:24         ` Tony Lindgren
  0 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

* Greg KH <greg@kroah.com> [110921 07:27]:
> On Tue, Sep 20, 2011 at 04:13:40PM -0700, Tony Lindgren wrote:
> > * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > > 
> > > I'm wondering how hwspinlock updates like this should go upstream.
> > > 
> > > The first hwspinlock batch was picked by Tony, because it involved a
> > > bulk of OMAP changes.
> > > 
> > > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > > STE's u8500) and the vast majority of changes are in drivers/. We're
> > > still very much ARM-related, though this may change too at some point
> > > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > > does).
> > > 
> > > Tony, if you're still willing to pick up these updates I'd be happy to
> > > send you pull requests of course.
> > 
> > I'd prefer for Greg to take these as these are drivers.
> 
> What, am I the catch-all for drivers these days?
> 
> Oh, right, it looks like I am :)
> 
> > If he's not taking it at this point based on it being ARM only,
> > I can take it then.
> 
> Please do, I don't even have the ability to build them here, as I don't
> have an arm cross-compiler on this travel laptop.

OK so you're off the hook then :) Now we still need to sort out the
remaining options posted by Arnd.

Tony

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 14:12       ` Arnd Bergmann
@ 2011-09-21 15:28         ` Tony Lindgren
  -1 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 15:28 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ohad Ben-Cohen, Andrew Morton, Greg KH, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Walleij, Linus Torvalds,
	Nicolas Pitre, Thomas Gleixner, Stephen Rothwell, Grant Likely

* Arnd Bergmann <arnd@arndb.de> [110921 06:39]:
> On Wednesday 21 September 2011, Tony Lindgren wrote:
> > * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > > 
> > > I'm wondering how hwspinlock updates like this should go upstream.
> > > 
> > > The first hwspinlock batch was picked by Tony, because it involved a
> > > bulk of OMAP changes.
> > > 
> > > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > > STE's u8500) and the vast majority of changes are in drivers/. We're
> > > still very much ARM-related, though this may change too at some point
> > > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > > does).
> > > 
> > > Tony, if you're still willing to pick up these updates I'd be happy to
> > > send you pull requests of course.
> > 
> > I'd prefer for Greg to take these as these are drivers.
> > 
> > If he's not taking it at this point based on it being ARM only,
> > I can take it then.
> 
> Sorry for replying late, I had accidentally ignored the entire thread.
> 
> My feeling is that it would be best for Ohad to send these directly
> to Linus, since it's basically a standalone subsystem and he's listed
> as the maintainer (well, after this series at least).

Ohad can you please try this first? Just please make sure your patches are
first in next tree before sending in the pull request.
 
> I'm also fine with any of the other paths like
> 
> ohad->GregKH->torvalds

Greg does not prefer that as it's ARM only currently.

> ohad->arnd->torvalds
> ohad->tmlind->torvalds
> ohad->tmlind->arnd->torvalds

So as a backup plan any of these are also fine with me too.

Tony

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 15:28         ` Tony Lindgren
  0 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

* Arnd Bergmann <arnd@arndb.de> [110921 06:39]:
> On Wednesday 21 September 2011, Tony Lindgren wrote:
> > * Ohad Ben-Cohen <ohad@wizery.com> [110920 01:34]:
> > > On Mon, Sep 12, 2011 at 7:46 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > > 
> > > I'm wondering how hwspinlock updates like this should go upstream.
> > > 
> > > The first hwspinlock batch was picked by Tony, because it involved a
> > > bulk of OMAP changes.
> > > 
> > > Hwspinlock isn't OMAP-specific anymore though (we gained support for
> > > STE's u8500) and the vast majority of changes are in drivers/. We're
> > > still very much ARM-related, though this may change too at some point
> > > (c6x has a similar "hardware semaphore" peripheral like the u8500
> > > does).
> > > 
> > > Tony, if you're still willing to pick up these updates I'd be happy to
> > > send you pull requests of course.
> > 
> > I'd prefer for Greg to take these as these are drivers.
> > 
> > If he's not taking it at this point based on it being ARM only,
> > I can take it then.
> 
> Sorry for replying late, I had accidentally ignored the entire thread.
> 
> My feeling is that it would be best for Ohad to send these directly
> to Linus, since it's basically a standalone subsystem and he's listed
> as the maintainer (well, after this series at least).

Ohad can you please try this first? Just please make sure your patches are
first in next tree before sending in the pull request.
 
> I'm also fine with any of the other paths like
> 
> ohad->GregKH->torvalds

Greg does not prefer that as it's ARM only currently.

> ohad->arnd->torvalds
> ohad->tmlind->torvalds
> ohad->tmlind->arnd->torvalds

So as a backup plan any of these are also fine with me too.

Tony

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 14:12       ` Arnd Bergmann
@ 2011-09-21 15:53         ` Linus Walleij
  -1 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2011-09-21 15:53 UTC (permalink / raw)
  To: Arnd Bergmann, Ohad Ben-Cohen
  Cc: Tony Lindgren, Andrew Morton, Greg KH, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Torvalds, Nicolas Pitre,
	Thomas Gleixner, Stephen Rothwell, Grant Likely

On Wed, Sep 21, 2011 at 4:12 PM, Arnd Bergmann <arnd@arndb.de> wrote:

> My feeling is that it would be best for Ohad to send these directly
> to Linus, since it's basically a standalone subsystem and he's listed
> as the maintainer (well, after this series at least).

I agree. That's the path of least resistance and trouble.

If/when ARM-specific driver subsystems need their own zuper-maintainer
we can deal with it, can't we? There aren't many of them yet.

Yours,
Linus Walleij

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 15:53         ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2011-09-21 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 21, 2011 at 4:12 PM, Arnd Bergmann <arnd@arndb.de> wrote:

> My feeling is that it would be best for Ohad to send these directly
> to Linus, since it's basically a standalone subsystem and he's listed
> as the maintainer (well, after this series at least).

I agree. That's the path of least resistance and trouble.

If/when ARM-specific driver subsystems need their own zuper-maintainer
we can deal with it, can't we? There aren't many of them yet.

Yours,
Linus Walleij

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 15:28         ` Tony Lindgren
  (?)
@ 2011-09-21 15:56           ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 15:56 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Rothwell
  Cc: Arnd Bergmann, Andrew Morton, Greg KH, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Walleij, Linus Torvalds,
	Nicolas Pitre, Thomas Gleixner, Grant Likely

On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
> Ohad can you please try this first? Just please make sure your patches are
> first in next tree before sending in the pull request.

Sure thing.

Stephen, I'll send you the location of my tree in a few.

Thanks,
Ohad.

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

* Re: [PATCH 00/10] hwspinlock-next
@ 2011-09-21 15:56           ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 15:56 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Rothwell
  Cc: Russell King, Arnd Bergmann, Nicolas Pitre, Greg KH,
	Linus Walleij, linux-kernel, Grant Likely, Andrew Morton,
	linux-omap, Linus Torvalds, Thomas Gleixner, linux-arm-kernel

On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
> Ohad can you please try this first? Just please make sure your patches are
> first in next tree before sending in the pull request.

Sure thing.

Stephen, I'll send you the location of my tree in a few.

Thanks,
Ohad.

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 15:56           ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
> Ohad can you please try this first? Just please make sure your patches are
> first in next tree before sending in the pull request.

Sure thing.

Stephen, I'll send you the location of my tree in a few.

Thanks,
Ohad.

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 15:56           ` Ohad Ben-Cohen
@ 2011-09-21 16:07             ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 16:07 UTC (permalink / raw)
  To: Tony Lindgren, Stephen Rothwell
  Cc: Arnd Bergmann, Andrew Morton, Greg KH, Russell King, linux-omap,
	linux-kernel, linux-arm-kernel, Linus Walleij, Linus Torvalds,
	Nicolas Pitre, Thomas Gleixner, Grant Likely

On Wed, Sep 21, 2011 at 6:56 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
>> Ohad can you please try this first? Just please make sure your patches are
>> first in next tree before sending in the pull request.
>
> Sure thing.
>
> Stephen, I'll send you the location of my tree in a few.

Just before I do, Tony can I please have your Ack for the mach-omap2
part of this patch-set:

 arch/arm/mach-omap2/hwspinlock.c         |    8 +-

Thanks,
Ohad.

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 16:07             ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 21, 2011 at 6:56 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
>> Ohad can you please try this first? Just please make sure your patches are
>> first in next tree before sending in the pull request.
>
> Sure thing.
>
> Stephen, I'll send you the location of my tree in a few.

Just before I do, Tony can I please have your Ack for the mach-omap2
part of this patch-set:

 arch/arm/mach-omap2/hwspinlock.c         |    8 +-

Thanks,
Ohad.

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

* Re: [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
  2011-09-12 16:46   ` Ohad Ben-Cohen
@ 2011-09-21 16:14     ` Tony Lindgren
  -1 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 16:14 UTC (permalink / raw)
  To: Ohad Ben-Cohen; +Cc: linux-omap, linux-kernel, linux-arm-kernel, Arnd Bergmann

* Ohad Ben-Cohen <ohad@wizery.com> [110912 09:14]:
> hwspinlock devices provide system-wide hardware locks that are used
> by remote processors that have no other way to achieve synchronization.
> 
> For that to work, each physical lock must have a system-wide unique id
> number that all processors are familiar with, otherwise they can't
> possibly assume they're using the same hardware lock.
> 
> Usually SoCs have a single hwspinlock device, which provides several
> hwspinlocks, and in this case, they can be trivially numbered 0 to
> (num-of-locks - 1).
> 
> In case boards have several hwspinlocks devices (each of which
> providing numerous hardware spinlocks) a different base id should be
> used for each hwspinlock device (they can't all use 0 as a starting
> id!).
> 
> While this is certainly not common, it's just plain wrong to just
> silently use 0 as a base id whenever the hwspinlock driver is probed.
> 
> This patch provides a hwspinlock_pdata structure, that boards can use
> to set a different base id for each of the hwspinlock devices they may
> have, and demonstrates how to use it with the omap hwspinlock driver
> (ultimately it will be DT which will supply this base_id information).
> 
> While we're at it, make sure the hwspinlock core prints an explicit
> error message in case an hwspinlock is registered with an id number
> that already exists; this will help users catch such base id issues.
> 
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>

Acked-by: Tony Lindgren <tony@atomide.com>

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

* [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices
@ 2011-09-21 16:14     ` Tony Lindgren
  0 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

* Ohad Ben-Cohen <ohad@wizery.com> [110912 09:14]:
> hwspinlock devices provide system-wide hardware locks that are used
> by remote processors that have no other way to achieve synchronization.
> 
> For that to work, each physical lock must have a system-wide unique id
> number that all processors are familiar with, otherwise they can't
> possibly assume they're using the same hardware lock.
> 
> Usually SoCs have a single hwspinlock device, which provides several
> hwspinlocks, and in this case, they can be trivially numbered 0 to
> (num-of-locks - 1).
> 
> In case boards have several hwspinlocks devices (each of which
> providing numerous hardware spinlocks) a different base id should be
> used for each hwspinlock device (they can't all use 0 as a starting
> id!).
> 
> While this is certainly not common, it's just plain wrong to just
> silently use 0 as a base id whenever the hwspinlock driver is probed.
> 
> This patch provides a hwspinlock_pdata structure, that boards can use
> to set a different base id for each of the hwspinlock devices they may
> have, and demonstrates how to use it with the omap hwspinlock driver
> (ultimately it will be DT which will supply this base_id information).
> 
> While we're at it, make sure the hwspinlock core prints an explicit
> error message in case an hwspinlock is registered with an id number
> that already exists; this will help users catch such base id issues.
> 
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>

Acked-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 16:07             ` Ohad Ben-Cohen
@ 2011-09-21 16:14               ` Tony Lindgren
  -1 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 16:14 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Stephen Rothwell, Arnd Bergmann, Andrew Morton, Greg KH,
	Russell King, linux-omap, linux-kernel, linux-arm-kernel,
	Linus Walleij, Linus Torvalds, Nicolas Pitre, Thomas Gleixner,
	Grant Likely

* Ohad Ben-Cohen <ohad@wizery.com> [110921 08:34]:
> On Wed, Sep 21, 2011 at 6:56 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
> >> Ohad can you please try this first? Just please make sure your patches are
> >> first in next tree before sending in the pull request.
> >
> > Sure thing.
> >
> > Stephen, I'll send you the location of my tree in a few.
> 
> Just before I do, Tony can I please have your Ack for the mach-omap2
> part of this patch-set:
> 
>  arch/arm/mach-omap2/hwspinlock.c         |    8 +-

OK acked the related patch.

Tony

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 16:14               ` Tony Lindgren
  0 siblings, 0 replies; 67+ messages in thread
From: Tony Lindgren @ 2011-09-21 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

* Ohad Ben-Cohen <ohad@wizery.com> [110921 08:34]:
> On Wed, Sep 21, 2011 at 6:56 PM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> > On Wed, Sep 21, 2011 at 6:28 PM, Tony Lindgren <tony@atomide.com> wrote:
> >> Ohad can you please try this first? Just please make sure your patches are
> >> first in next tree before sending in the pull request.
> >
> > Sure thing.
> >
> > Stephen, I'll send you the location of my tree in a few.
> 
> Just before I do, Tony can I please have your Ack for the mach-omap2
> part of this patch-set:
> 
>  arch/arm/mach-omap2/hwspinlock.c         |    8 +-

OK acked the related patch.

Tony

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 16:14               ` Tony Lindgren
@ 2011-09-21 16:16                 ` Ohad Ben-Cohen
  -1 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 16:16 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Stephen Rothwell, Arnd Bergmann, Andrew Morton, Greg KH,
	Russell King, linux-omap, linux-kernel, linux-arm-kernel,
	Linus Walleij, Linus Torvalds, Nicolas Pitre, Thomas Gleixner,
	Grant Likely

On Wed, Sep 21, 2011 at 7:14 PM, Tony Lindgren <tony@atomide.com> wrote:
> OK acked the related patch.

Thanks!

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 16:16                 ` Ohad Ben-Cohen
  0 siblings, 0 replies; 67+ messages in thread
From: Ohad Ben-Cohen @ 2011-09-21 16:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 21, 2011 at 7:14 PM, Tony Lindgren <tony@atomide.com> wrote:
> OK acked the related patch.

Thanks!

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

* Re: [PATCH 00/10] hwspinlock-next
  2011-09-21 15:53         ` Linus Walleij
@ 2011-09-21 16:21           ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2011-09-21 16:21 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Ohad Ben-Cohen, Tony Lindgren, Andrew Morton, Greg KH,
	Russell King, linux-omap, linux-kernel, linux-arm-kernel,
	Linus Torvalds, Nicolas Pitre, Thomas Gleixner, Stephen Rothwell,
	Grant Likely

On Wednesday 21 September 2011, Linus Walleij wrote:
> On Wed, Sep 21, 2011 at 4:12 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> > My feeling is that it would be best for Ohad to send these directly
> > to Linus, since it's basically a standalone subsystem and he's listed
> > as the maintainer (well, after this series at least).
> 
> I agree. That's the path of least resistance and trouble.
> 
> If/when ARM-specific driver subsystems need their own zuper-maintainer
> we can deal with it, can't we? There aren't many of them yet.

Definitely, I think that's the ideal case. I would very much like to
see independent subsystem maintainers for the device drivers that are
currently buried in per-architecture or per-platform directories.
Among the ones that we should be moving out of there (or have already)
are cpufreq, gpio, irqchip, pinmux, clock, dmaengine, timer, and there
are probably some more. Since none of these are strictly ARM specific,
my feeling is that they should not be part of the arm or arm-soc tree
in the future but have their own trees.

	Arnd

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

* [PATCH 00/10] hwspinlock-next
@ 2011-09-21 16:21           ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2011-09-21 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 21 September 2011, Linus Walleij wrote:
> On Wed, Sep 21, 2011 at 4:12 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> > My feeling is that it would be best for Ohad to send these directly
> > to Linus, since it's basically a standalone subsystem and he's listed
> > as the maintainer (well, after this series at least).
> 
> I agree. That's the path of least resistance and trouble.
> 
> If/when ARM-specific driver subsystems need their own zuper-maintainer
> we can deal with it, can't we? There aren't many of them yet.

Definitely, I think that's the ideal case. I would very much like to
see independent subsystem maintainers for the device drivers that are
currently buried in per-architecture or per-platform directories.
Among the ones that we should be moving out of there (or have already)
are cpufreq, gpio, irqchip, pinmux, clock, dmaengine, timer, and there
are probably some more. Since none of these are strictly ARM specific,
my feeling is that they should not be part of the arm or arm-soc tree
in the future but have their own trees.

	Arnd

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

end of thread, other threads:[~2011-09-21 16:22 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-12 16:46 [PATCH 00/10] hwspinlock-next Ohad Ben-Cohen
2011-09-12 16:46 ` Ohad Ben-Cohen
2011-09-12 16:46 ` Ohad Ben-Cohen
2011-09-12 16:46 ` [PATCH 01/10] hwspinlock/core: simplify Kconfig Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46 ` [PATCH 02/10] hwspinlock/core: simplify 'owner' handling Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46 ` [PATCH 03/10] hwspinlock/omap: simplify allocation scheme Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46 ` [PATCH 04/10] hwspinlock/core/omap: fix id issues on multiple hwspinlock devices Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-12 16:46   ` Ohad Ben-Cohen
2011-09-21 16:14   ` Tony Lindgren
2011-09-21 16:14     ` Tony Lindgren
2011-09-12 16:47 ` [PATCH 05/10] hwspinlock/core: use a mutex to protect the radix tree Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47 ` [PATCH 06/10] hwspinlock/core: remove stubs for register/unregister Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47 ` [PATCH 07/10] hwspinlock/core: register a bank of hwspinlocks in a single API call Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47 ` [PATCH 08/10] hwspinlock/u8500: add hwspinlock driver Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47 ` [PATCH 09/10] hwspinlock/omap: omap_hwspinlock_remove should be __devexit Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47 ` [PATCH 10/10] hwspinlock: add MAINTAINERS entries Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:47   ` Ohad Ben-Cohen
2011-09-12 16:58   ` Joe Perches
2011-09-12 16:58     ` Joe Perches
2011-09-12 16:58     ` Joe Perches
2011-09-12 17:01     ` Ohad Ben-Cohen
2011-09-12 17:01       ` Ohad Ben-Cohen
2011-09-12 17:01       ` Ohad Ben-Cohen
2011-09-20  9:07 ` [PATCH 00/10] hwspinlock-next Ohad Ben-Cohen
2011-09-20  9:07   ` Ohad Ben-Cohen
2011-09-20  9:07   ` Ohad Ben-Cohen
2011-09-20 23:13   ` Tony Lindgren
2011-09-20 23:13     ` Tony Lindgren
2011-09-20 23:45     ` Greg KH
2011-09-20 23:45       ` Greg KH
2011-09-21 15:24       ` Tony Lindgren
2011-09-21 15:24         ` Tony Lindgren
2011-09-21 14:12     ` Arnd Bergmann
2011-09-21 14:12       ` Arnd Bergmann
2011-09-21 15:28       ` Tony Lindgren
2011-09-21 15:28         ` Tony Lindgren
2011-09-21 15:56         ` Ohad Ben-Cohen
2011-09-21 15:56           ` Ohad Ben-Cohen
2011-09-21 15:56           ` Ohad Ben-Cohen
2011-09-21 16:07           ` Ohad Ben-Cohen
2011-09-21 16:07             ` Ohad Ben-Cohen
2011-09-21 16:14             ` Tony Lindgren
2011-09-21 16:14               ` Tony Lindgren
2011-09-21 16:16               ` Ohad Ben-Cohen
2011-09-21 16:16                 ` Ohad Ben-Cohen
2011-09-21 15:53       ` Linus Walleij
2011-09-21 15:53         ` Linus Walleij
2011-09-21 16:21         ` Arnd Bergmann
2011-09-21 16:21           ` Arnd Bergmann

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.