All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
@ 2012-02-23 11:40 ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak

Re-sending as these patches did not make it to the lists due to
issues with my 'git send-email'

Hi Tony,

This is a re-spin of your series to fix up the section
mismatch warnings noted by Russell with omap2_hsmmc_init().
The previous series had an issue around multiple insmod/rmmod
of the twl4030 gpio driver when built as a module as reported
by Russell again.

There were 2 issues, one with gpio_requests failing as they were
never freed on the module unload/unbind. The other was with the
mmc devices being registered again. I have fixed both these issues
in this series, mainly by having a .teardown hook for twl4030 gpio
driver populated from all OMAP3 board files, which release all the
requested gpios and also unregister the mmc omap/platform device.

regards,
Rajendra

Ohad Ben-Cohen (1):
  ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register}

Rajendra Nayak (4):
  ARM: OMAP: omap_device: Add omap_device_unregister()
  mmc: omap_hsmmc: Make the driver support hotpluggable devices
  mmc: omap_hsmmc: If probe fails, give our error messages
  ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests

Tony Lindgren (2):
  ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO
    pins
  ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as
    __init

 arch/arm/mach-omap2/board-2430sdp.c           |    2 +-
 arch/arm/mach-omap2/board-3430sdp.c           |   22 +++-
 arch/arm/mach-omap2/board-4430sdp.c           |    4 +-
 arch/arm/mach-omap2/board-am3517evm.c         |    2 +-
 arch/arm/mach-omap2/board-cm-t35.c            |   18 +++-
 arch/arm/mach-omap2/board-devkit8000.c        |   17 +++-
 arch/arm/mach-omap2/board-flash.c             |    2 +-
 arch/arm/mach-omap2/board-igep0020.c          |   25 ++++-
 arch/arm/mach-omap2/board-ldp.c               |   11 ++-
 arch/arm/mach-omap2/board-omap3beagle.c       |   25 ++++-
 arch/arm/mach-omap2/board-omap3evm.c          |   22 +++-
 arch/arm/mach-omap2/board-omap3logic.c        |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c      |   22 +++-
 arch/arm/mach-omap2/board-omap3stalker.c      |   28 ++++--
 arch/arm/mach-omap2/board-omap3touchbook.c    |   30 ++++--
 arch/arm/mach-omap2/board-omap4panda.c        |    6 +-
 arch/arm/mach-omap2/board-overo.c             |   13 +++-
 arch/arm/mach-omap2/board-rm680.c             |    2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c  |   10 ++-
 arch/arm/mach-omap2/board-zoom-peripherals.c  |   18 +++-
 arch/arm/mach-omap2/display.c                 |    8 +-
 arch/arm/mach-omap2/hsmmc.c                   |  130 +++++++++++++++++++------
 arch/arm/mach-omap2/hsmmc.h                   |   17 +++-
 arch/arm/mach-omap2/mux.c                     |   14 ++--
 arch/arm/plat-omap/include/plat/omap_device.h |    8 ++
 arch/arm/plat-omap/omap_device.c              |   33 ++++---
 drivers/mmc/host/omap_hsmmc.c                 |   11 +-
 27 files changed, 372 insertions(+), 130 deletions(-)


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

* [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
@ 2012-02-23 11:40 ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Re-sending as these patches did not make it to the lists due to
issues with my 'git send-email'

Hi Tony,

This is a re-spin of your series to fix up the section
mismatch warnings noted by Russell with omap2_hsmmc_init().
The previous series had an issue around multiple insmod/rmmod
of the twl4030 gpio driver when built as a module as reported
by Russell again.

There were 2 issues, one with gpio_requests failing as they were
never freed on the module unload/unbind. The other was with the
mmc devices being registered again. I have fixed both these issues
in this series, mainly by having a .teardown hook for twl4030 gpio
driver populated from all OMAP3 board files, which release all the
requested gpios and also unregister the mmc omap/platform device.

regards,
Rajendra

Ohad Ben-Cohen (1):
  ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register}

Rajendra Nayak (4):
  ARM: OMAP: omap_device: Add omap_device_unregister()
  mmc: omap_hsmmc: Make the driver support hotpluggable devices
  mmc: omap_hsmmc: If probe fails, give our error messages
  ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests

Tony Lindgren (2):
  ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO
    pins
  ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as
    __init

 arch/arm/mach-omap2/board-2430sdp.c           |    2 +-
 arch/arm/mach-omap2/board-3430sdp.c           |   22 +++-
 arch/arm/mach-omap2/board-4430sdp.c           |    4 +-
 arch/arm/mach-omap2/board-am3517evm.c         |    2 +-
 arch/arm/mach-omap2/board-cm-t35.c            |   18 +++-
 arch/arm/mach-omap2/board-devkit8000.c        |   17 +++-
 arch/arm/mach-omap2/board-flash.c             |    2 +-
 arch/arm/mach-omap2/board-igep0020.c          |   25 ++++-
 arch/arm/mach-omap2/board-ldp.c               |   11 ++-
 arch/arm/mach-omap2/board-omap3beagle.c       |   25 ++++-
 arch/arm/mach-omap2/board-omap3evm.c          |   22 +++-
 arch/arm/mach-omap2/board-omap3logic.c        |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c      |   22 +++-
 arch/arm/mach-omap2/board-omap3stalker.c      |   28 ++++--
 arch/arm/mach-omap2/board-omap3touchbook.c    |   30 ++++--
 arch/arm/mach-omap2/board-omap4panda.c        |    6 +-
 arch/arm/mach-omap2/board-overo.c             |   13 +++-
 arch/arm/mach-omap2/board-rm680.c             |    2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c  |   10 ++-
 arch/arm/mach-omap2/board-zoom-peripherals.c  |   18 +++-
 arch/arm/mach-omap2/display.c                 |    8 +-
 arch/arm/mach-omap2/hsmmc.c                   |  130 +++++++++++++++++++------
 arch/arm/mach-omap2/hsmmc.h                   |   17 +++-
 arch/arm/mach-omap2/mux.c                     |   14 ++--
 arch/arm/plat-omap/include/plat/omap_device.h |    8 ++
 arch/arm/plat-omap/omap_device.c              |   33 ++++---
 drivers/mmc/host/omap_hsmmc.c                 |   11 +-
 27 files changed, 372 insertions(+), 130 deletions(-)

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

* [PATCH v2 1/7] ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register}
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony
  Cc: linux-omap, linux-arm-kernel, Ohad Ben-Cohen, Kevin Hilman,
	Rajendra Nayak

From: Ohad Ben-Cohen <ohad@wizery.com>

Expose omap_device_{alloc, delete, register} so we can use them outside
of omap_device.c.

This approach allows users, which need to manipulate an archdata member
of a device before it is registered, to do so. This is also useful
for users who have their devices created very early so they can be used
at ->reserve() time to reserve CMA memory.

The immediate use case for this is to set the private iommu archdata
member, which binds a device to its associated iommu controller.
This way, generic code will be able to attach omap devices to their
iommus, without calling any omap-specific API.

With this in hand, we can further clean the existing mainline OMAP iommu
driver and its mainline users, and focus on generic IOMMU approaches
for future users (rpmsg/remoteproc and the upcoming generic DMA API).

This patch is still considered an interim solution until DT fully materializes
for omap; at that point, this functionality will be removed as DT will
take care of creating the devices and configuring them correctly.

Tested on OMAP4 with a generic rpmsg/remoteproc that doesn't use any
omap-specific IOMMU API anymore.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    7 +++++++
 arch/arm/plat-omap/omap_device.c              |   13 +++----------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 51423d2..05f7615 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -100,6 +100,13 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 					 struct omap_device_pm_latency *pm_lats,
 					 int pm_lats_cnt, int is_early_device);
 
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
+				      struct omap_hwmod **ohs, int oh_cnt,
+				      struct omap_device_pm_latency *pm_lats,
+				      int pm_lats_cnt);
+void omap_device_delete(struct omap_device *od);
+int omap_device_register(struct platform_device *pdev);
+
 void __iomem *omap_device_get_rt_va(struct omap_device *od);
 struct device *omap_device_get_by_hwmod_name(const char *oh_name);
 
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index e8d9869..f72fafc 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -97,14 +97,7 @@
 #define USE_WAKEUP_LAT			0
 #define IGNORE_WAKEUP_LAT		1
 
-static int omap_device_register(struct platform_device *pdev);
 static int omap_early_device_register(struct platform_device *pdev);
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
-				      struct omap_hwmod **ohs, int oh_cnt,
-				      struct omap_device_pm_latency *pm_lats,
-				      int pm_lats_cnt);
-static void omap_device_delete(struct omap_device *od);
-
 
 static struct omap_device_pm_latency omap_default_latency[] = {
 	{
@@ -509,7 +502,7 @@ static int omap_device_fill_resources(struct omap_device *od,
  *
  * Returns an struct omap_device pointer or ERR_PTR() on error;
  */
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
 					struct omap_hwmod **ohs, int oh_cnt,
 					struct omap_device_pm_latency *pm_lats,
 					int pm_lats_cnt)
@@ -591,7 +584,7 @@ oda_exit1:
 	return ERR_PTR(ret);
 }
 
-static void omap_device_delete(struct omap_device *od)
+void omap_device_delete(struct omap_device *od)
 {
 	if (!od)
 		return;
@@ -817,7 +810,7 @@ static struct dev_pm_domain omap_device_pm_domain = {
  * platform_device_register() on the underlying platform_device.
  * Returns the return value of platform_device_register().
  */
-static int omap_device_register(struct platform_device *pdev)
+int omap_device_register(struct platform_device *pdev)
 {
 	pr_debug("omap_device: %s: registering\n", pdev->name);
 
-- 
1.7.1


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

* [PATCH v2 1/7] ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register}
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ohad Ben-Cohen <ohad@wizery.com>

Expose omap_device_{alloc, delete, register} so we can use them outside
of omap_device.c.

This approach allows users, which need to manipulate an archdata member
of a device before it is registered, to do so. This is also useful
for users who have their devices created very early so they can be used
at ->reserve() time to reserve CMA memory.

The immediate use case for this is to set the private iommu archdata
member, which binds a device to its associated iommu controller.
This way, generic code will be able to attach omap devices to their
iommus, without calling any omap-specific API.

With this in hand, we can further clean the existing mainline OMAP iommu
driver and its mainline users, and focus on generic IOMMU approaches
for future users (rpmsg/remoteproc and the upcoming generic DMA API).

This patch is still considered an interim solution until DT fully materializes
for omap; at that point, this functionality will be removed as DT will
take care of creating the devices and configuring them correctly.

Tested on OMAP4 with a generic rpmsg/remoteproc that doesn't use any
omap-specific IOMMU API anymore.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    7 +++++++
 arch/arm/plat-omap/omap_device.c              |   13 +++----------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 51423d2..05f7615 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -100,6 +100,13 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 					 struct omap_device_pm_latency *pm_lats,
 					 int pm_lats_cnt, int is_early_device);
 
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
+				      struct omap_hwmod **ohs, int oh_cnt,
+				      struct omap_device_pm_latency *pm_lats,
+				      int pm_lats_cnt);
+void omap_device_delete(struct omap_device *od);
+int omap_device_register(struct platform_device *pdev);
+
 void __iomem *omap_device_get_rt_va(struct omap_device *od);
 struct device *omap_device_get_by_hwmod_name(const char *oh_name);
 
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index e8d9869..f72fafc 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -97,14 +97,7 @@
 #define USE_WAKEUP_LAT			0
 #define IGNORE_WAKEUP_LAT		1
 
-static int omap_device_register(struct platform_device *pdev);
 static int omap_early_device_register(struct platform_device *pdev);
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
-				      struct omap_hwmod **ohs, int oh_cnt,
-				      struct omap_device_pm_latency *pm_lats,
-				      int pm_lats_cnt);
-static void omap_device_delete(struct omap_device *od);
-
 
 static struct omap_device_pm_latency omap_default_latency[] = {
 	{
@@ -509,7 +502,7 @@ static int omap_device_fill_resources(struct omap_device *od,
  *
  * Returns an struct omap_device pointer or ERR_PTR() on error;
  */
-static struct omap_device *omap_device_alloc(struct platform_device *pdev,
+struct omap_device *omap_device_alloc(struct platform_device *pdev,
 					struct omap_hwmod **ohs, int oh_cnt,
 					struct omap_device_pm_latency *pm_lats,
 					int pm_lats_cnt)
@@ -591,7 +584,7 @@ oda_exit1:
 	return ERR_PTR(ret);
 }
 
-static void omap_device_delete(struct omap_device *od)
+void omap_device_delete(struct omap_device *od)
 {
 	if (!od)
 		return;
@@ -817,7 +810,7 @@ static struct dev_pm_domain omap_device_pm_domain = {
  * platform_device_register() on the underlying platform_device.
  * Returns the return value of platform_device_register().
  */
-static int omap_device_register(struct platform_device *pdev)
+int omap_device_register(struct platform_device *pdev)
 {
 	pr_debug("omap_device: %s: registering\n", pdev->name);
 
-- 
1.7.1

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

* [PATCH v2 2/7] ARM: OMAP: omap_device: Add omap_device_unregister()
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak, Kevin Hilman

Add support to unregister an omap_device using
omap_device_unregister api.

While here, also fix the kerneldoc comments for
omap_device_register.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    1 +
 arch/arm/plat-omap/omap_device.c              |   20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 05f7615..ce0dc86 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -106,6 +106,7 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
 				      int pm_lats_cnt);
 void omap_device_delete(struct omap_device *od);
 int omap_device_register(struct platform_device *pdev);
+void omap_device_unregister(struct platform_device *pdev);
 
 void __iomem *omap_device_get_rt_va(struct omap_device *od);
 struct device *omap_device_get_by_hwmod_name(const char *oh_name);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f72fafc..ae7f055 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -807,8 +807,8 @@ static struct dev_pm_domain omap_device_pm_domain = {
  * @od: struct omap_device * to register
  *
  * Register the omap_device structure.  This currently just calls
- * platform_device_register() on the underlying platform_device.
- * Returns the return value of platform_device_register().
+ * platform_device_add() on the underlying platform_device.
+ * Returns the return value of platform_device_add().
  */
 int omap_device_register(struct platform_device *pdev)
 {
@@ -819,6 +819,22 @@ int omap_device_register(struct platform_device *pdev)
 	return platform_device_add(pdev);
 }
 
+/**
+ * omap_device_unregister - unregister an omap_device with one omap_hwmod
+ * @od: struct omap_device * to unregister
+ *
+ * Unregister the omap_device structure.  This currently just calls
+ * platform_device_del() on the underlying platform_device.
+ * No return value.
+ */
+void omap_device_unregister(struct platform_device *pdev)
+{
+	pr_debug("omap_device: %s: unregistering\n", pdev->name);
+
+	pdev->dev.parent = &omap_device_parent;
+	pdev->dev.pm_domain = &omap_device_pm_domain;
+	platform_device_del(pdev);
+}
 
 /* Public functions for use by device drivers through struct platform_data */
 
-- 
1.7.1


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

* [PATCH v2 2/7] ARM: OMAP: omap_device: Add omap_device_unregister()
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add support to unregister an omap_device using
omap_device_unregister api.

While here, also fix the kerneldoc comments for
omap_device_register.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    1 +
 arch/arm/plat-omap/omap_device.c              |   20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 05f7615..ce0dc86 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -106,6 +106,7 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
 				      int pm_lats_cnt);
 void omap_device_delete(struct omap_device *od);
 int omap_device_register(struct platform_device *pdev);
+void omap_device_unregister(struct platform_device *pdev);
 
 void __iomem *omap_device_get_rt_va(struct omap_device *od);
 struct device *omap_device_get_by_hwmod_name(const char *oh_name);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f72fafc..ae7f055 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -807,8 +807,8 @@ static struct dev_pm_domain omap_device_pm_domain = {
  * @od: struct omap_device * to register
  *
  * Register the omap_device structure.  This currently just calls
- * platform_device_register() on the underlying platform_device.
- * Returns the return value of platform_device_register().
+ * platform_device_add() on the underlying platform_device.
+ * Returns the return value of platform_device_add().
  */
 int omap_device_register(struct platform_device *pdev)
 {
@@ -819,6 +819,22 @@ int omap_device_register(struct platform_device *pdev)
 	return platform_device_add(pdev);
 }
 
+/**
+ * omap_device_unregister - unregister an omap_device with one omap_hwmod
+ * @od: struct omap_device * to unregister
+ *
+ * Unregister the omap_device structure.  This currently just calls
+ * platform_device_del() on the underlying platform_device.
+ * No return value.
+ */
+void omap_device_unregister(struct platform_device *pdev)
+{
+	pr_debug("omap_device: %s: unregistering\n", pdev->name);
+
+	pdev->dev.parent = &omap_device_parent;
+	pdev->dev.pm_domain = &omap_device_pm_domain;
+	platform_device_del(pdev);
+}
 
 /* Public functions for use by device drivers through struct platform_data */
 
-- 
1.7.1

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

* [PATCH v2 3/7] mmc: omap_hsmmc: Make the driver support hotpluggable devices
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak, Chris Ball, linux-mmc

Make the hsmmc driver register the driver using platform_driver_register()
so it can support hotpluggable devices.

This is needed, for instance, in case of OMAP3, wherein some of the mmc
devices might get added and removed dynamically based on dependent modules
like twl4030-gpio.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: <linux-mmc@vger.kernel.org>
---
 drivers/mmc/host/omap_hsmmc.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fd0c661..21b8afa 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1847,7 +1847,7 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc)
 
 #endif
 
-static int __init omap_hsmmc_probe(struct platform_device *pdev)
+static int omap_hsmmc_probe(struct platform_device *pdev)
 {
 	struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
 	struct mmc_host *mmc;
@@ -2264,6 +2264,7 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
 };
 
 static struct platform_driver omap_hsmmc_driver = {
+	.probe		= omap_hsmmc_probe,
 	.remove		= omap_hsmmc_remove,
 	.driver		= {
 		.name = DRIVER_NAME,
@@ -2275,7 +2276,7 @@ static struct platform_driver omap_hsmmc_driver = {
 static int __init omap_hsmmc_init(void)
 {
 	/* Register the MMC driver */
-	return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
+	return platform_driver_register(&omap_hsmmc_driver);
 }
 
 static void __exit omap_hsmmc_cleanup(void)
-- 
1.7.1


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

* [PATCH v2 3/7] mmc: omap_hsmmc: Make the driver support hotpluggable devices
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Make the hsmmc driver register the driver using platform_driver_register()
so it can support hotpluggable devices.

This is needed, for instance, in case of OMAP3, wherein some of the mmc
devices might get added and removed dynamically based on dependent modules
like twl4030-gpio.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: <linux-mmc@vger.kernel.org>
---
 drivers/mmc/host/omap_hsmmc.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fd0c661..21b8afa 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1847,7 +1847,7 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc)
 
 #endif
 
-static int __init omap_hsmmc_probe(struct platform_device *pdev)
+static int omap_hsmmc_probe(struct platform_device *pdev)
 {
 	struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
 	struct mmc_host *mmc;
@@ -2264,6 +2264,7 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
 };
 
 static struct platform_driver omap_hsmmc_driver = {
+	.probe		= omap_hsmmc_probe,
 	.remove		= omap_hsmmc_remove,
 	.driver		= {
 		.name = DRIVER_NAME,
@@ -2275,7 +2276,7 @@ static struct platform_driver omap_hsmmc_driver = {
 static int __init omap_hsmmc_init(void)
 {
 	/* Register the MMC driver */
-	return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe);
+	return platform_driver_register(&omap_hsmmc_driver);
 }
 
 static void __exit omap_hsmmc_cleanup(void)
-- 
1.7.1

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

* [PATCH v2 4/7] mmc: omap_hsmmc: If probe fails, give our error messages
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak, Chris Ball, linux-mmc

Giving our debug messages even in case of probe failure seems
not very useful. Make them error messages instead.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: <linux-mmc@vger.kernel.org>
---
 drivers/mmc/host/omap_hsmmc.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 21b8afa..653ffee 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2008,13 +2008,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 	ret = request_irq(host->irq, omap_hsmmc_irq, 0,
 			mmc_hostname(mmc), host);
 	if (ret) {
-		dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+		dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
 		goto err_irq;
 	}
 
 	if (pdata->init != NULL) {
 		if (pdata->init(&pdev->dev) != 0) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to configure MMC IRQs\n");
 			goto err_irq_cd_init;
 		}
@@ -2037,7 +2037,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 					   mmc_hostname(mmc), host);
 		if (ret) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to grab MMC CD IRQ\n");
 			goto err_irq_cd;
 		}
-- 
1.7.1


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

* [PATCH v2 4/7] mmc: omap_hsmmc: If probe fails, give our error messages
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

Giving our debug messages even in case of probe failure seems
not very useful. Make them error messages instead.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: <linux-mmc@vger.kernel.org>
---
 drivers/mmc/host/omap_hsmmc.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 21b8afa..653ffee 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2008,13 +2008,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 	ret = request_irq(host->irq, omap_hsmmc_irq, 0,
 			mmc_hostname(mmc), host);
 	if (ret) {
-		dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+		dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
 		goto err_irq;
 	}
 
 	if (pdata->init != NULL) {
 		if (pdata->init(&pdev->dev) != 0) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to configure MMC IRQs\n");
 			goto err_irq_cd_init;
 		}
@@ -2037,7 +2037,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 					   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 					   mmc_hostname(mmc), host);
 		if (ret) {
-			dev_dbg(mmc_dev(host->mmc),
+			dev_err(mmc_dev(host->mmc),
 				"Unable to grab MMC CD IRQ\n");
 			goto err_irq_cd;
 		}
-- 
1.7.1

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak

From: Tony Lindgren <tony@atomide.com>

Otherwise omap_device_build() and omap_mux related functions
can't be marked as __init when twl is build as a module.

If a board is using GPIO pins or regulators configured by an
external chip, such as TWL PMIC on I2C bus, the board must
mark those MMC controllers as deferred. Additionally both
omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
by the board.

For MMC controllers using internal GPIO pins for card
detect and regulators the slots don't need to be marked
deferred. In this case calling omap_hsmmc_init() is sufficient.

Note that this patch does not change the behaviour for
board-4430sdp.c board-omap4panda.c. These boards wrongly
rely on the omap_hsmmc.c init function callback to configure
the PMIC GPIO interrupt lines on external chip. If the PMIC
interrupt lines are not configured during init, they will
fail.

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
 arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
 arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
 arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
 arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
 arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
 arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
 arch/arm/mach-omap2/board-ldp.c              |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
 arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
 arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
 arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
 arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
 arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
 arch/arm/mach-omap2/board-overo.c            |    5 +-
 arch/arm/mach-omap2/board-rm680.c            |    2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
 arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
 arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
 21 files changed, 165 insertions(+), 89 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 7370983..c8bda62 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -279,7 +279,7 @@ static void __init omap_2430sdp_init(void)
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
 	omap_serial_init();
 	omap_sdrc_init(NULL, NULL);
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 	omap2_usbfs_init(&sdp2430_usb_config);
 
 	omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 383717b..f93bb84 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -232,11 +232,15 @@ static struct omap2_hsmmc_info mmc[] = {
 		 */
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
 		.gpio_wp	= 4,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
 		.gpio_wp	= 7,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -244,12 +248,7 @@ static struct omap2_hsmmc_info mmc[] = {
 static int sdp3430_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	/* gpio + 0 is "mmc0_cd" (input/IRQ),
-	 * gpio + 1 is "mmc1_cd" (input/IRQ)
-	 */
-	mmc[0].gpio_cd = gpio + 0;
-	mmc[1].gpio_cd = gpio + 1;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
 	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
@@ -606,6 +605,7 @@ static void __init omap_3430sdp_init(void)
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_board_config = sdp3430_config;
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	omap_hsmmc_init(mmc);
 	omap3430_i2c_init();
 	omap_display_init(&sdp3430_dss_data);
 	if (omap_rev() > OMAP3430_REV_ES1_0)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4e90715..09ae257 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -491,9 +491,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	struct omap2_hsmmc_info *c;
 
-	omap2_hsmmc_init(controllers);
+	omap_hsmmc_init(controllers);
 	for (c = controllers; c->mmc; c++)
-		omap4_twl6030_hsmmc_set_late_init(c->dev);
+		omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 4b1cfe3..71138a1 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -504,7 +504,7 @@ static void __init am3517_evm_init(void)
 	am3517_evm_musb_init();
 
 	/* MMC init function */
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 }
 
 MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index d73316e..14df109 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
-
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
@@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
 		.ocr_mask	= 0x00100000,	/* 3.3V */
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
 		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
 	}
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	return 0;
 }
@@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
 	omap_serial_init();
 	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
+	omap_hsmmc_init(mmc);
 	cm_t35_init_i2c();
 	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
 	cm_t35_init_ethernet();
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index e873063..6b99a5e 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -99,7 +99,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 29,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -226,9 +228,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -636,6 +636,7 @@ static void __init devkit8000_init(void)
 
 	omap_dm9000_init();
 
+	omap_hsmmc_init(mmc);
 	devkit8000_i2c_init();
 	platform_add_devices(devkit8000_devices,
 			ARRAY_SIZE(devkit8000_devices));
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index a59ace0..11a6aa4 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
 	{
@@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.caps		= MMC_CAP_4_BIT_DATA,
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 #endif
 	{}      /* Terminator */
@@ -400,9 +402,7 @@ static int igep_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
@@ -639,6 +639,9 @@ static void __init igep_init(void)
 
 	/* Get IGEP2 hardware revision */
 	igep2_get_revision();
+
+	omap_hsmmc_init(mmc);
+
 	/* Register I2C busses and drivers */
 	igep_i2c_init();
 	platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 2d2a61f..b5bc9b2 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -424,7 +424,7 @@ static void __init omap_ldp_init(void)
 	board_nand_init(ldp_nand_partitions,
 		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
 
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 	ldp_display_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 7ffcd28..e219b7d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -252,7 +252,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -275,9 +277,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
 	if (beagle_config.mmc1_gpio_wp != -EINVAL)
 		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
@@ -521,6 +521,7 @@ static void __init omap3_beagle_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3_beagle_init_rev();
+	omap_hsmmc_init(mmc);
 	omap3_beagle_i2c_init();
 
 	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c775bea..b736c4d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -315,8 +315,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 63,
+		.deferred	= true,
 	},
 #ifdef CONFIG_WL12XX_PLATFORM_DATA
 	{
@@ -326,6 +327,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.gpio_cd	= -EINVAL,
 		.nonremovable	= true,
+		.deferred	= true,
 	},
 #endif
 	{}	/* Terminator */
@@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 {
 	int r, lcd_bl_en;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -644,6 +644,7 @@ static void __init omap3_evm_init(void)
 	omap_board_config = omap3_evm_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
+	omap_hsmmc_init(mmc);
 	omap3_evm_i2c_init();
 
 	omap_display_init(&omap3_evm_dss_data);
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 4198dd0..2304ba3 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -128,7 +128,7 @@ static void __init board_mmc_init(void)
 		return;
 	}
 
-	omap2_hsmmc_init(board_mmc_info);
+	omap_hsmmc_init(board_mmc_info);
 }
 
 static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 1644b73..d984048 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -270,17 +270,19 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 126,
 		.ext_clock	= 0,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
 		.gpio_wp	= 127,
 		.ext_clock	= 1,
 		.transceiver	= true,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 3,
@@ -288,6 +290,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
 		.init_card	= pandora_wl1251_init_card,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -297,10 +300,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
 {
 	int ret, gpio_32khz;
 
-	/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
-	omap3pandora_mmc[0].gpio_cd = gpio + 0;
-	omap3pandora_mmc[1].gpio_cd = gpio + 1;
-	omap2_hsmmc_init(omap3pandora_mmc);
+	omap_hsmmc_deferred_add(omap3pandora_mmc);
 
 	/* gpio + 13 drives 32kHz buffer for wifi module */
 	gpio_32khz = gpio + 13;
@@ -580,6 +580,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init omap3pandora_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_hsmmc_init(omap3pandora_mmc);
 	omap3pandora_i2c_init();
 	pandora_wl1251_init();
 	platform_add_devices(omap3pandora_devices,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index cb089a4..a2fb3e3 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -209,10 +209,11 @@ static struct regulator_init_data omap3stalker_vsim = {
 
 static struct omap2_hsmmc_info mmc[] = {
 	{
-	 .mmc		= 1,
-	 .caps		= MMC_CAP_4_BIT_DATA,
-	 .gpio_cd	= -EINVAL,
-	 .gpio_wp	= 23,
+		.mmc		= 1,
+		.caps		= MMC_CAP_4_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
+		.gpio_wp	= 23,
+		.deferred	= true,
 	 },
 	{}			/* Terminator */
 };
@@ -281,10 +282,8 @@ static int
 omap3stalker_twl_gpio_setup(struct device *dev,
 			    unsigned gpio, unsigned ngpio)
 {
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -425,6 +424,7 @@ static void __init omap3_stalker_init(void)
 	omap_board_config = omap3_stalker_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
+	omap_hsmmc_init(mmc);
 	omap3_stalker_i2c_init();
 
 	platform_add_devices(omap3_stalker_devices,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index a0b851a..b5ff46b 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -99,7 +99,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 29,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -123,9 +125,7 @@ static int touchbook_twl_gpio_setup(struct device *dev,
 	} else {
 		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
 	}
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* REVISIT: need ehci-omap hooks for external VBUS
 	 * power switch and overcurrent detect
@@ -351,6 +351,7 @@ static void __init omap3_touchbook_init(void)
 
 	pm_power_off = omap3_touchbook_poweroff;
 
+	omap_hsmmc_init(mmc);
 	omap3_touchbook_i2c_init();
 	platform_add_devices(omap3_touchbook_devices,
 			ARRAY_SIZE(omap3_touchbook_devices));
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 28fc271..bcc563c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -245,9 +245,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	struct omap2_hsmmc_info *c;
 
-	omap2_hsmmc_init(controllers);
+	omap_hsmmc_init(controllers);
 	for (c = controllers; c->mmc; c++)
-		omap4_twl6030_hsmmc_set_late_init(c->dev);
+		omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 52c0cef..8b6065b 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -301,6 +301,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.caps		= MMC_CAP_4_BIT_DATA,
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
@@ -309,6 +310,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.transceiver	= true,
 		.ocr_mask	= 0x00100000,	/* 3.3V */
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -407,7 +409,7 @@ static inline void __init overo_init_keys(void) { return; }
 static int overo_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
@@ -505,6 +507,7 @@ static void __init overo_init(void)
 	int ret;
 
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_hsmmc_init(mmc);
 	overo_i2c_init();
 	omap_display_init(&overo_dss_data);
 	omap_serial_init();
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 8678b38..2d24c98 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -120,7 +120,7 @@ static void __init rm680_peripherals_init(void)
 				ARRAY_SIZE(rm680_peripherals_devices));
 	rm680_i2c_init();
 	gpmc_onenand_init(board_onenand_data);
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 }
 
 #ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index acb4e77..0e9d89a 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -1145,7 +1145,7 @@ void __init rx51_peripherals_init(void)
 
 	partition = omap_mux_get("core");
 	if (partition)
-		omap2_hsmmc_init(mmc);
+		omap_hsmmc_init(mmc);
 
 	rx51_charger_init();
 }
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index c126461..f99284f 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -203,8 +203,10 @@ static struct omap2_hsmmc_info mmc[] = {
 		.name		= "external",
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
 		.power_saving	= true,
+		.deferred	= true,
 	},
 	{
 		.name		= "internal",
@@ -214,6 +216,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.nonremovable	= true,
 		.power_saving	= true,
+		.deferred	= true,
 	},
 	{
 		.name		= "wl1271",
@@ -222,6 +225,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.gpio_cd	= -EINVAL,
 		.nonremovable	= true,
+		.deferred	= true,
 	},
 	{}      /* Terminator */
 };
@@ -231,9 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
 			       "lcd enable");
@@ -301,6 +303,7 @@ void __init zoom_peripherals_init(void)
 	if (ret)
 		pr_err("error setting wl12xx data: %d\n", ret);
 
+	omap_hsmmc_init(mmc);
 	omap_i2c_init();
 	platform_device_register(&omap_vwlan_device);
 	usb_musb_init(NULL);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b40c288..51e3a2d 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -430,64 +430,118 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 
 #define MAX_OMAP_MMC_HWMOD_NAME_LEN		16
 
-void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+static void omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
+						int ctrl_nr, int deferred)
 {
 	struct omap_hwmod *oh;
+	struct omap_hwmod *ohs[1];
+	struct omap_device *od;
 	struct platform_device *pdev;
 	char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
 	struct omap_mmc_platform_data *mmc_data;
 	struct omap_mmc_dev_attr *mmc_dev_attr;
 	char *name;
-	int l;
+	int res;
 
-	mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
-	if (!mmc_data) {
-		pr_err("Cannot allocate memory for mmc device!\n");
-		goto done;
-	}
+	if (!hsmmcinfo->mmc_data) {
+		mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
+		if (!mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			return;
+		}
 
-	if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
-		pr_err("%s fails!\n", __func__);
-		goto done;
+		res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
+		if (res < 0)
+			goto free_mmc;
+
+		omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+		hsmmcinfo->mmc_data = kmemdup(mmc_data, sizeof(*mmc_data),
+								 GFP_KERNEL);
+		if (!hsmmcinfo->mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			goto free_mmc;
+		}
+	} else	{
+		mmc_data = kmemdup(hsmmcinfo->mmc_data, sizeof(*mmc_data),
+								 GFP_KERNEL);
+		if (!mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			return;
+		}
 	}
-	omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
 
-	name = "omap_hsmmc";
+	if (deferred)
+		goto free_mmc;
 
-	l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
+	name = "omap_hsmmc";
+	res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
 		     "mmc%d", ctrl_nr);
-	WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
+	WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
 	     "String buffer overflow in MMC%d device setup\n", ctrl_nr);
+
 	oh = omap_hwmod_lookup(oh_name);
 	if (!oh) {
 		pr_err("Could not look up %s\n", oh_name);
-		kfree(mmc_data->slots[0].name);
-		goto done;
+		goto free_name;
 	}
-
+	ohs[0] = oh;
 	if (oh->dev_attr != NULL) {
 		mmc_dev_attr = oh->dev_attr;
 		mmc_data->controller_flags = mmc_dev_attr->flags;
 	}
 
-	pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
-		sizeof(struct omap_mmc_platform_data), NULL, 0, false);
-	if (IS_ERR(pdev)) {
-		WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
-		kfree(mmc_data->slots[0].name);
-		goto done;
+	pdev = platform_device_alloc(name, ctrl_nr - 1);
+	if (!pdev) {
+		pr_err("Could not allocate pdev for %s\n", name);
+		goto free_name;
+	}
+	dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+
+	od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
+	if (!od) {
+		pr_err("Could not allocate od for %s\n", name);
+		goto put_pdev;
 	}
-	/*
-	 * return device handle to board setup code
-	 * required to populate for regulator framework structure
-	 */
-	hsmmcinfo->dev = &pdev->dev;
 
-done:
+	res = platform_device_add_data(pdev, mmc_data, sizeof(*mmc_data));
+	if (res) {
+		pr_err("Could not add pdata for %s\n", name);
+		goto put_pdev;
+	}
+
+	hsmmcinfo->pdev = pdev;
+
+	res = omap_device_register(pdev);
+	if (res) {
+		pr_err("Could not register od for %s\n", name);
+		goto free_od;
+	}
+
+	goto free_mmc;
+
+free_od:
+	omap_device_delete(od);
+
+put_pdev:
+	platform_device_put(pdev);
+
+free_name:
+	kfree(mmc_data->slots[0].name);
+
+free_mmc:
 	kfree(mmc_data);
 }
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
+{
+	for (; controllers->mmc; controllers++) {
+		if (!controllers->deferred)
+			continue;
+		omap_hsmmc_init_one(controllers, controllers->mmc, 0);
+	}
+}
+
+void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
 
@@ -515,7 +569,8 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 	}
 
 	for (; controllers->mmc; controllers++)
-		omap_init_hsmmc(controllers, controllers->mmc);
+		omap_hsmmc_init_one(controllers, controllers->mmc,
+						 controllers->deferred);
 
 }
 
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index c440973..75d57fb 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -21,24 +21,31 @@ struct omap2_hsmmc_info {
 	bool	no_off;		/* power_saving and power is not to go off */
 	bool	no_off_init;	/* no power off when not in MMC sleep state */
 	bool	vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+	bool	deferred;	/* mmc needs a deferred probe */
 	int	gpio_cd;	/* or -EINVAL */
 	int	gpio_wp;	/* or -EINVAL */
 	char	*name;		/* or NULL for default */
-	struct device *dev;	/* returned: pointer to mmc adapter */
+	struct platform_device *pdev;	/* mmc controller instance */
 	int	ocr_mask;	/* temporary HACK */
 	/* Remux (pad configuration) when powering on/off */
 	void (*remux)(struct device *dev, int slot, int power_on);
 	/* init some special card */
 	void (*init_card)(struct mmc_card *card);
+	struct omap_mmc_platform_data *mmc_data;
 };
 
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *);
 
 #else
 
-static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
+static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+static inline void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *info)
 {
 }
 
-- 
1.7.1


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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tony Lindgren <tony@atomide.com>

Otherwise omap_device_build() and omap_mux related functions
can't be marked as __init when twl is build as a module.

If a board is using GPIO pins or regulators configured by an
external chip, such as TWL PMIC on I2C bus, the board must
mark those MMC controllers as deferred. Additionally both
omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
by the board.

For MMC controllers using internal GPIO pins for card
detect and regulators the slots don't need to be marked
deferred. In this case calling omap_hsmmc_init() is sufficient.

Note that this patch does not change the behaviour for
board-4430sdp.c board-omap4panda.c. These boards wrongly
rely on the omap_hsmmc.c init function callback to configure
the PMIC GPIO interrupt lines on external chip. If the PMIC
interrupt lines are not configured during init, they will
fail.

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
 arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
 arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
 arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
 arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
 arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
 arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
 arch/arm/mach-omap2/board-ldp.c              |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
 arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
 arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
 arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
 arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
 arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
 arch/arm/mach-omap2/board-overo.c            |    5 +-
 arch/arm/mach-omap2/board-rm680.c            |    2 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
 arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
 arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
 21 files changed, 165 insertions(+), 89 deletions(-)

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 7370983..c8bda62 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -279,7 +279,7 @@ static void __init omap_2430sdp_init(void)
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
 	omap_serial_init();
 	omap_sdrc_init(NULL, NULL);
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 	omap2_usbfs_init(&sdp2430_usb_config);
 
 	omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 383717b..f93bb84 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -232,11 +232,15 @@ static struct omap2_hsmmc_info mmc[] = {
 		 */
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
 		.gpio_wp	= 4,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
 		.gpio_wp	= 7,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -244,12 +248,7 @@ static struct omap2_hsmmc_info mmc[] = {
 static int sdp3430_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	/* gpio + 0 is "mmc0_cd" (input/IRQ),
-	 * gpio + 1 is "mmc1_cd" (input/IRQ)
-	 */
-	mmc[0].gpio_cd = gpio + 0;
-	mmc[1].gpio_cd = gpio + 1;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
 	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
@@ -606,6 +605,7 @@ static void __init omap_3430sdp_init(void)
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_board_config = sdp3430_config;
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	omap_hsmmc_init(mmc);
 	omap3430_i2c_init();
 	omap_display_init(&sdp3430_dss_data);
 	if (omap_rev() > OMAP3430_REV_ES1_0)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4e90715..09ae257 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -491,9 +491,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	struct omap2_hsmmc_info *c;
 
-	omap2_hsmmc_init(controllers);
+	omap_hsmmc_init(controllers);
 	for (c = controllers; c->mmc; c++)
-		omap4_twl6030_hsmmc_set_late_init(c->dev);
+		omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 4b1cfe3..71138a1 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -504,7 +504,7 @@ static void __init am3517_evm_init(void)
 	am3517_evm_musb_init();
 
 	/* MMC init function */
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 }
 
 MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index d73316e..14df109 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
-
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
@@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
 		.ocr_mask	= 0x00100000,	/* 3.3V */
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
 		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
 	}
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	return 0;
 }
@@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
 	omap_serial_init();
 	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params);
+	omap_hsmmc_init(mmc);
 	cm_t35_init_i2c();
 	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
 	cm_t35_init_ethernet();
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index e873063..6b99a5e 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -99,7 +99,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 29,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -226,9 +228,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -636,6 +636,7 @@ static void __init devkit8000_init(void)
 
 	omap_dm9000_init();
 
+	omap_hsmmc_init(mmc);
 	devkit8000_i2c_init();
 	platform_add_devices(devkit8000_devices,
 			ARRAY_SIZE(devkit8000_devices));
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index a59ace0..11a6aa4 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
 	{
@@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.caps		= MMC_CAP_4_BIT_DATA,
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 #endif
 	{}      /* Terminator */
@@ -400,9 +402,7 @@ static int igep_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
@@ -639,6 +639,9 @@ static void __init igep_init(void)
 
 	/* Get IGEP2 hardware revision */
 	igep2_get_revision();
+
+	omap_hsmmc_init(mmc);
+
 	/* Register I2C busses and drivers */
 	igep_i2c_init();
 	platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 2d2a61f..b5bc9b2 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -424,7 +424,7 @@ static void __init omap_ldp_init(void)
 	board_nand_init(ldp_nand_partitions,
 		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
 
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 	ldp_display_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 7ffcd28..e219b7d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -252,7 +252,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -275,9 +277,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
 	if (beagle_config.mmc1_gpio_wp != -EINVAL)
 		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
@@ -521,6 +521,7 @@ static void __init omap3_beagle_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3_beagle_init_rev();
+	omap_hsmmc_init(mmc);
 	omap3_beagle_i2c_init();
 
 	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c775bea..b736c4d 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -315,8 +315,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 63,
+		.deferred	= true,
 	},
 #ifdef CONFIG_WL12XX_PLATFORM_DATA
 	{
@@ -326,6 +327,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.gpio_cd	= -EINVAL,
 		.nonremovable	= true,
+		.deferred	= true,
 	},
 #endif
 	{}	/* Terminator */
@@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 {
 	int r, lcd_bl_en;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -644,6 +644,7 @@ static void __init omap3_evm_init(void)
 	omap_board_config = omap3_evm_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
+	omap_hsmmc_init(mmc);
 	omap3_evm_i2c_init();
 
 	omap_display_init(&omap3_evm_dss_data);
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 4198dd0..2304ba3 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -128,7 +128,7 @@ static void __init board_mmc_init(void)
 		return;
 	}
 
-	omap2_hsmmc_init(board_mmc_info);
+	omap_hsmmc_init(board_mmc_info);
 }
 
 static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 1644b73..d984048 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -270,17 +270,19 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 126,
 		.ext_clock	= 0,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
 		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
 		.gpio_wp	= 127,
 		.ext_clock	= 1,
 		.transceiver	= true,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 3,
@@ -288,6 +290,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
 		.init_card	= pandora_wl1251_init_card,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -297,10 +300,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
 {
 	int ret, gpio_32khz;
 
-	/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
-	omap3pandora_mmc[0].gpio_cd = gpio + 0;
-	omap3pandora_mmc[1].gpio_cd = gpio + 1;
-	omap2_hsmmc_init(omap3pandora_mmc);
+	omap_hsmmc_deferred_add(omap3pandora_mmc);
 
 	/* gpio + 13 drives 32kHz buffer for wifi module */
 	gpio_32khz = gpio + 13;
@@ -580,6 +580,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init omap3pandora_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_hsmmc_init(omap3pandora_mmc);
 	omap3pandora_i2c_init();
 	pandora_wl1251_init();
 	platform_add_devices(omap3pandora_devices,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index cb089a4..a2fb3e3 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -209,10 +209,11 @@ static struct regulator_init_data omap3stalker_vsim = {
 
 static struct omap2_hsmmc_info mmc[] = {
 	{
-	 .mmc		= 1,
-	 .caps		= MMC_CAP_4_BIT_DATA,
-	 .gpio_cd	= -EINVAL,
-	 .gpio_wp	= 23,
+		.mmc		= 1,
+		.caps		= MMC_CAP_4_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
+		.gpio_wp	= 23,
+		.deferred	= true,
 	 },
 	{}			/* Terminator */
 };
@@ -281,10 +282,8 @@ static int
 omap3stalker_twl_gpio_setup(struct device *dev,
 			    unsigned gpio, unsigned ngpio)
 {
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/*
 	 * Most GPIOs are for USB OTG.  Some are mostly sent to
@@ -425,6 +424,7 @@ static void __init omap3_stalker_init(void)
 	omap_board_config = omap3_stalker_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
+	omap_hsmmc_init(mmc);
 	omap3_stalker_i2c_init();
 
 	platform_add_devices(omap3_stalker_devices,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index a0b851a..b5ff46b 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -99,7 +99,9 @@ static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= 29,
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -123,9 +125,7 @@ static int touchbook_twl_gpio_setup(struct device *dev,
 	} else {
 		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
 	}
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	/* REVISIT: need ehci-omap hooks for external VBUS
 	 * power switch and overcurrent detect
@@ -351,6 +351,7 @@ static void __init omap3_touchbook_init(void)
 
 	pm_power_off = omap3_touchbook_poweroff;
 
+	omap_hsmmc_init(mmc);
 	omap3_touchbook_i2c_init();
 	platform_add_devices(omap3_touchbook_devices,
 			ARRAY_SIZE(omap3_touchbook_devices));
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 28fc271..bcc563c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -245,9 +245,9 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	struct omap2_hsmmc_info *c;
 
-	omap2_hsmmc_init(controllers);
+	omap_hsmmc_init(controllers);
 	for (c = controllers; c->mmc; c++)
-		omap4_twl6030_hsmmc_set_late_init(c->dev);
+		omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 52c0cef..8b6065b 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -301,6 +301,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.caps		= MMC_CAP_4_BIT_DATA,
 		.gpio_cd	= -EINVAL,
 		.gpio_wp	= -EINVAL,
+		.deferred	= true,
 	},
 	{
 		.mmc		= 2,
@@ -309,6 +310,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.transceiver	= true,
 		.ocr_mask	= 0x00100000,	/* 3.3V */
+		.deferred	= true,
 	},
 	{}	/* Terminator */
 };
@@ -407,7 +409,7 @@ static inline void __init overo_init_keys(void) { return; }
 static int overo_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
@@ -505,6 +507,7 @@ static void __init overo_init(void)
 	int ret;
 
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+	omap_hsmmc_init(mmc);
 	overo_i2c_init();
 	omap_display_init(&overo_dss_data);
 	omap_serial_init();
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 8678b38..2d24c98 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -120,7 +120,7 @@ static void __init rm680_peripherals_init(void)
 				ARRAY_SIZE(rm680_peripherals_devices));
 	rm680_i2c_init();
 	gpmc_onenand_init(board_onenand_data);
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_init(mmc);
 }
 
 #ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index acb4e77..0e9d89a 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -1145,7 +1145,7 @@ void __init rx51_peripherals_init(void)
 
 	partition = omap_mux_get("core");
 	if (partition)
-		omap2_hsmmc_init(mmc);
+		omap_hsmmc_init(mmc);
 
 	rx51_charger_init();
 }
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index c126461..f99284f 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -203,8 +203,10 @@ static struct omap2_hsmmc_info mmc[] = {
 		.name		= "external",
 		.mmc		= 1,
 		.caps		= MMC_CAP_4_BIT_DATA,
+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
 		.gpio_wp	= -EINVAL,
 		.power_saving	= true,
+		.deferred	= true,
 	},
 	{
 		.name		= "internal",
@@ -214,6 +216,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.nonremovable	= true,
 		.power_saving	= true,
+		.deferred	= true,
 	},
 	{
 		.name		= "wl1271",
@@ -222,6 +225,7 @@ static struct omap2_hsmmc_info mmc[] = {
 		.gpio_wp	= -EINVAL,
 		.gpio_cd	= -EINVAL,
 		.nonremovable	= true,
+		.deferred	= true,
 	},
 	{}      /* Terminator */
 };
@@ -231,9 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
 {
 	int ret;
 
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
+	omap_hsmmc_deferred_add(mmc);
 
 	ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
 			       "lcd enable");
@@ -301,6 +303,7 @@ void __init zoom_peripherals_init(void)
 	if (ret)
 		pr_err("error setting wl12xx data: %d\n", ret);
 
+	omap_hsmmc_init(mmc);
 	omap_i2c_init();
 	platform_device_register(&omap_vwlan_device);
 	usb_musb_init(NULL);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b40c288..51e3a2d 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -430,64 +430,118 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 
 #define MAX_OMAP_MMC_HWMOD_NAME_LEN		16
 
-void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+static void omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
+						int ctrl_nr, int deferred)
 {
 	struct omap_hwmod *oh;
+	struct omap_hwmod *ohs[1];
+	struct omap_device *od;
 	struct platform_device *pdev;
 	char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
 	struct omap_mmc_platform_data *mmc_data;
 	struct omap_mmc_dev_attr *mmc_dev_attr;
 	char *name;
-	int l;
+	int res;
 
-	mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
-	if (!mmc_data) {
-		pr_err("Cannot allocate memory for mmc device!\n");
-		goto done;
-	}
+	if (!hsmmcinfo->mmc_data) {
+		mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
+		if (!mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			return;
+		}
 
-	if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
-		pr_err("%s fails!\n", __func__);
-		goto done;
+		res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
+		if (res < 0)
+			goto free_mmc;
+
+		omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+		hsmmcinfo->mmc_data = kmemdup(mmc_data, sizeof(*mmc_data),
+								 GFP_KERNEL);
+		if (!hsmmcinfo->mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			goto free_mmc;
+		}
+	} else	{
+		mmc_data = kmemdup(hsmmcinfo->mmc_data, sizeof(*mmc_data),
+								 GFP_KERNEL);
+		if (!mmc_data) {
+			pr_err("Cannot allocate memory for mmc device!\n");
+			return;
+		}
 	}
-	omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
 
-	name = "omap_hsmmc";
+	if (deferred)
+		goto free_mmc;
 
-	l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
+	name = "omap_hsmmc";
+	res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
 		     "mmc%d", ctrl_nr);
-	WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
+	WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
 	     "String buffer overflow in MMC%d device setup\n", ctrl_nr);
+
 	oh = omap_hwmod_lookup(oh_name);
 	if (!oh) {
 		pr_err("Could not look up %s\n", oh_name);
-		kfree(mmc_data->slots[0].name);
-		goto done;
+		goto free_name;
 	}
-
+	ohs[0] = oh;
 	if (oh->dev_attr != NULL) {
 		mmc_dev_attr = oh->dev_attr;
 		mmc_data->controller_flags = mmc_dev_attr->flags;
 	}
 
-	pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
-		sizeof(struct omap_mmc_platform_data), NULL, 0, false);
-	if (IS_ERR(pdev)) {
-		WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
-		kfree(mmc_data->slots[0].name);
-		goto done;
+	pdev = platform_device_alloc(name, ctrl_nr - 1);
+	if (!pdev) {
+		pr_err("Could not allocate pdev for %s\n", name);
+		goto free_name;
+	}
+	dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+
+	od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
+	if (!od) {
+		pr_err("Could not allocate od for %s\n", name);
+		goto put_pdev;
 	}
-	/*
-	 * return device handle to board setup code
-	 * required to populate for regulator framework structure
-	 */
-	hsmmcinfo->dev = &pdev->dev;
 
-done:
+	res = platform_device_add_data(pdev, mmc_data, sizeof(*mmc_data));
+	if (res) {
+		pr_err("Could not add pdata for %s\n", name);
+		goto put_pdev;
+	}
+
+	hsmmcinfo->pdev = pdev;
+
+	res = omap_device_register(pdev);
+	if (res) {
+		pr_err("Could not register od for %s\n", name);
+		goto free_od;
+	}
+
+	goto free_mmc;
+
+free_od:
+	omap_device_delete(od);
+
+put_pdev:
+	platform_device_put(pdev);
+
+free_name:
+	kfree(mmc_data->slots[0].name);
+
+free_mmc:
 	kfree(mmc_data);
 }
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
+{
+	for (; controllers->mmc; controllers++) {
+		if (!controllers->deferred)
+			continue;
+		omap_hsmmc_init_one(controllers, controllers->mmc, 0);
+	}
+}
+
+void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
 
@@ -515,7 +569,8 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 	}
 
 	for (; controllers->mmc; controllers++)
-		omap_init_hsmmc(controllers, controllers->mmc);
+		omap_hsmmc_init_one(controllers, controllers->mmc,
+						 controllers->deferred);
 
 }
 
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index c440973..75d57fb 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -21,24 +21,31 @@ struct omap2_hsmmc_info {
 	bool	no_off;		/* power_saving and power is not to go off */
 	bool	no_off_init;	/* no power off when not in MMC sleep state */
 	bool	vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+	bool	deferred;	/* mmc needs a deferred probe */
 	int	gpio_cd;	/* or -EINVAL */
 	int	gpio_wp;	/* or -EINVAL */
 	char	*name;		/* or NULL for default */
-	struct device *dev;	/* returned: pointer to mmc adapter */
+	struct platform_device *pdev;	/* mmc controller instance */
 	int	ocr_mask;	/* temporary HACK */
 	/* Remux (pad configuration) when powering on/off */
 	void (*remux)(struct device *dev, int slot, int power_on);
 	/* init some special card */
 	void (*init_card)(struct mmc_card *card);
+	struct omap_mmc_platform_data *mmc_data;
 };
 
 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-void omap2_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_init(struct omap2_hsmmc_info *);
+void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *);
 
 #else
 
-static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
+static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+static inline void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *info)
 {
 }
 
-- 
1.7.1

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

* [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Rajendra Nayak

All OMAP3 boards which register a .setup function with twl4030
gpio driver do not seem to have a .teardown hook implemented.
.setup mainly requests a few gpios and also in most cases
does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
and of the requested gpios and also do a omap_hsmmc_deferred_del().
This helps in case the twl4030 gpio driver is built as a module and
added and removed multiple times. Without the .teardown a multiple
insmod/rmmod can result in gpio request failues and also WARN messages
stating addition of already registered mmc devices.

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
 arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
 arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
 arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
 arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
 arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
 arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
 arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
 arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
 arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
 arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
 arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
 arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
 arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
 arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
 15 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index f93bb84..c1ddbb7 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -259,6 +259,15 @@ static int sdp3430_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int sdp3430_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 15);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -266,6 +275,7 @@ static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(8) | BIT(13)
 				| BIT(16) | BIT(17),
 	.setup		= sdp3430_twl_gpio_setup,
+	.teardown	= sdp3430_twl_gpio_teardown,
 };
 
 /* regulator consumer mappings */
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 14df109..55e0180 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
 	return 0;
 }
 
+static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
+				 unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 2);
+	return 0;
+}
 static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup          = cm_t35_twl_gpio_setup,
+	.teardown	= cm_t35_twl_gpio_teardown,
 };
 
 static struct twl4030_platform_data cm_t35_twldata = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 6b99a5e..2903dd1 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -254,6 +254,15 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int devkit8000_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX + 0);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -262,6 +271,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 	.pulldowns	= BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= devkit8000_twl_gpio_setup,
+	.teardown	= devkit8000_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 11a6aa4..1d0850f 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
 	return 0;
 };
 
+static int igep_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
+	if (machine_is_igep0030())
+		return 0;
+
+	gpio_free(gpio + 1);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= igep_twl_gpio_setup,
+	.teardown	= igep_twl_gpio_teardown,
 };
 
 static int igep2_enable_dvi(struct omap_dss_device *dssdev)
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index b5bc9b2..279ef18 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -274,11 +274,20 @@ static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
 	return 0;
 }
 
+static int ldp_twl_gpio_teardown(struct device *dev, unsigned gpio,
+							 unsigned ngpio)
+{
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 15);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data ldp_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= ldp_twl_gpio_setup,
+	.teardown	= ldp_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e219b7d..08749a5 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -321,6 +321,17 @@ static int beagle_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int beagle_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 1);
+	if (cpu_is_omap3630())
+		gpio_free(gpio + 2);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data beagle_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -330,6 +341,7 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= beagle_twl_gpio_setup,
+	.teardown	= beagle_twl_gpio_teardown,
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b736c4d..2fa7d06 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -388,12 +388,22 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int omap3evm_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= omap3evm_twl_gpio_setup,
+	.teardown	= omap3evm_twl_gpio_teardown,
 };
 
 static uint32_t board_keymap[] = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index d984048..828e58c 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -313,11 +313,20 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int omap3pandora_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(omap3pandora_mmc);
+	gpio_free(gpio + 13);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= omap3pandora_twl_gpio_setup,
+	.teardown	= omap3pandora_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply pandora_vmmc1_supply[] = {
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a2fb3e3..c6bab9a 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -306,12 +306,23 @@ omap3stalker_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int
+omap3stalker_twl_gpio_teardown(struct device *dev,
+			    unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3stalker_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= omap3stalker_twl_gpio_setup,
+	.teardown	= omap3stalker_twl_gpio_teardown,
 };
 
 static uint32_t board_keymap[] = {
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index b5ff46b..02c0a78 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -142,6 +142,15 @@ static int touchbook_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int touchbook_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 1);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -151,6 +160,7 @@ static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= touchbook_twl_gpio_setup,
+	.teardown	= touchbook_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply touchbook_vdac_supply[] = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 8b6065b..e1f496d 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int overo_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data overo_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= overo_twl_gpio_setup,
+	.teardown	= overo_twl_gpio_teardown,
 };
 
 static struct regulator_init_data overo_vmmc1 = {
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 0e9d89a..8aefbc0 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -702,6 +702,13 @@ static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
 	return 0;
 }
 
+static int rx51_twlgpio_teardown(struct device *dev, unsigned gpio, unsigned n)
+{
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data rx51_gpio_data = {
 	.gpio_base		= OMAP_MAX_GPIO_LINES,
 	.irq_base		= TWL4030_GPIO_IRQ_BASE,
@@ -712,6 +719,7 @@ static struct twl4030_gpio_platform_data rx51_gpio_data = {
 				| BIT(12) | BIT(13) | BIT(14) | BIT(15)
 				| BIT(16) | BIT(17) ,
 	.setup			= rx51_twlgpio_setup,
+	.teardown		= rx51_twlgpio_teardown,
 };
 
 static struct twl4030_ins sleep_on_seq[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index f99284f..bd1c487 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -246,6 +246,14 @@ static int zoom_twl_gpio_setup(struct device *dev,
 	return ret;
 }
 
+static int zoom_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(LCD_PANEL_ENABLE_GPIO);
+	return 0;
+}
+
 /* EXTMUTE callback function */
 static void zoom2_set_hs_extmute(int mute)
 {
@@ -257,6 +265,7 @@ static struct twl4030_gpio_platform_data zoom_gpio_data = {
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= zoom_twl_gpio_setup,
+	.teardown	= zoom_twl_gpio_teardown,
 };
 
 static struct twl4030_platform_data zoom_twldata = {
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 51e3a2d..0f256ca 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
 	}
 }
 
+void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
+{
+	struct platform_device *pdev;
+	for (; controllers->mmc; controllers++) {
+		if (!controllers->deferred)
+			continue;
+		pdev = controllers->pdev;
+		omap_device_unregister(pdev);
+	}
+}
+
 void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 75d57fb..2c1c580 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -38,6 +38,7 @@ struct omap2_hsmmc_info {
 
 void omap_hsmmc_init(struct omap2_hsmmc_info *);
 void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *);
+void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *);
 
 #else
 
@@ -49,4 +50,7 @@ static inline void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *info)
 {
 }
 
+static inline void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *info)
+{
+}
 #endif
-- 
1.7.1


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

* [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

All OMAP3 boards which register a .setup function with twl4030
gpio driver do not seem to have a .teardown hook implemented.
.setup mainly requests a few gpios and also in most cases
does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
and of the requested gpios and also do a omap_hsmmc_deferred_del().
This helps in case the twl4030 gpio driver is built as a module and
added and removed multiple times. Without the .teardown a multiple
insmod/rmmod can result in gpio request failues and also WARN messages
stating addition of already registered mmc devices.

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
 arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
 arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
 arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
 arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
 arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
 arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
 arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
 arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
 arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
 arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
 arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
 arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
 arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
 arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
 15 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index f93bb84..c1ddbb7 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -259,6 +259,15 @@ static int sdp3430_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int sdp3430_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 15);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -266,6 +275,7 @@ static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(8) | BIT(13)
 				| BIT(16) | BIT(17),
 	.setup		= sdp3430_twl_gpio_setup,
+	.teardown	= sdp3430_twl_gpio_teardown,
 };
 
 /* regulator consumer mappings */
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 14df109..55e0180 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
 	return 0;
 }
 
+static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
+				 unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 2);
+	return 0;
+}
 static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup          = cm_t35_twl_gpio_setup,
+	.teardown	= cm_t35_twl_gpio_teardown,
 };
 
 static struct twl4030_platform_data cm_t35_twldata = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 6b99a5e..2903dd1 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -254,6 +254,15 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int devkit8000_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX + 0);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -262,6 +271,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 	.pulldowns	= BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= devkit8000_twl_gpio_setup,
+	.teardown	= devkit8000_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 11a6aa4..1d0850f 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
 	return 0;
 };
 
+static int igep_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
+	if (machine_is_igep0030())
+		return 0;
+
+	gpio_free(gpio + 1);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= igep_twl_gpio_setup,
+	.teardown	= igep_twl_gpio_teardown,
 };
 
 static int igep2_enable_dvi(struct omap_dss_device *dssdev)
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index b5bc9b2..279ef18 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -274,11 +274,20 @@ static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
 	return 0;
 }
 
+static int ldp_twl_gpio_teardown(struct device *dev, unsigned gpio,
+							 unsigned ngpio)
+{
+	gpio_free(gpio + 7);
+	gpio_free(gpio + 15);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data ldp_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= ldp_twl_gpio_setup,
+	.teardown	= ldp_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e219b7d..08749a5 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -321,6 +321,17 @@ static int beagle_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int beagle_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 1);
+	if (cpu_is_omap3630())
+		gpio_free(gpio + 2);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data beagle_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -330,6 +341,7 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= beagle_twl_gpio_setup,
+	.teardown	= beagle_twl_gpio_teardown,
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b736c4d..2fa7d06 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -388,12 +388,22 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int omap3evm_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= omap3evm_twl_gpio_setup,
+	.teardown	= omap3evm_twl_gpio_teardown,
 };
 
 static uint32_t board_keymap[] = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index d984048..828e58c 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -313,11 +313,20 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int omap3pandora_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(omap3pandora_mmc);
+	gpio_free(gpio + 13);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= omap3pandora_twl_gpio_setup,
+	.teardown	= omap3pandora_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply pandora_vmmc1_supply[] = {
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a2fb3e3..c6bab9a 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -306,12 +306,23 @@ omap3stalker_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int
+omap3stalker_twl_gpio_teardown(struct device *dev,
+			    unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3stalker_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= omap3stalker_twl_gpio_setup,
+	.teardown	= omap3stalker_twl_gpio_teardown,
 };
 
 static uint32_t board_keymap[] = {
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index b5ff46b..02c0a78 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -142,6 +142,15 @@ static int touchbook_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int touchbook_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(gpio + 1);
+	gpio_free(gpio + TWL4030_GPIO_MAX);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -151,6 +160,7 @@ static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 	.pulldowns	= BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
 				| BIT(15) | BIT(16) | BIT(17),
 	.setup		= touchbook_twl_gpio_setup,
+	.teardown	= touchbook_twl_gpio_teardown,
 };
 
 static struct regulator_consumer_supply touchbook_vdac_supply[] = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 8b6065b..e1f496d 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
 	return 0;
 }
 
+static int overo_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data overo_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
 	.setup		= overo_twl_gpio_setup,
+	.teardown	= overo_twl_gpio_teardown,
 };
 
 static struct regulator_init_data overo_vmmc1 = {
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 0e9d89a..8aefbc0 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -702,6 +702,13 @@ static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
 	return 0;
 }
 
+static int rx51_twlgpio_teardown(struct device *dev, unsigned gpio, unsigned n)
+{
+	gpio_free(gpio + 6);
+	gpio_free(gpio + 7);
+	return 0;
+}
+
 static struct twl4030_gpio_platform_data rx51_gpio_data = {
 	.gpio_base		= OMAP_MAX_GPIO_LINES,
 	.irq_base		= TWL4030_GPIO_IRQ_BASE,
@@ -712,6 +719,7 @@ static struct twl4030_gpio_platform_data rx51_gpio_data = {
 				| BIT(12) | BIT(13) | BIT(14) | BIT(15)
 				| BIT(16) | BIT(17) ,
 	.setup			= rx51_twlgpio_setup,
+	.teardown		= rx51_twlgpio_teardown,
 };
 
 static struct twl4030_ins sleep_on_seq[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index f99284f..bd1c487 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -246,6 +246,14 @@ static int zoom_twl_gpio_setup(struct device *dev,
 	return ret;
 }
 
+static int zoom_twl_gpio_teardown(struct device *dev,
+		unsigned gpio, unsigned ngpio)
+{
+	omap_hsmmc_deferred_del(mmc);
+	gpio_free(LCD_PANEL_ENABLE_GPIO);
+	return 0;
+}
+
 /* EXTMUTE callback function */
 static void zoom2_set_hs_extmute(int mute)
 {
@@ -257,6 +265,7 @@ static struct twl4030_gpio_platform_data zoom_gpio_data = {
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.setup		= zoom_twl_gpio_setup,
+	.teardown	= zoom_twl_gpio_teardown,
 };
 
 static struct twl4030_platform_data zoom_twldata = {
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 51e3a2d..0f256ca 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
 	}
 }
 
+void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
+{
+	struct platform_device *pdev;
+	for (; controllers->mmc; controllers++) {
+		if (!controllers->deferred)
+			continue;
+		pdev = controllers->pdev;
+		omap_device_unregister(pdev);
+	}
+}
+
 void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 75d57fb..2c1c580 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -38,6 +38,7 @@ struct omap2_hsmmc_info {
 
 void omap_hsmmc_init(struct omap2_hsmmc_info *);
 void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *);
+void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *);
 
 #else
 
@@ -49,4 +50,7 @@ static inline void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *info)
 {
 }
 
+static inline void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *info)
+{
+}
 #endif
-- 
1.7.1

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 11:40   ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: tony; +Cc: linux-omap, linux-arm-kernel, Russell King, Rajendra Nayak

From: Tony Lindgren <tony@atomide.com>

Now that omap hsmmc init is split into two functions, it's safe
to mark omap_hsmmc_init and omap_mux related functions to __init.

This basically reverts the following fixes for the case where
TWL was compiled as a module:

a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)

Additionally it fixes up the remaining section warnings for
all callers of omap_mux functions.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-flash.c          |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    6 ++++--
 arch/arm/mach-omap2/board-omap3evm.c       |    3 ++-
 arch/arm/mach-omap2/board-omap3stalker.c   |    3 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |   13 +++++++------
 arch/arm/mach-omap2/board-omap4panda.c     |    2 +-
 arch/arm/mach-omap2/display.c              |    8 ++++----
 arch/arm/mach-omap2/hsmmc.c                |    4 ++--
 arch/arm/mach-omap2/mux.c                  |   14 +++++++-------
 9 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 30a6f52..0349fd2 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -189,7 +189,7 @@ unmap:
  *
  * @return - void.
  */
-void board_flash_init(struct flash_partitions partition_info[],
+void __init board_flash_init(struct flash_partitions partition_info[],
 			char chip_sel_board[][GPMC_CS_NUM], int nand_type)
 {
 	u8		cs = 0;
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 08749a5..916167e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -274,8 +274,6 @@ static int beagle_twl_gpio_setup(struct device *dev,
 {
 	int r;
 
-	if (beagle_config.mmc1_gpio_wp != -EINVAL)
-		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
 	omap_hsmmc_deferred_add(mmc);
 
@@ -533,7 +531,11 @@ static void __init omap3_beagle_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3_beagle_init_rev();
+
+	if (beagle_config.mmc1_gpio_wp != -EINVAL)
+		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_beagle_i2c_init();
 
 	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 2fa7d06..47336c2 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -362,7 +362,6 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 {
 	int r, lcd_bl_en;
 
-	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	omap_hsmmc_deferred_add(mmc);
 
 	/*
@@ -654,7 +653,9 @@ static void __init omap3_evm_init(void)
 	omap_board_config = omap3_evm_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
+	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_evm_i2c_init();
 
 	omap_display_init(&omap3_evm_dss_data);
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c6bab9a..b11700d 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -282,7 +282,6 @@ static int
 omap3stalker_twl_gpio_setup(struct device *dev,
 			    unsigned gpio, unsigned ngpio)
 {
-	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
 	omap_hsmmc_deferred_add(mmc);
 
 	/*
@@ -435,7 +434,9 @@ static void __init omap3_stalker_init(void)
 	omap_board_config = omap3_stalker_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
+	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_stalker_i2c_init();
 
 	platform_add_devices(omap3_stalker_devices,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 02c0a78..a66e592 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -119,12 +119,6 @@ static struct gpio_led gpio_leds[];
 static int touchbook_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
-		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
-		mmc[0].gpio_wp = 23;
-	} else {
-		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
-	}
 	omap_hsmmc_deferred_add(mmc);
 
 	/* REVISIT: need ehci-omap hooks for external VBUS
@@ -361,7 +355,14 @@ static void __init omap3_touchbook_init(void)
 
 	pm_power_off = omap3_touchbook_poweroff;
 
+	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+		mmc[0].gpio_wp = 23;
+	} else {
+		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+	}
 	omap_hsmmc_init(mmc);
+
 	omap3_touchbook_i2c_init();
 	platform_add_devices(omap3_touchbook_devices,
 			ARRAY_SIZE(omap3_touchbook_devices));
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index bcc563c..7ca7a5c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -461,7 +461,7 @@ static struct omap_dss_board_info omap4_panda_dss_data = {
 	.default_device	= &omap4_panda_dvi_device,
 };
 
-void omap4_panda_display_init(void)
+void __init omap4_panda_display_init(void)
 {
 	int r;
 
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 3677b1f..62e133c 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -124,7 +124,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 	}
 }
 
-static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -157,7 +157,7 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 	return 0;
 }
 
-int omap_hdmi_init(enum omap_hdmi_flags flags)
+int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 {
 	if (cpu_is_omap44xx())
 		omap4_hdmi_mux_pads(flags);
@@ -165,7 +165,7 @@ int omap_hdmi_init(enum omap_hdmi_flags flags)
 	return 0;
 }
 
-static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -173,7 +173,7 @@ static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 	return 0;
 }
 
-static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+static void __init omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 0f256ca..b30dbb8 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -293,7 +293,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
 	}
 }
 
-static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 				 struct omap_mmc_platform_data *mmc)
 {
 	char *hc_name;
@@ -552,7 +552,7 @@ void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
 	}
 }
 
-void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
 
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index fb8bc9f..f26b2fa 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -100,8 +100,8 @@ void omap_mux_write_array(struct omap_mux_partition *partition,
 
 static char *omap_mux_options;
 
-static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
-			       int gpio, int val)
+static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
+				      int gpio, int val)
 {
 	struct omap_mux_entry *e;
 	struct omap_mux *gpio_mux = NULL;
@@ -145,7 +145,7 @@ static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
 	return 0;
 }
 
-int omap_mux_init_gpio(int gpio, int val)
+int __init omap_mux_init_gpio(int gpio, int val)
 {
 	struct omap_mux_partition *partition;
 	int ret;
@@ -159,9 +159,9 @@ int omap_mux_init_gpio(int gpio, int val)
 	return -ENODEV;
 }
 
-static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
-				 const char *muxname,
-				 struct omap_mux **found_mux)
+static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
+					const char *muxname,
+					struct omap_mux **found_mux)
 {
 	struct omap_mux *mux = NULL;
 	struct omap_mux_entry *e;
@@ -240,7 +240,7 @@ omap_mux_get_by_name(const char *muxname,
 	return -ENODEV;
 }
 
-int omap_mux_init_signal(const char *muxname, int val)
+int __init omap_mux_init_signal(const char *muxname, int val)
 {
 	struct omap_mux_partition *partition = NULL;
 	struct omap_mux *mux = NULL;
-- 
1.7.1


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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-02-23 11:40   ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-23 11:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tony Lindgren <tony@atomide.com>

Now that omap hsmmc init is split into two functions, it's safe
to mark omap_hsmmc_init and omap_mux related functions to __init.

This basically reverts the following fixes for the case where
TWL was compiled as a module:

a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)

Additionally it fixes up the remaining section warnings for
all callers of omap_mux functions.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-flash.c          |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c    |    6 ++++--
 arch/arm/mach-omap2/board-omap3evm.c       |    3 ++-
 arch/arm/mach-omap2/board-omap3stalker.c   |    3 ++-
 arch/arm/mach-omap2/board-omap3touchbook.c |   13 +++++++------
 arch/arm/mach-omap2/board-omap4panda.c     |    2 +-
 arch/arm/mach-omap2/display.c              |    8 ++++----
 arch/arm/mach-omap2/hsmmc.c                |    4 ++--
 arch/arm/mach-omap2/mux.c                  |   14 +++++++-------
 9 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 30a6f52..0349fd2 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -189,7 +189,7 @@ unmap:
  *
  * @return - void.
  */
-void board_flash_init(struct flash_partitions partition_info[],
+void __init board_flash_init(struct flash_partitions partition_info[],
 			char chip_sel_board[][GPMC_CS_NUM], int nand_type)
 {
 	u8		cs = 0;
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 08749a5..916167e 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -274,8 +274,6 @@ static int beagle_twl_gpio_setup(struct device *dev,
 {
 	int r;
 
-	if (beagle_config.mmc1_gpio_wp != -EINVAL)
-		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
 	omap_hsmmc_deferred_add(mmc);
 
@@ -533,7 +531,11 @@ static void __init omap3_beagle_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap3_beagle_init_rev();
+
+	if (beagle_config.mmc1_gpio_wp != -EINVAL)
+		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_beagle_i2c_init();
 
 	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 2fa7d06..47336c2 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -362,7 +362,6 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
 {
 	int r, lcd_bl_en;
 
-	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	omap_hsmmc_deferred_add(mmc);
 
 	/*
@@ -654,7 +653,9 @@ static void __init omap3_evm_init(void)
 	omap_board_config = omap3_evm_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
+	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_evm_i2c_init();
 
 	omap_display_init(&omap3_evm_dss_data);
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c6bab9a..b11700d 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -282,7 +282,6 @@ static int
 omap3stalker_twl_gpio_setup(struct device *dev,
 			    unsigned gpio, unsigned ngpio)
 {
-	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
 	omap_hsmmc_deferred_add(mmc);
 
 	/*
@@ -435,7 +434,9 @@ static void __init omap3_stalker_init(void)
 	omap_board_config = omap3_stalker_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
 
+	omap_mux_init_gpio(23, OMAP_PIN_INPUT);
 	omap_hsmmc_init(mmc);
+
 	omap3_stalker_i2c_init();
 
 	platform_add_devices(omap3_stalker_devices,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 02c0a78..a66e592 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -119,12 +119,6 @@ static struct gpio_led gpio_leds[];
 static int touchbook_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
-		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
-		mmc[0].gpio_wp = 23;
-	} else {
-		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
-	}
 	omap_hsmmc_deferred_add(mmc);
 
 	/* REVISIT: need ehci-omap hooks for external VBUS
@@ -361,7 +355,14 @@ static void __init omap3_touchbook_init(void)
 
 	pm_power_off = omap3_touchbook_poweroff;
 
+	if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+		omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+		mmc[0].gpio_wp = 23;
+	} else {
+		omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+	}
 	omap_hsmmc_init(mmc);
+
 	omap3_touchbook_i2c_init();
 	platform_add_devices(omap3_touchbook_devices,
 			ARRAY_SIZE(omap3_touchbook_devices));
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index bcc563c..7ca7a5c 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -461,7 +461,7 @@ static struct omap_dss_board_info omap4_panda_dss_data = {
 	.default_device	= &omap4_panda_dvi_device,
 };
 
-void omap4_panda_display_init(void)
+void __init omap4_panda_display_init(void)
 {
 	int r;
 
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 3677b1f..62e133c 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -124,7 +124,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 	}
 }
 
-static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -157,7 +157,7 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 	return 0;
 }
 
-int omap_hdmi_init(enum omap_hdmi_flags flags)
+int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 {
 	if (cpu_is_omap44xx())
 		omap4_hdmi_mux_pads(flags);
@@ -165,7 +165,7 @@ int omap_hdmi_init(enum omap_hdmi_flags flags)
 	return 0;
 }
 
-static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -173,7 +173,7 @@ static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 	return 0;
 }
 
-static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+static void __init omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 0f256ca..b30dbb8 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -293,7 +293,7 @@ static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
 	}
 }
 
-static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 				 struct omap_mmc_platform_data *mmc)
 {
 	char *hc_name;
@@ -552,7 +552,7 @@ void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
 	}
 }
 
-void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
+void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
 	u32 reg;
 
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index fb8bc9f..f26b2fa 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -100,8 +100,8 @@ void omap_mux_write_array(struct omap_mux_partition *partition,
 
 static char *omap_mux_options;
 
-static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
-			       int gpio, int val)
+static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
+				      int gpio, int val)
 {
 	struct omap_mux_entry *e;
 	struct omap_mux *gpio_mux = NULL;
@@ -145,7 +145,7 @@ static int _omap_mux_init_gpio(struct omap_mux_partition *partition,
 	return 0;
 }
 
-int omap_mux_init_gpio(int gpio, int val)
+int __init omap_mux_init_gpio(int gpio, int val)
 {
 	struct omap_mux_partition *partition;
 	int ret;
@@ -159,9 +159,9 @@ int omap_mux_init_gpio(int gpio, int val)
 	return -ENODEV;
 }
 
-static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
-				 const char *muxname,
-				 struct omap_mux **found_mux)
+static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
+					const char *muxname,
+					struct omap_mux **found_mux)
 {
 	struct omap_mux *mux = NULL;
 	struct omap_mux_entry *e;
@@ -240,7 +240,7 @@ omap_mux_get_by_name(const char *muxname,
 	return -ENODEV;
 }
 
-int omap_mux_init_signal(const char *muxname, int val)
+int __init omap_mux_init_signal(const char *muxname, int val)
 {
 	struct omap_mux_partition *partition = NULL;
 	struct omap_mux *mux = NULL;
-- 
1.7.1

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-23 11:40   ` Rajendra Nayak
@ 2012-02-23 14:28     ` Igor Grinberg
  -1 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-23 14:28 UTC (permalink / raw)
  To: Rajendra Nayak
  Cc: tony, linux-omap, linux-arm-kernel, Steve Sakoman, Steve Sakoman

Hi Tony, Rajendra,

On 02/23/12 13:40, Rajendra Nayak wrote:
> From: Tony Lindgren <tony@atomide.com>
> 
> Otherwise omap_device_build() and omap_mux related functions
> can't be marked as __init when twl is build as a module.
> 
> If a board is using GPIO pins or regulators configured by an
> external chip, such as TWL PMIC on I2C bus, the board must
> mark those MMC controllers as deferred. Additionally both
> omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
> by the board.
> 
> For MMC controllers using internal GPIO pins for card
> detect and regulators the slots don't need to be marked
> deferred. In this case calling omap_hsmmc_init() is sufficient.
> 
> Note that this patch does not change the behaviour for
> board-4430sdp.c board-omap4panda.c. These boards wrongly
> rely on the omap_hsmmc.c init function callback to configure
> the PMIC GPIO interrupt lines on external chip. If the PMIC
> interrupt lines are not configured during init, they will
> fail.
> 
> Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
>  arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
>  arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
>  arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
>  arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
>  arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
>  arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
>  arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
>  arch/arm/mach-omap2/board-ldp.c              |    2 +-
>  arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
>  arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
>  arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
>  arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
>  arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
>  arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
>  arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
>  arch/arm/mach-omap2/board-overo.c            |    5 +-
>  arch/arm/mach-omap2/board-rm680.c            |    2 +-
>  arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
>  arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
>  arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
>  arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
>  21 files changed, 165 insertions(+), 89 deletions(-)

[...]

> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index d73316e..14df109 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
> -
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> +		.deferred	= true,

Why do you defer this one?
It does not use external GPIO chip, in fact it does not use CD/WP at all.

>  	},
>  	{}	/* Terminator */
>  };
> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>  		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>  	}
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	return 0;
>  }
> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>  	omap_serial_init();
>  	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>  			     mt46h32m32lf6_sdrc_params);
> +	omap_hsmmc_init(mmc);
>  	cm_t35_init_i2c();
>  	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>  	cm_t35_init_ethernet();

Other then the comment above, looks fine.
I will probably be able to test this on Sunday.

[...]

> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index a59ace0..11a6aa4 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,
>  	},
>  #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>  	{
> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.caps		= MMC_CAP_4_BIT_DATA,
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,

same here, why defer it?

>  	},
>  #endif
>  	{}      /* Terminator */
> @@ -400,9 +402,7 @@ static int igep_twl_gpio_setup(struct device *dev,
>  {
>  	int ret;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
>  #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
> @@ -639,6 +639,9 @@ static void __init igep_init(void)
>  
>  	/* Get IGEP2 hardware revision */
>  	igep2_get_revision();
> +
> +	omap_hsmmc_init(mmc);
> +
>  	/* Register I2C busses and drivers */
>  	igep_i2c_init();
>  	platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));

[...]

> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index c775bea..b736c4d 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -315,8 +315,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= 63,
> +		.deferred	= true,
>  	},
>  #ifdef CONFIG_WL12XX_PLATFORM_DATA
>  	{
> @@ -326,6 +327,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.gpio_cd	= -EINVAL,
>  		.nonremovable	= true,
> +		.deferred	= true,

ditto

>  	},
>  #endif
>  	{}	/* Terminator */
> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>  {
>  	int r, lcd_bl_en;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>  	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	/*
>  	 * Most GPIOs are for USB OTG.  Some are mostly sent to
> @@ -644,6 +644,7 @@ static void __init omap3_evm_init(void)
>  	omap_board_config = omap3_evm_config;
>  	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
>  
> +	omap_hsmmc_init(mmc);
>  	omap3_evm_i2c_init();
>  
>  	omap_display_init(&omap3_evm_dss_data);

[...]

> diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
> index 1644b73..d984048 100644
> --- a/arch/arm/mach-omap2/board-omap3pandora.c
> +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> @@ -270,17 +270,19 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= 126,
>  		.ext_clock	= 0,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
>  		.gpio_wp	= 127,
>  		.ext_clock	= 1,
>  		.transceiver	= true,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 3,
> @@ -288,6 +290,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
>  		.init_card	= pandora_wl1251_init_card,
> +		.deferred	= true,

ditto

>  	},
>  	{}	/* Terminator */
>  };
> @@ -297,10 +300,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
>  {
>  	int ret, gpio_32khz;
>  
> -	/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
> -	omap3pandora_mmc[0].gpio_cd = gpio + 0;
> -	omap3pandora_mmc[1].gpio_cd = gpio + 1;
> -	omap2_hsmmc_init(omap3pandora_mmc);
> +	omap_hsmmc_deferred_add(omap3pandora_mmc);
>  
>  	/* gpio + 13 drives 32kHz buffer for wifi module */
>  	gpio_32khz = gpio + 13;
> @@ -580,6 +580,7 @@ static struct omap_board_mux board_mux[] __initdata = {
>  static void __init omap3pandora_init(void)
>  {
>  	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> +	omap_hsmmc_init(omap3pandora_mmc);
>  	omap3pandora_i2c_init();
>  	pandora_wl1251_init();
>  	platform_add_devices(omap3pandora_devices,

[...]

> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 52c0cef..8b6065b 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -301,6 +301,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.caps		= MMC_CAP_4_BIT_DATA,
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
> @@ -309,6 +310,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.transceiver	= true,
>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> +		.deferred	= true,
>  	},
>  	{}	/* Terminator */
>  };
> @@ -407,7 +409,7 @@ static inline void __init overo_init_keys(void) { return; }
>  static int overo_twl_gpio_setup(struct device *dev,
>  		unsigned gpio, unsigned ngpio)
>  {
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);

This board does not look like using external chip for MMC GPIOs,
if that is true, then the above can be just removed.

Added Steve to Cc.

>  
>  #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
>  	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
> @@ -505,6 +507,7 @@ static void __init overo_init(void)
>  	int ret;
>  
>  	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> +	omap_hsmmc_init(mmc);
>  	overo_i2c_init();
>  	omap_display_init(&overo_dss_data);
>  	omap_serial_init();

[...]

> diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
> index c126461..f99284f 100644
> --- a/arch/arm/mach-omap2/board-zoom-peripherals.c
> +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
> @@ -203,8 +203,10 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.name		= "external",
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
>  		.power_saving	= true,
> +		.deferred	= true,
>  	},
>  	{
>  		.name		= "internal",
> @@ -214,6 +216,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.nonremovable	= true,
>  		.power_saving	= true,
> +		.deferred	= true,

ditto, why defer?

>  	},
>  	{
>  		.name		= "wl1271",
> @@ -222,6 +225,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.gpio_cd	= -EINVAL,
>  		.nonremovable	= true,
> +		.deferred	= true,

ditto

>  	},
>  	{}      /* Terminator */
>  };
> @@ -231,9 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
>  {
>  	int ret;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
>  			       "lcd enable");
> @@ -301,6 +303,7 @@ void __init zoom_peripherals_init(void)
>  	if (ret)
>  		pr_err("error setting wl12xx data: %d\n", ret);
>  
> +	omap_hsmmc_init(mmc);
>  	omap_i2c_init();
>  	platform_device_register(&omap_vwlan_device);
>  	usb_musb_init(NULL);

[...]


-- 
Regards,
Igor.

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-23 14:28     ` Igor Grinberg
  0 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-23 14:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony, Rajendra,

On 02/23/12 13:40, Rajendra Nayak wrote:
> From: Tony Lindgren <tony@atomide.com>
> 
> Otherwise omap_device_build() and omap_mux related functions
> can't be marked as __init when twl is build as a module.
> 
> If a board is using GPIO pins or regulators configured by an
> external chip, such as TWL PMIC on I2C bus, the board must
> mark those MMC controllers as deferred. Additionally both
> omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
> by the board.
> 
> For MMC controllers using internal GPIO pins for card
> detect and regulators the slots don't need to be marked
> deferred. In this case calling omap_hsmmc_init() is sufficient.
> 
> Note that this patch does not change the behaviour for
> board-4430sdp.c board-omap4panda.c. These boards wrongly
> rely on the omap_hsmmc.c init function callback to configure
> the PMIC GPIO interrupt lines on external chip. If the PMIC
> interrupt lines are not configured during init, they will
> fail.
> 
> Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
>  arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
>  arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
>  arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
>  arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
>  arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
>  arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
>  arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
>  arch/arm/mach-omap2/board-ldp.c              |    2 +-
>  arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
>  arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
>  arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
>  arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
>  arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
>  arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
>  arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
>  arch/arm/mach-omap2/board-overo.c            |    5 +-
>  arch/arm/mach-omap2/board-rm680.c            |    2 +-
>  arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
>  arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
>  arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
>  arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
>  21 files changed, 165 insertions(+), 89 deletions(-)

[...]

> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index d73316e..14df109 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
> -
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> +		.deferred	= true,

Why do you defer this one?
It does not use external GPIO chip, in fact it does not use CD/WP at all.

>  	},
>  	{}	/* Terminator */
>  };
> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>  		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>  	}
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	return 0;
>  }
> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>  	omap_serial_init();
>  	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>  			     mt46h32m32lf6_sdrc_params);
> +	omap_hsmmc_init(mmc);
>  	cm_t35_init_i2c();
>  	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>  	cm_t35_init_ethernet();

Other then the comment above, looks fine.
I will probably be able to test this on Sunday.

[...]

> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index a59ace0..11a6aa4 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,
>  	},
>  #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>  	{
> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.caps		= MMC_CAP_4_BIT_DATA,
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,

same here, why defer it?

>  	},
>  #endif
>  	{}      /* Terminator */
> @@ -400,9 +402,7 @@ static int igep_twl_gpio_setup(struct device *dev,
>  {
>  	int ret;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
>  #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
> @@ -639,6 +639,9 @@ static void __init igep_init(void)
>  
>  	/* Get IGEP2 hardware revision */
>  	igep2_get_revision();
> +
> +	omap_hsmmc_init(mmc);
> +
>  	/* Register I2C busses and drivers */
>  	igep_i2c_init();
>  	platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));

[...]

> diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
> index c775bea..b736c4d 100644
> --- a/arch/arm/mach-omap2/board-omap3evm.c
> +++ b/arch/arm/mach-omap2/board-omap3evm.c
> @@ -315,8 +315,9 @@ static struct omap2_hsmmc_info mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= 63,
> +		.deferred	= true,
>  	},
>  #ifdef CONFIG_WL12XX_PLATFORM_DATA
>  	{
> @@ -326,6 +327,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.gpio_cd	= -EINVAL,
>  		.nonremovable	= true,
> +		.deferred	= true,

ditto

>  	},
>  #endif
>  	{}	/* Terminator */
> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>  {
>  	int r, lcd_bl_en;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>  	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	/*
>  	 * Most GPIOs are for USB OTG.  Some are mostly sent to
> @@ -644,6 +644,7 @@ static void __init omap3_evm_init(void)
>  	omap_board_config = omap3_evm_config;
>  	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
>  
> +	omap_hsmmc_init(mmc);
>  	omap3_evm_i2c_init();
>  
>  	omap_display_init(&omap3_evm_dss_data);

[...]

> diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
> index 1644b73..d984048 100644
> --- a/arch/arm/mach-omap2/board-omap3pandora.c
> +++ b/arch/arm/mach-omap2/board-omap3pandora.c
> @@ -270,17 +270,19 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
>  	{
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= 126,
>  		.ext_clock	= 0,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> -		.gpio_cd	= -EINVAL,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 1,
>  		.gpio_wp	= 127,
>  		.ext_clock	= 1,
>  		.transceiver	= true,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 3,
> @@ -288,6 +290,7 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
>  		.init_card	= pandora_wl1251_init_card,
> +		.deferred	= true,

ditto

>  	},
>  	{}	/* Terminator */
>  };
> @@ -297,10 +300,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
>  {
>  	int ret, gpio_32khz;
>  
> -	/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
> -	omap3pandora_mmc[0].gpio_cd = gpio + 0;
> -	omap3pandora_mmc[1].gpio_cd = gpio + 1;
> -	omap2_hsmmc_init(omap3pandora_mmc);
> +	omap_hsmmc_deferred_add(omap3pandora_mmc);
>  
>  	/* gpio + 13 drives 32kHz buffer for wifi module */
>  	gpio_32khz = gpio + 13;
> @@ -580,6 +580,7 @@ static struct omap_board_mux board_mux[] __initdata = {
>  static void __init omap3pandora_init(void)
>  {
>  	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> +	omap_hsmmc_init(omap3pandora_mmc);
>  	omap3pandora_i2c_init();
>  	pandora_wl1251_init();
>  	platform_add_devices(omap3pandora_devices,

[...]

> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 52c0cef..8b6065b 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -301,6 +301,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.caps		= MMC_CAP_4_BIT_DATA,
>  		.gpio_cd	= -EINVAL,
>  		.gpio_wp	= -EINVAL,
> +		.deferred	= true,
>  	},
>  	{
>  		.mmc		= 2,
> @@ -309,6 +310,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.transceiver	= true,
>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> +		.deferred	= true,
>  	},
>  	{}	/* Terminator */
>  };
> @@ -407,7 +409,7 @@ static inline void __init overo_init_keys(void) { return; }
>  static int overo_twl_gpio_setup(struct device *dev,
>  		unsigned gpio, unsigned ngpio)
>  {
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);

This board does not look like using external chip for MMC GPIOs,
if that is true, then the above can be just removed.

Added Steve to Cc.

>  
>  #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
>  	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
> @@ -505,6 +507,7 @@ static void __init overo_init(void)
>  	int ret;
>  
>  	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
> +	omap_hsmmc_init(mmc);
>  	overo_i2c_init();
>  	omap_display_init(&overo_dss_data);
>  	omap_serial_init();

[...]

> diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
> index c126461..f99284f 100644
> --- a/arch/arm/mach-omap2/board-zoom-peripherals.c
> +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
> @@ -203,8 +203,10 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.name		= "external",
>  		.mmc		= 1,
>  		.caps		= MMC_CAP_4_BIT_DATA,
> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>  		.gpio_wp	= -EINVAL,
>  		.power_saving	= true,
> +		.deferred	= true,
>  	},
>  	{
>  		.name		= "internal",
> @@ -214,6 +216,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.nonremovable	= true,
>  		.power_saving	= true,
> +		.deferred	= true,

ditto, why defer?

>  	},
>  	{
>  		.name		= "wl1271",
> @@ -222,6 +225,7 @@ static struct omap2_hsmmc_info mmc[] = {
>  		.gpio_wp	= -EINVAL,
>  		.gpio_cd	= -EINVAL,
>  		.nonremovable	= true,
> +		.deferred	= true,

ditto

>  	},
>  	{}      /* Terminator */
>  };
> @@ -231,9 +235,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
>  {
>  	int ret;
>  
> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> -	mmc[0].gpio_cd = gpio + 0;
> -	omap2_hsmmc_init(mmc);
> +	omap_hsmmc_deferred_add(mmc);
>  
>  	ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
>  			       "lcd enable");
> @@ -301,6 +303,7 @@ void __init zoom_peripherals_init(void)
>  	if (ret)
>  		pr_err("error setting wl12xx data: %d\n", ret);
>  
> +	omap_hsmmc_init(mmc);
>  	omap_i2c_init();
>  	platform_device_register(&omap_vwlan_device);
>  	usb_musb_init(NULL);

[...]


-- 
Regards,
Igor.

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

* Re: [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
  2012-02-23 11:40   ` Rajendra Nayak
@ 2012-02-23 14:55     ` Igor Grinberg
  -1 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-23 14:55 UTC (permalink / raw)
  To: Rajendra Nayak
  Cc: tony, linux-omap, linux-arm-kernel, Steve Sakoman, Steve Sakoman

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Rajendra,

On 02/23/12 13:40, Rajendra Nayak wrote:
> All OMAP3 boards which register a .setup function with twl4030
> gpio driver do not seem to have a .teardown hook implemented.
> .setup mainly requests a few gpios and also in most cases
> does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
> and of the requested gpios and also do a omap_hsmmc_deferred_del().
> This helps in case the twl4030 gpio driver is built as a module and
> added and removed multiple times. Without the .teardown a multiple
> insmod/rmmod can result in gpio request failues and also WARN messages
> stating addition of already registered mmc devices.
> 
> Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
>  arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
>  arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
>  arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
>  arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
>  arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
>  arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
>  arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
>  arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
>  arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
>  arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
>  arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
>  arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
>  arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
>  arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
>  arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
>  15 files changed, 143 insertions(+), 0 deletions(-)

[...]

> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index 14df109..55e0180 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>  	return 0;
>  }
>  
> +static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
> +				 unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);
> +	gpio_free(gpio + 2);
> +	return 0;
> +}

Can we have an empty line here?

>  static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.setup          = cm_t35_twl_gpio_setup,
> +	.teardown	= cm_t35_twl_gpio_teardown,
>  };
>  
>  static struct twl4030_platform_data cm_t35_twldata = {

[...]

> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index 11a6aa4..1d0850f 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
>  	return 0;
>  };
>  
> +static int igep_twl_gpio_teardown(struct device *dev,
> +		unsigned gpio, unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);
> +	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
> +	if (machine_is_igep0030())
> +		return 0;
> +
> +	gpio_free(gpio + 1);
> +	gpio_free(gpio + TWL4030_GPIO_MAX);

gpio_free_array()?

> +	return 0;
> +}
> +
>  static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.use_leds	= true,
>  	.setup		= igep_twl_gpio_setup,
> +	.teardown	= igep_twl_gpio_teardown,
>  };
>  
>  static int igep2_enable_dvi(struct omap_dss_device *dssdev)

[...]

> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 8b6065b..e1f496d 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
>  	return 0;
>  }
>  
> +static int overo_twl_gpio_teardown(struct device *dev,
> +		unsigned gpio, unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);

If Overo will not have omap_hsmmc_deferred_add() (as for my comment to
the previous patch), then no need for the omap_hsmmc_deferred_del().

> +	return 0;
> +}
> +
>  static struct twl4030_gpio_platform_data overo_gpio_data = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.use_leds	= true,
>  	.setup		= overo_twl_gpio_setup,
> +	.teardown	= overo_twl_gpio_teardown,
>  };
>  
>  static struct regulator_init_data overo_vmmc1 = {

[...]

> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
> index 51e3a2d..0f256ca 100644
> --- a/arch/arm/mach-omap2/hsmmc.c
> +++ b/arch/arm/mach-omap2/hsmmc.c
> @@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
>  	}
>  }
>  
> +void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
> +{
> +	struct platform_device *pdev;
> +	for (; controllers->mmc; controllers++) {
> +		if (!controllers->deferred)
> +			continue;
> +		pdev = controllers->pdev;
> +		omap_device_unregister(pdev);

Just:

if (controllers->deferred)
	omap_device_unregister(controllers->pdev);

and no need for the for loop brackets?

> +	}
> +}
> +
>  void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
>  {
>  	u32 reg;

[...]


- -- 
Regards,
Igor.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJPRlNnAAoJEBDE8YO64EfabxYP/0/4OVAirTFzPpyJfkAXHeKI
+CeAQN+/aPChvkJ2cuxarR/RdfJjOZNyLDh9t01Hs8RMgOQF2tIhxkHsxsATfQoa
80pXX+eyq4cDcyy+knDm/2Nhr6smsZLRGyw5IvuuVyL4yzyQDe8XZUnr2X58Us0F
0wm7+JtzGkFQxjhxj6Dqh5XaeOi6qTHsO9DG342d6/2ps/Dc/E0J4d9l06EykCzH
l/QFYA5NBuhbVXJOOheosr1z8yD+BQUg/oOUDU7yl3Dzhat9ka348iYrK1ndy4Us
DWV/4oOt7MOqKozscsLwLuWqfSQMupXc0AJGrFLrDeimj0vAlXSIUL7WRA7Kx9E1
DV4UZZYIRseqIia7FbIjxvevW5XIfm149G+4XFzrmCz48OCpVDs/KSJpqtNNpS0q
IkxQdE4AIpj6VzSzeARMSL0iqucB7BZGZFtv0E41RWHe5UFiQ/QnsBSc2nNJxBlt
UAyW/Baya+zL9F1SrcMwufKCFngxae5WBfEi1MqHPTBOmQm9kAlxGSHryZ1xPgL3
/xrJEeDw9kfyAFgWJHckHNyiDxx85yrv6zeX/hyk2j5VzmuEaW1+ETx07oF+sssB
+3Bz+qJJMSMl8bvzGMafZCRMfu4Hv0UbQh8gnY6Dx16zMAccCIu5qv3iAO+vwkSM
RH841I5wPtu6TTZRWGrj
=WzOO
-----END PGP SIGNATURE-----

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

* [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
@ 2012-02-23 14:55     ` Igor Grinberg
  0 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-23 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Rajendra,

On 02/23/12 13:40, Rajendra Nayak wrote:
> All OMAP3 boards which register a .setup function with twl4030
> gpio driver do not seem to have a .teardown hook implemented.
> .setup mainly requests a few gpios and also in most cases
> does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
> and of the requested gpios and also do a omap_hsmmc_deferred_del().
> This helps in case the twl4030 gpio driver is built as a module and
> added and removed multiple times. Without the .teardown a multiple
> insmod/rmmod can result in gpio request failues and also WARN messages
> stating addition of already registered mmc devices.
> 
> Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> ---
>  arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
>  arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
>  arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
>  arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
>  arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
>  arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
>  arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
>  arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
>  arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
>  arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
>  arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
>  arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
>  arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
>  arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
>  arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
>  15 files changed, 143 insertions(+), 0 deletions(-)

[...]

> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index 14df109..55e0180 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>  	return 0;
>  }
>  
> +static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
> +				 unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);
> +	gpio_free(gpio + 2);
> +	return 0;
> +}

Can we have an empty line here?

>  static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.setup          = cm_t35_twl_gpio_setup,
> +	.teardown	= cm_t35_twl_gpio_teardown,
>  };
>  
>  static struct twl4030_platform_data cm_t35_twldata = {

[...]

> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> index 11a6aa4..1d0850f 100644
> --- a/arch/arm/mach-omap2/board-igep0020.c
> +++ b/arch/arm/mach-omap2/board-igep0020.c
> @@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
>  	return 0;
>  };
>  
> +static int igep_twl_gpio_teardown(struct device *dev,
> +		unsigned gpio, unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);
> +	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
> +	if (machine_is_igep0030())
> +		return 0;
> +
> +	gpio_free(gpio + 1);
> +	gpio_free(gpio + TWL4030_GPIO_MAX);

gpio_free_array()?

> +	return 0;
> +}
> +
>  static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.use_leds	= true,
>  	.setup		= igep_twl_gpio_setup,
> +	.teardown	= igep_twl_gpio_teardown,
>  };
>  
>  static int igep2_enable_dvi(struct omap_dss_device *dssdev)

[...]

> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
> index 8b6065b..e1f496d 100644
> --- a/arch/arm/mach-omap2/board-overo.c
> +++ b/arch/arm/mach-omap2/board-overo.c
> @@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
>  	return 0;
>  }
>  
> +static int overo_twl_gpio_teardown(struct device *dev,
> +		unsigned gpio, unsigned ngpio)
> +{
> +	omap_hsmmc_deferred_del(mmc);

If Overo will not have omap_hsmmc_deferred_add() (as for my comment to
the previous patch), then no need for the omap_hsmmc_deferred_del().

> +	return 0;
> +}
> +
>  static struct twl4030_gpio_platform_data overo_gpio_data = {
>  	.gpio_base	= OMAP_MAX_GPIO_LINES,
>  	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>  	.irq_end	= TWL4030_GPIO_IRQ_END,
>  	.use_leds	= true,
>  	.setup		= overo_twl_gpio_setup,
> +	.teardown	= overo_twl_gpio_teardown,
>  };
>  
>  static struct regulator_init_data overo_vmmc1 = {

[...]

> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
> index 51e3a2d..0f256ca 100644
> --- a/arch/arm/mach-omap2/hsmmc.c
> +++ b/arch/arm/mach-omap2/hsmmc.c
> @@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
>  	}
>  }
>  
> +void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
> +{
> +	struct platform_device *pdev;
> +	for (; controllers->mmc; controllers++) {
> +		if (!controllers->deferred)
> +			continue;
> +		pdev = controllers->pdev;
> +		omap_device_unregister(pdev);

Just:

if (controllers->deferred)
	omap_device_unregister(controllers->pdev);

and no need for the for loop brackets?

> +	}
> +}
> +
>  void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
>  {
>  	u32 reg;

[...]


- -- 
Regards,
Igor.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJPRlNnAAoJEBDE8YO64EfabxYP/0/4OVAirTFzPpyJfkAXHeKI
+CeAQN+/aPChvkJ2cuxarR/RdfJjOZNyLDh9t01Hs8RMgOQF2tIhxkHsxsATfQoa
80pXX+eyq4cDcyy+knDm/2Nhr6smsZLRGyw5IvuuVyL4yzyQDe8XZUnr2X58Us0F
0wm7+JtzGkFQxjhxj6Dqh5XaeOi6qTHsO9DG342d6/2ps/Dc/E0J4d9l06EykCzH
l/QFYA5NBuhbVXJOOheosr1z8yD+BQUg/oOUDU7yl3Dzhat9ka348iYrK1ndy4Us
DWV/4oOt7MOqKozscsLwLuWqfSQMupXc0AJGrFLrDeimj0vAlXSIUL7WRA7Kx9E1
DV4UZZYIRseqIia7FbIjxvevW5XIfm149G+4XFzrmCz48OCpVDs/KSJpqtNNpS0q
IkxQdE4AIpj6VzSzeARMSL0iqucB7BZGZFtv0E41RWHe5UFiQ/QnsBSc2nNJxBlt
UAyW/Baya+zL9F1SrcMwufKCFngxae5WBfEi1MqHPTBOmQm9kAlxGSHryZ1xPgL3
/xrJEeDw9kfyAFgWJHckHNyiDxx85yrv6zeX/hyk2j5VzmuEaW1+ETx07oF+sssB
+3Bz+qJJMSMl8bvzGMafZCRMfu4Hv0UbQh8gnY6Dx16zMAccCIu5qv3iAO+vwkSM
RH841I5wPtu6TTZRWGrj
=WzOO
-----END PGP SIGNATURE-----

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-23 14:28     ` Igor Grinberg
@ 2012-02-23 18:47       ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-23 18:47 UTC (permalink / raw)
  To: Igor Grinberg
  Cc: Rajendra Nayak, linux-omap, linux-arm-kernel, Steve Sakoman,
	Steve Sakoman

* Igor Grinberg <grinberg@compulab.co.il> [120223 05:56]:
> > --- a/arch/arm/mach-omap2/board-cm-t35.c
> > +++ b/arch/arm/mach-omap2/board-cm-t35.c
> > @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >  	{
> >  		.mmc		= 1,
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> > -		.gpio_cd	= -EINVAL,
> > +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >  		.gpio_wp	= -EINVAL,

I don't have these changes, in my second revision of the patch.

It's best not to hardcode the values here.

> > -
> > +		.deferred	= true,
> >  	},
> >  	{
> >  		.mmc		= 2,
> > @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >  		.gpio_cd	= -EINVAL,
> >  		.gpio_wp	= -EINVAL,
> >  		.ocr_mask	= 0x00100000,	/* 3.3V */
> > +		.deferred	= true,
> 
> Why do you defer this one?
> It does not use external GPIO chip, in fact it does not use CD/WP at all.

Why do you have the following then to set gpio_cd?
 
> >  	},
> >  	{}	/* Terminator */
> >  };
> > @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
> >  		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
> >  	}
> >  
> > -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> > -	mmc[0].gpio_cd = gpio + 0;
> > -	omap2_hsmmc_init(mmc);
> > +	omap_hsmmc_deferred_add(mmc);
> >  
> >  	return 0;
> >  }

Hmm I don't have omap_hsmmc_deferred_add() in my second version
of the patch either.

Rajendra, please do the patches on that, now it's impossible to
see what else you've changed. That's the version posted here:

http://www.spinics.net/lists/linux-omap/msg64884.html

> > @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
> >  	omap_serial_init();
> >  	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
> >  			     mt46h32m32lf6_sdrc_params);
> > +	omap_hsmmc_init(mmc);
> >  	cm_t35_init_i2c();
> >  	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
> >  	cm_t35_init_ethernet();
> 
> Other then the comment above, looks fine.
> I will probably be able to test this on Sunday.

OK
 
> > diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> > index a59ace0..11a6aa4 100644
> > --- a/arch/arm/mach-omap2/board-igep0020.c
> > +++ b/arch/arm/mach-omap2/board-igep0020.c
> > @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >  	{
> >  		.mmc		= 1,
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> > -		.gpio_cd	= -EINVAL,
> > +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >  		.gpio_wp	= -EINVAL,
> > +		.deferred	= true,
> >  	},
> >  #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
> >  	{
> > @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> >  		.gpio_cd	= -EINVAL,
> >  		.gpio_wp	= -EINVAL,
> > +		.deferred	= true,
> 
> same here, why defer it?

Because it too sets gpio_cd in the callback.
 
> ditto

ditto, that too sets gpio_cd..
 
> >  	},
> >  #endif
> >  	{}	/* Terminator */
> > @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
> >  {
> >  	int r, lcd_bl_en;
> >  
> > -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> >  	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
> > -	mmc[0].gpio_cd = gpio + 0;

..here. Same for the others. So maybe check is some are wrong?

Tony

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-23 18:47       ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-23 18:47 UTC (permalink / raw)
  To: linux-arm-kernel

* Igor Grinberg <grinberg@compulab.co.il> [120223 05:56]:
> > --- a/arch/arm/mach-omap2/board-cm-t35.c
> > +++ b/arch/arm/mach-omap2/board-cm-t35.c
> > @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >  	{
> >  		.mmc		= 1,
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> > -		.gpio_cd	= -EINVAL,
> > +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >  		.gpio_wp	= -EINVAL,

I don't have these changes, in my second revision of the patch.

It's best not to hardcode the values here.

> > -
> > +		.deferred	= true,
> >  	},
> >  	{
> >  		.mmc		= 2,
> > @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >  		.gpio_cd	= -EINVAL,
> >  		.gpio_wp	= -EINVAL,
> >  		.ocr_mask	= 0x00100000,	/* 3.3V */
> > +		.deferred	= true,
> 
> Why do you defer this one?
> It does not use external GPIO chip, in fact it does not use CD/WP at all.

Why do you have the following then to set gpio_cd?
 
> >  	},
> >  	{}	/* Terminator */
> >  };
> > @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
> >  		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
> >  	}
> >  
> > -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> > -	mmc[0].gpio_cd = gpio + 0;
> > -	omap2_hsmmc_init(mmc);
> > +	omap_hsmmc_deferred_add(mmc);
> >  
> >  	return 0;
> >  }

Hmm I don't have omap_hsmmc_deferred_add() in my second version
of the patch either.

Rajendra, please do the patches on that, now it's impossible to
see what else you've changed. That's the version posted here:

http://www.spinics.net/lists/linux-omap/msg64884.html

> > @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
> >  	omap_serial_init();
> >  	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
> >  			     mt46h32m32lf6_sdrc_params);
> > +	omap_hsmmc_init(mmc);
> >  	cm_t35_init_i2c();
> >  	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
> >  	cm_t35_init_ethernet();
> 
> Other then the comment above, looks fine.
> I will probably be able to test this on Sunday.

OK
 
> > diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
> > index a59ace0..11a6aa4 100644
> > --- a/arch/arm/mach-omap2/board-igep0020.c
> > +++ b/arch/arm/mach-omap2/board-igep0020.c
> > @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >  	{
> >  		.mmc		= 1,
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> > -		.gpio_cd	= -EINVAL,
> > +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >  		.gpio_wp	= -EINVAL,
> > +		.deferred	= true,
> >  	},
> >  #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
> >  	{
> > @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >  		.caps		= MMC_CAP_4_BIT_DATA,
> >  		.gpio_cd	= -EINVAL,
> >  		.gpio_wp	= -EINVAL,
> > +		.deferred	= true,
> 
> same here, why defer it?

Because it too sets gpio_cd in the callback.
 
> ditto

ditto, that too sets gpio_cd..
 
> >  	},
> >  #endif
> >  	{}	/* Terminator */
> > @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
> >  {
> >  	int r, lcd_bl_en;
> >  
> > -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> >  	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
> > -	mmc[0].gpio_cd = gpio + 0;

..here. Same for the others. So maybe check is some are wrong?

Tony

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

* Re: [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
  2012-02-23 11:40 ` Rajendra Nayak
@ 2012-02-23 18:52   ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-23 18:52 UTC (permalink / raw)
  To: Rajendra Nayak; +Cc: linux-omap, linux-arm-kernel

* Rajendra Nayak <rnayak@ti.com> [120223 03:09]:
> Re-sending as these patches did not make it to the lists due to
> issues with my 'git send-email'
> 
> Hi Tony,
> 
> This is a re-spin of your series to fix up the section
> mismatch warnings noted by Russell with omap2_hsmmc_init().
> The previous series had an issue around multiple insmod/rmmod
> of the twl4030 gpio driver when built as a module as reported
> by Russell again.

OK, can you please rebase your patches on hsmmc branch in linux-omap
at commit 0e91c8ddf0e0932da59ec1d116e34049791b0e73?

Note that at least the hardcoded GPIO numbers are no longer needed.
 
> There were 2 issues, one with gpio_requests failing as they were
> never freed on the module unload/unbind. The other was with the
> mmc devices being registered again. I have fixed both these issues
> in this series, mainly by having a .teardown hook for twl4030 gpio
> driver populated from all OMAP3 board files, which release all the
> requested gpios and also unregister the mmc omap/platform device.

Yes that's great.
 
Regards,

Tony

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

* [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
@ 2012-02-23 18:52   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-23 18:52 UTC (permalink / raw)
  To: linux-arm-kernel

* Rajendra Nayak <rnayak@ti.com> [120223 03:09]:
> Re-sending as these patches did not make it to the lists due to
> issues with my 'git send-email'
> 
> Hi Tony,
> 
> This is a re-spin of your series to fix up the section
> mismatch warnings noted by Russell with omap2_hsmmc_init().
> The previous series had an issue around multiple insmod/rmmod
> of the twl4030 gpio driver when built as a module as reported
> by Russell again.

OK, can you please rebase your patches on hsmmc branch in linux-omap
at commit 0e91c8ddf0e0932da59ec1d116e34049791b0e73?

Note that at least the hardcoded GPIO numbers are no longer needed.
 
> There were 2 issues, one with gpio_requests failing as they were
> never freed on the module unload/unbind. The other was with the
> mmc devices being registered again. I have fixed both these issues
> in this series, mainly by having a .teardown hook for twl4030 gpio
> driver populated from all OMAP3 board files, which release all the
> requested gpios and also unregister the mmc omap/platform device.

Yes that's great.
 
Regards,

Tony

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-23 14:28     ` Igor Grinberg
@ 2012-02-24  3:24       ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  3:24 UTC (permalink / raw)
  To: Igor Grinberg
  Cc: tony, Steve Sakoman, linux-omap, linux-arm-kernel, Steve Sakoman

On Thursday 23 February 2012 07:58 PM, Igor Grinberg wrote:
> Hi Tony, Rajendra,
>
> On 02/23/12 13:40, Rajendra Nayak wrote:
>> >  From: Tony Lindgren<tony@atomide.com>
>> >
>> >  Otherwise omap_device_build() and omap_mux related functions
>> >  can't be marked as __init when twl is build as a module.
>> >
>> >  If a board is using GPIO pins or regulators configured by an
>> >  external chip, such as TWL PMIC on I2C bus, the board must
>> >  mark those MMC controllers as deferred. Additionally both
>> >  omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
>> >  by the board.
>> >
>> >  For MMC controllers using internal GPIO pins for card
>> >  detect and regulators the slots don't need to be marked
>> >  deferred. In this case calling omap_hsmmc_init() is sufficient.
>> >
>> >  Note that this patch does not change the behaviour for
>> >  board-4430sdp.c board-omap4panda.c. These boards wrongly
>> >  rely on the omap_hsmmc.c init function callback to configure
>> >  the PMIC GPIO interrupt lines on external chip. If the PMIC
>> >  interrupt lines are not configured during init, they will
>> >  fail.
>> >
>> >  Reported-by: Russell King<rmk+kernel@arm.linux.org.uk>
>> >  Signed-off-by: Tony Lindgren<tony@atomide.com>
>> >  Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> >  ---
>> >    arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
>> >    arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
>> >    arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
>> >    arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
>> >    arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
>> >    arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
>> >    arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
>> >    arch/arm/mach-omap2/board-ldp.c              |    2 +-
>> >    arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
>> >    arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
>> >    arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
>> >    arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
>> >    arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
>> >    arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
>> >    arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
>> >    arch/arm/mach-omap2/board-overo.c            |    5 +-
>> >    arch/arm/mach-omap2/board-rm680.c            |    2 +-
>> >    arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
>> >    arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
>> >    arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
>> >    arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
>> >    21 files changed, 165 insertions(+), 89 deletions(-)
> [...]
>
>> >  diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
>> >  index d73316e..14df109 100644
>> >  --- a/arch/arm/mach-omap2/board-cm-t35.c
>> >  +++ b/arch/arm/mach-omap2/board-cm-t35.c
>> >  @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>> >    	{
>> >    		.mmc		= 1,
>> >    		.caps		= MMC_CAP_4_BIT_DATA,
>> >  -		.gpio_cd	= -EINVAL,
>> >  +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>> >    		.gpio_wp	= -EINVAL,
>> >  -
>> >  +		.deferred	= true,
>> >    	},
>> >    	{
>> >    		.mmc		= 2,
>> >  @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>> >    		.gpio_cd	= -EINVAL,
>> >    		.gpio_wp	= -EINVAL,
>> >    		.ocr_mask	= 0x00100000,	/* 3.3V */
>> >  +		.deferred	= true,
> Why do you defer this one?
> It does not use external GPIO chip, in fact it does not use CD/WP at all.

I thought so too, but kept it that way since Tony's original patch
deferred it.
Tony, any reason you deferred the mmc devices which *do not* have card
detect via twl4030 gpio too?

>
>> >    	},
>> >    	{}	/* Terminator */
>> >    };
>> >  @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>> >    		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>> >    	}
>> >
>> >  -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>> >  -	mmc[0].gpio_cd = gpio + 0;
>> >  -	omap2_hsmmc_init(mmc);
>> >  +	omap_hsmmc_deferred_add(mmc);
>> >
>> >    	return 0;
>> >    }
>> >  @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>> >    	omap_serial_init();
>> >    	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>> >    			mt46h32m32lf6_sdrc_params);
>> >  +	omap_hsmmc_init(mmc);
>> >    	cm_t35_init_i2c();
>> >    	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>> >    	cm_t35_init_ethernet();
> Other then the comment above, looks fine.
> I will probably be able to test this on Sunday.

Great, thanks.

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-24  3:24       ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  3:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 23 February 2012 07:58 PM, Igor Grinberg wrote:
> Hi Tony, Rajendra,
>
> On 02/23/12 13:40, Rajendra Nayak wrote:
>> >  From: Tony Lindgren<tony@atomide.com>
>> >
>> >  Otherwise omap_device_build() and omap_mux related functions
>> >  can't be marked as __init when twl is build as a module.
>> >
>> >  If a board is using GPIO pins or regulators configured by an
>> >  external chip, such as TWL PMIC on I2C bus, the board must
>> >  mark those MMC controllers as deferred. Additionally both
>> >  omap_hsmmc_init() and omap_hsmmc_deferred_add() must be called
>> >  by the board.
>> >
>> >  For MMC controllers using internal GPIO pins for card
>> >  detect and regulators the slots don't need to be marked
>> >  deferred. In this case calling omap_hsmmc_init() is sufficient.
>> >
>> >  Note that this patch does not change the behaviour for
>> >  board-4430sdp.c board-omap4panda.c. These boards wrongly
>> >  rely on the omap_hsmmc.c init function callback to configure
>> >  the PMIC GPIO interrupt lines on external chip. If the PMIC
>> >  interrupt lines are not configured during init, they will
>> >  fail.
>> >
>> >  Reported-by: Russell King<rmk+kernel@arm.linux.org.uk>
>> >  Signed-off-by: Tony Lindgren<tony@atomide.com>
>> >  Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> >  ---
>> >    arch/arm/mach-omap2/board-2430sdp.c          |    2 +-
>> >    arch/arm/mach-omap2/board-3430sdp.c          |   12 ++--
>> >    arch/arm/mach-omap2/board-4430sdp.c          |    4 +-
>> >    arch/arm/mach-omap2/board-am3517evm.c        |    2 +-
>> >    arch/arm/mach-omap2/board-cm-t35.c           |   10 +-
>> >    arch/arm/mach-omap2/board-devkit8000.c       |    7 +-
>> >    arch/arm/mach-omap2/board-igep0020.c         |   11 ++-
>> >    arch/arm/mach-omap2/board-ldp.c              |    2 +-
>> >    arch/arm/mach-omap2/board-omap3beagle.c      |    7 +-
>> >    arch/arm/mach-omap2/board-omap3evm.c         |    9 +-
>> >    arch/arm/mach-omap2/board-omap3logic.c       |    2 +-
>> >    arch/arm/mach-omap2/board-omap3pandora.c     |   13 ++--
>> >    arch/arm/mach-omap2/board-omap3stalker.c     |   14 ++--
>> >    arch/arm/mach-omap2/board-omap3touchbook.c   |    7 +-
>> >    arch/arm/mach-omap2/board-omap4panda.c       |    4 +-
>> >    arch/arm/mach-omap2/board-overo.c            |    5 +-
>> >    arch/arm/mach-omap2/board-rm680.c            |    2 +-
>> >    arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
>> >    arch/arm/mach-omap2/board-zoom-peripherals.c |    9 ++-
>> >    arch/arm/mach-omap2/hsmmc.c                  |  117 +++++++++++++++++++-------
>> >    arch/arm/mach-omap2/hsmmc.h                  |   13 ++-
>> >    21 files changed, 165 insertions(+), 89 deletions(-)
> [...]
>
>> >  diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
>> >  index d73316e..14df109 100644
>> >  --- a/arch/arm/mach-omap2/board-cm-t35.c
>> >  +++ b/arch/arm/mach-omap2/board-cm-t35.c
>> >  @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>> >    	{
>> >    		.mmc		= 1,
>> >    		.caps		= MMC_CAP_4_BIT_DATA,
>> >  -		.gpio_cd	= -EINVAL,
>> >  +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>> >    		.gpio_wp	= -EINVAL,
>> >  -
>> >  +		.deferred	= true,
>> >    	},
>> >    	{
>> >    		.mmc		= 2,
>> >  @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>> >    		.gpio_cd	= -EINVAL,
>> >    		.gpio_wp	= -EINVAL,
>> >    		.ocr_mask	= 0x00100000,	/* 3.3V */
>> >  +		.deferred	= true,
> Why do you defer this one?
> It does not use external GPIO chip, in fact it does not use CD/WP at all.

I thought so too, but kept it that way since Tony's original patch
deferred it.
Tony, any reason you deferred the mmc devices which *do not* have card
detect via twl4030 gpio too?

>
>> >    	},
>> >    	{}	/* Terminator */
>> >    };
>> >  @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>> >    		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>> >    	}
>> >
>> >  -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>> >  -	mmc[0].gpio_cd = gpio + 0;
>> >  -	omap2_hsmmc_init(mmc);
>> >  +	omap_hsmmc_deferred_add(mmc);
>> >
>> >    	return 0;
>> >    }
>> >  @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>> >    	omap_serial_init();
>> >    	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>> >    			mt46h32m32lf6_sdrc_params);
>> >  +	omap_hsmmc_init(mmc);
>> >    	cm_t35_init_i2c();
>> >    	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>> >    	cm_t35_init_ethernet();
> Other then the comment above, looks fine.
> I will probably be able to test this on Sunday.

Great, thanks.

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

* Re: [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
  2012-02-23 14:55     ` Igor Grinberg
@ 2012-02-24  3:43       ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  3:43 UTC (permalink / raw)
  To: Igor Grinberg
  Cc: tony, linux-omap, linux-arm-kernel, Steve Sakoman, Steve Sakoman

Igor,

On Thursday 23 February 2012 08:25 PM, Igor Grinberg wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi Rajendra,
>
> On 02/23/12 13:40, Rajendra Nayak wrote:
>> All OMAP3 boards which register a .setup function with twl4030
>> gpio driver do not seem to have a .teardown hook implemented.
>> .setup mainly requests a few gpios and also in most cases
>> does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
>> and of the requested gpios and also do a omap_hsmmc_deferred_del().
>> This helps in case the twl4030 gpio driver is built as a module and
>> added and removed multiple times. Without the .teardown a multiple
>> insmod/rmmod can result in gpio request failues and also WARN messages
>> stating addition of already registered mmc devices.

Thanks for the review. I'll take care of all your comments in the next
spin.

regards,
Rajendra

>>
>> Reported-by: Russell King<rmk+kernel@arm.linux.org.uk>
>> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> ---
>>   arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
>>   arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
>>   arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
>>   arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
>>   arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
>>   arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
>>   arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
>>   arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
>>   arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
>>   arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
>>   arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
>>   arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
>>   arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
>>   arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
>>   arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
>>   15 files changed, 143 insertions(+), 0 deletions(-)
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
>> index 14df109..55e0180 100644
>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>> @@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>   	return 0;
>>   }
>>
>> +static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
>> +				 unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>> +	gpio_free(gpio + 2);
>> +	return 0;
>> +}
>
> Can we have an empty line here?
>
>>   static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.setup          = cm_t35_twl_gpio_setup,
>> +	.teardown	= cm_t35_twl_gpio_teardown,
>>   };
>>
>>   static struct twl4030_platform_data cm_t35_twldata = {
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>> index 11a6aa4..1d0850f 100644
>> --- a/arch/arm/mach-omap2/board-igep0020.c
>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>> @@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
>>   	return 0;
>>   };
>>
>> +static int igep_twl_gpio_teardown(struct device *dev,
>> +		unsigned gpio, unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>> +	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
>> +	if (machine_is_igep0030())
>> +		return 0;
>> +
>> +	gpio_free(gpio + 1);
>> +	gpio_free(gpio + TWL4030_GPIO_MAX);
>
> gpio_free_array()?
>
>> +	return 0;
>> +}
>> +
>>   static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.use_leds	= true,
>>   	.setup		= igep_twl_gpio_setup,
>> +	.teardown	= igep_twl_gpio_teardown,
>>   };
>>
>>   static int igep2_enable_dvi(struct omap_dss_device *dssdev)
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
>> index 8b6065b..e1f496d 100644
>> --- a/arch/arm/mach-omap2/board-overo.c
>> +++ b/arch/arm/mach-omap2/board-overo.c
>> @@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
>>   	return 0;
>>   }
>>
>> +static int overo_twl_gpio_teardown(struct device *dev,
>> +		unsigned gpio, unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>
> If Overo will not have omap_hsmmc_deferred_add() (as for my comment to
> the previous patch), then no need for the omap_hsmmc_deferred_del().
>
>> +	return 0;
>> +}
>> +
>>   static struct twl4030_gpio_platform_data overo_gpio_data = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.use_leds	= true,
>>   	.setup		= overo_twl_gpio_setup,
>> +	.teardown	= overo_twl_gpio_teardown,
>>   };
>>
>>   static struct regulator_init_data overo_vmmc1 = {
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
>> index 51e3a2d..0f256ca 100644
>> --- a/arch/arm/mach-omap2/hsmmc.c
>> +++ b/arch/arm/mach-omap2/hsmmc.c
>> @@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
>>   	}
>>   }
>>
>> +void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
>> +{
>> +	struct platform_device *pdev;
>> +	for (; controllers->mmc; controllers++) {
>> +		if (!controllers->deferred)
>> +			continue;
>> +		pdev = controllers->pdev;
>> +		omap_device_unregister(pdev);
>
> Just:
>
> if (controllers->deferred)
> 	omap_device_unregister(controllers->pdev);
>
> and no need for the for loop brackets?
>
>> +	}
>> +}
>> +
>>   void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
>>   {
>>   	u32 reg;
>
> [...]
>
>
> - --
> Regards,
> Igor.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.17 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iQIcBAEBAgAGBQJPRlNnAAoJEBDE8YO64EfabxYP/0/4OVAirTFzPpyJfkAXHeKI
> +CeAQN+/aPChvkJ2cuxarR/RdfJjOZNyLDh9t01Hs8RMgOQF2tIhxkHsxsATfQoa
> 80pXX+eyq4cDcyy+knDm/2Nhr6smsZLRGyw5IvuuVyL4yzyQDe8XZUnr2X58Us0F
> 0wm7+JtzGkFQxjhxj6Dqh5XaeOi6qTHsO9DG342d6/2ps/Dc/E0J4d9l06EykCzH
> l/QFYA5NBuhbVXJOOheosr1z8yD+BQUg/oOUDU7yl3Dzhat9ka348iYrK1ndy4Us
> DWV/4oOt7MOqKozscsLwLuWqfSQMupXc0AJGrFLrDeimj0vAlXSIUL7WRA7Kx9E1
> DV4UZZYIRseqIia7FbIjxvevW5XIfm149G+4XFzrmCz48OCpVDs/KSJpqtNNpS0q
> IkxQdE4AIpj6VzSzeARMSL0iqucB7BZGZFtv0E41RWHe5UFiQ/QnsBSc2nNJxBlt
> UAyW/Baya+zL9F1SrcMwufKCFngxae5WBfEi1MqHPTBOmQm9kAlxGSHryZ1xPgL3
> /xrJEeDw9kfyAFgWJHckHNyiDxx85yrv6zeX/hyk2j5VzmuEaW1+ETx07oF+sssB
> +3Bz+qJJMSMl8bvzGMafZCRMfu4Hv0UbQh8gnY6Dx16zMAccCIu5qv3iAO+vwkSM
> RH841I5wPtu6TTZRWGrj
> =WzOO
> -----END PGP SIGNATURE-----


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

* [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests
@ 2012-02-24  3:43       ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  3:43 UTC (permalink / raw)
  To: linux-arm-kernel

Igor,

On Thursday 23 February 2012 08:25 PM, Igor Grinberg wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi Rajendra,
>
> On 02/23/12 13:40, Rajendra Nayak wrote:
>> All OMAP3 boards which register a .setup function with twl4030
>> gpio driver do not seem to have a .teardown hook implemented.
>> .setup mainly requests a few gpios and also in most cases
>> does a omap_hsmmc_deferred_add(). Have a .teardown do a gpio_free()
>> and of the requested gpios and also do a omap_hsmmc_deferred_del().
>> This helps in case the twl4030 gpio driver is built as a module and
>> added and removed multiple times. Without the .teardown a multiple
>> insmod/rmmod can result in gpio request failues and also WARN messages
>> stating addition of already registered mmc devices.

Thanks for the review. I'll take care of all your comments in the next
spin.

regards,
Rajendra

>>
>> Reported-by: Russell King<rmk+kernel@arm.linux.org.uk>
>> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> ---
>>   arch/arm/mach-omap2/board-3430sdp.c          |   10 ++++++++++
>>   arch/arm/mach-omap2/board-cm-t35.c           |    8 ++++++++
>>   arch/arm/mach-omap2/board-devkit8000.c       |   10 ++++++++++
>>   arch/arm/mach-omap2/board-igep0020.c         |   14 ++++++++++++++
>>   arch/arm/mach-omap2/board-ldp.c              |    9 +++++++++
>>   arch/arm/mach-omap2/board-omap3beagle.c      |   12 ++++++++++++
>>   arch/arm/mach-omap2/board-omap3evm.c         |   10 ++++++++++
>>   arch/arm/mach-omap2/board-omap3pandora.c     |    9 +++++++++
>>   arch/arm/mach-omap2/board-omap3stalker.c     |   11 +++++++++++
>>   arch/arm/mach-omap2/board-omap3touchbook.c   |   10 ++++++++++
>>   arch/arm/mach-omap2/board-overo.c            |    8 ++++++++
>>   arch/arm/mach-omap2/board-rx51-peripherals.c |    8 ++++++++
>>   arch/arm/mach-omap2/board-zoom-peripherals.c |    9 +++++++++
>>   arch/arm/mach-omap2/hsmmc.c                  |   11 +++++++++++
>>   arch/arm/mach-omap2/hsmmc.h                  |    4 ++++
>>   15 files changed, 143 insertions(+), 0 deletions(-)
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
>> index 14df109..55e0180 100644
>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>> @@ -475,11 +475,19 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>   	return 0;
>>   }
>>
>> +static int cm_t35_twl_gpio_teardown(struct device *dev, unsigned gpio,
>> +				 unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>> +	gpio_free(gpio + 2);
>> +	return 0;
>> +}
>
> Can we have an empty line here?
>
>>   static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.setup          = cm_t35_twl_gpio_setup,
>> +	.teardown	= cm_t35_twl_gpio_teardown,
>>   };
>>
>>   static struct twl4030_platform_data cm_t35_twldata = {
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>> index 11a6aa4..1d0850f 100644
>> --- a/arch/arm/mach-omap2/board-igep0020.c
>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>> @@ -435,12 +435,26 @@ static int igep_twl_gpio_setup(struct device *dev,
>>   	return 0;
>>   };
>>
>> +static int igep_twl_gpio_teardown(struct device *dev,
>> +		unsigned gpio, unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>> +	gpio_free(gpio + TWL4030_GPIO_MAX + 1);
>> +	if (machine_is_igep0030())
>> +		return 0;
>> +
>> +	gpio_free(gpio + 1);
>> +	gpio_free(gpio + TWL4030_GPIO_MAX);
>
> gpio_free_array()?
>
>> +	return 0;
>> +}
>> +
>>   static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.use_leds	= true,
>>   	.setup		= igep_twl_gpio_setup,
>> +	.teardown	= igep_twl_gpio_teardown,
>>   };
>>
>>   static int igep2_enable_dvi(struct omap_dss_device *dssdev)
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
>> index 8b6065b..e1f496d 100644
>> --- a/arch/arm/mach-omap2/board-overo.c
>> +++ b/arch/arm/mach-omap2/board-overo.c
>> @@ -419,12 +419,20 @@ static int overo_twl_gpio_setup(struct device *dev,
>>   	return 0;
>>   }
>>
>> +static int overo_twl_gpio_teardown(struct device *dev,
>> +		unsigned gpio, unsigned ngpio)
>> +{
>> +	omap_hsmmc_deferred_del(mmc);
>
> If Overo will not have omap_hsmmc_deferred_add() (as for my comment to
> the previous patch), then no need for the omap_hsmmc_deferred_del().
>
>> +	return 0;
>> +}
>> +
>>   static struct twl4030_gpio_platform_data overo_gpio_data = {
>>   	.gpio_base	= OMAP_MAX_GPIO_LINES,
>>   	.irq_base	= TWL4030_GPIO_IRQ_BASE,
>>   	.irq_end	= TWL4030_GPIO_IRQ_END,
>>   	.use_leds	= true,
>>   	.setup		= overo_twl_gpio_setup,
>> +	.teardown	= overo_twl_gpio_teardown,
>>   };
>>
>>   static struct regulator_init_data overo_vmmc1 = {
>
> [...]
>
>> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
>> index 51e3a2d..0f256ca 100644
>> --- a/arch/arm/mach-omap2/hsmmc.c
>> +++ b/arch/arm/mach-omap2/hsmmc.c
>> @@ -541,6 +541,17 @@ void omap_hsmmc_deferred_add(struct omap2_hsmmc_info *controllers)
>>   	}
>>   }
>>
>> +void omap_hsmmc_deferred_del(struct omap2_hsmmc_info *controllers)
>> +{
>> +	struct platform_device *pdev;
>> +	for (; controllers->mmc; controllers++) {
>> +		if (!controllers->deferred)
>> +			continue;
>> +		pdev = controllers->pdev;
>> +		omap_device_unregister(pdev);
>
> Just:
>
> if (controllers->deferred)
> 	omap_device_unregister(controllers->pdev);
>
> and no need for the for loop brackets?
>
>> +	}
>> +}
>> +
>>   void omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
>>   {
>>   	u32 reg;
>
> [...]
>
>
> - --
> Regards,
> Igor.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2.0.17 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iQIcBAEBAgAGBQJPRlNnAAoJEBDE8YO64EfabxYP/0/4OVAirTFzPpyJfkAXHeKI
> +CeAQN+/aPChvkJ2cuxarR/RdfJjOZNyLDh9t01Hs8RMgOQF2tIhxkHsxsATfQoa
> 80pXX+eyq4cDcyy+knDm/2Nhr6smsZLRGyw5IvuuVyL4yzyQDe8XZUnr2X58Us0F
> 0wm7+JtzGkFQxjhxj6Dqh5XaeOi6qTHsO9DG342d6/2ps/Dc/E0J4d9l06EykCzH
> l/QFYA5NBuhbVXJOOheosr1z8yD+BQUg/oOUDU7yl3Dzhat9ka348iYrK1ndy4Us
> DWV/4oOt7MOqKozscsLwLuWqfSQMupXc0AJGrFLrDeimj0vAlXSIUL7WRA7Kx9E1
> DV4UZZYIRseqIia7FbIjxvevW5XIfm149G+4XFzrmCz48OCpVDs/KSJpqtNNpS0q
> IkxQdE4AIpj6VzSzeARMSL0iqucB7BZGZFtv0E41RWHe5UFiQ/QnsBSc2nNJxBlt
> UAyW/Baya+zL9F1SrcMwufKCFngxae5WBfEi1MqHPTBOmQm9kAlxGSHryZ1xPgL3
> /xrJEeDw9kfyAFgWJHckHNyiDxx85yrv6zeX/hyk2j5VzmuEaW1+ETx07oF+sssB
> +3Bz+qJJMSMl8bvzGMafZCRMfu4Hv0UbQh8gnY6Dx16zMAccCIu5qv3iAO+vwkSM
> RH841I5wPtu6TTZRWGrj
> =WzOO
> -----END PGP SIGNATURE-----

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-23 18:47       ` Tony Lindgren
@ 2012-02-24  4:11         ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  4:11 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Igor Grinberg, linux-omap, linux-arm-kernel, Steve Sakoman,
	Steve Sakoman

On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
> * Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
>>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>>> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   	{
>>>   		.mmc		= 1,
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>> -		.gpio_cd	= -EINVAL,
>>> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>>>   		.gpio_wp	= -EINVAL,
>
> I don't have these changes, in my second revision of the patch.
>
> It's best not to hardcode the values here.

Ok, I just though doing it the other way is more round about
hardcoding where in the board passes a hardcoded value to
twl4030 gpio driver and the driver passes the *same* hardcoded
value back to the board callback, which is then populated in
mmc pdata. The board could as well directly hardcode it in the
mmc pdata. That makes it much more readable than this round about
hardcoding.
But I'll go back to the old way if you think thats how we should
handle this.

>
>>> -
>>> +		.deferred	= true,
>>>   	},
>>>   	{
>>>   		.mmc		= 2,
>>> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   		.gpio_cd	= -EINVAL,
>>>   		.gpio_wp	= -EINVAL,
>>>   		.ocr_mask	= 0x00100000,	/* 3.3V */
>>> +		.deferred	= true,
>>
>> Why do you defer this one?
>> It does not use external GPIO chip, in fact it does not use CD/WP at all.
>
> Why do you have the following then to set gpio_cd?

There is only one instance of gpio_cd being populated for the
first element in the array mmc[], which is already deferred.

 >>> -	mmc[0].gpio_cd = gpio + 0;

Igor was asking about the second element in the array which never
has gpio_cd populated. Its just initialized to -EINVAL and stays
that way.

>
>>>   	},
>>>   	{}	/* Terminator */
>>>   };
>>> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>>   		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>>>   	}
>>>
>>> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>> -	mmc[0].gpio_cd = gpio + 0;
>>> -	omap2_hsmmc_init(mmc);
>>> +	omap_hsmmc_deferred_add(mmc);
>>>
>>>   	return 0;
>>>   }
>
> Hmm I don't have omap_hsmmc_deferred_add() in my second version
> of the patch either.
>
> Rajendra, please do the patches on that, now it's impossible to
> see what else you've changed. That's the version posted here:
>
> http://www.spinics.net/lists/linux-omap/msg64884.html

Sorry for the mess up. I will make sure I have taken all changes/fixes
from your reposts.

regards,
Rajendra
>
>>> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>>>   	omap_serial_init();
>>>   	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>>>   			     mt46h32m32lf6_sdrc_params);
>>> +	omap_hsmmc_init(mmc);
>>>   	cm_t35_init_i2c();
>>>   	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>>>   	cm_t35_init_ethernet();
>>
>> Other then the comment above, looks fine.
>> I will probably be able to test this on Sunday.
>
> OK
>
>>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>>> index a59ace0..11a6aa4 100644
>>> --- a/arch/arm/mach-omap2/board-igep0020.c
>>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>>> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   	{
>>>   		.mmc		= 1,
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>> -		.gpio_cd	= -EINVAL,
>>> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>>>   		.gpio_wp	= -EINVAL,
>>> +		.deferred	= true,
>>>   	},
>>>   #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>>>   	{
>>> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>>   		.gpio_cd	= -EINVAL,
>>>   		.gpio_wp	= -EINVAL,
>>> +		.deferred	= true,
>>
>> same here, why defer it?
>
> Because it too sets gpio_cd in the callback.
>
>> ditto
>
> ditto, that too sets gpio_cd..
>
>>>   	},
>>>   #endif
>>>   	{}	/* Terminator */
>>> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>>>   {
>>>   	int r, lcd_bl_en;
>>>
>>> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>   	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
>>> -	mmc[0].gpio_cd = gpio + 0;
>
> ..here. Same for the others. So maybe check is some are wrong?
>
> Tony


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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-24  4:11         ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  4:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
> * Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
>>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>>> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   	{
>>>   		.mmc		= 1,
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>> -		.gpio_cd	= -EINVAL,
>>> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>>>   		.gpio_wp	= -EINVAL,
>
> I don't have these changes, in my second revision of the patch.
>
> It's best not to hardcode the values here.

Ok, I just though doing it the other way is more round about
hardcoding where in the board passes a hardcoded value to
twl4030 gpio driver and the driver passes the *same* hardcoded
value back to the board callback, which is then populated in
mmc pdata. The board could as well directly hardcode it in the
mmc pdata. That makes it much more readable than this round about
hardcoding.
But I'll go back to the old way if you think thats how we should
handle this.

>
>>> -
>>> +		.deferred	= true,
>>>   	},
>>>   	{
>>>   		.mmc		= 2,
>>> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   		.gpio_cd	= -EINVAL,
>>>   		.gpio_wp	= -EINVAL,
>>>   		.ocr_mask	= 0x00100000,	/* 3.3V */
>>> +		.deferred	= true,
>>
>> Why do you defer this one?
>> It does not use external GPIO chip, in fact it does not use CD/WP at all.
>
> Why do you have the following then to set gpio_cd?

There is only one instance of gpio_cd being populated for the
first element in the array mmc[], which is already deferred.

 >>> -	mmc[0].gpio_cd = gpio + 0;

Igor was asking about the second element in the array which never
has gpio_cd populated. Its just initialized to -EINVAL and stays
that way.

>
>>>   	},
>>>   	{}	/* Terminator */
>>>   };
>>> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>>   		pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>>>   	}
>>>
>>> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>> -	mmc[0].gpio_cd = gpio + 0;
>>> -	omap2_hsmmc_init(mmc);
>>> +	omap_hsmmc_deferred_add(mmc);
>>>
>>>   	return 0;
>>>   }
>
> Hmm I don't have omap_hsmmc_deferred_add() in my second version
> of the patch either.
>
> Rajendra, please do the patches on that, now it's impossible to
> see what else you've changed. That's the version posted here:
>
> http://www.spinics.net/lists/linux-omap/msg64884.html

Sorry for the mess up. I will make sure I have taken all changes/fixes
from your reposts.

regards,
Rajendra
>
>>> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>>>   	omap_serial_init();
>>>   	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>>>   			     mt46h32m32lf6_sdrc_params);
>>> +	omap_hsmmc_init(mmc);
>>>   	cm_t35_init_i2c();
>>>   	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>>>   	cm_t35_init_ethernet();
>>
>> Other then the comment above, looks fine.
>> I will probably be able to test this on Sunday.
>
> OK
>
>>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>>> index a59ace0..11a6aa4 100644
>>> --- a/arch/arm/mach-omap2/board-igep0020.c
>>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>>> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   	{
>>>   		.mmc		= 1,
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>> -		.gpio_cd	= -EINVAL,
>>> +		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
>>>   		.gpio_wp	= -EINVAL,
>>> +		.deferred	= true,
>>>   	},
>>>   #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>>>   	{
>>> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>   		.caps		= MMC_CAP_4_BIT_DATA,
>>>   		.gpio_cd	= -EINVAL,
>>>   		.gpio_wp	= -EINVAL,
>>> +		.deferred	= true,
>>
>> same here, why defer it?
>
> Because it too sets gpio_cd in the callback.
>
>> ditto
>
> ditto, that too sets gpio_cd..
>
>>>   	},
>>>   #endif
>>>   	{}	/* Terminator */
>>> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>>>   {
>>>   	int r, lcd_bl_en;
>>>
>>> -	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>   	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
>>> -	mmc[0].gpio_cd = gpio + 0;
>
> ..here. Same for the others. So maybe check is some are wrong?
>
> Tony

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

* Re: [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
  2012-02-23 18:52   ` Tony Lindgren
@ 2012-02-24  4:14     ` Rajendra Nayak
  -1 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  4:14 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap, linux-arm-kernel

On Friday 24 February 2012 12:22 AM, Tony Lindgren wrote:
> * Rajendra Nayak<rnayak@ti.com>  [120223 03:09]:
>> Re-sending as these patches did not make it to the lists due to
>> issues with my 'git send-email'
>>
>> Hi Tony,
>>
>> This is a re-spin of your series to fix up the section
>> mismatch warnings noted by Russell with omap2_hsmmc_init().
>> The previous series had an issue around multiple insmod/rmmod
>> of the twl4030 gpio driver when built as a module as reported
>> by Russell again.
>
> OK, can you please rebase your patches on hsmmc branch in linux-omap
> at commit 0e91c8ddf0e0932da59ec1d116e34049791b0e73?

Ok, will do.

>
> Note that at least the hardcoded GPIO numbers are no longer needed.

Ok, I explained my rational in the other mail thread. Its always been
hardcoded GPIO numbers and this will change only with DT as Benoit
mentioned. I was just trying to make the hard-coding more readable.
Will remove it and do it how it was done earlier, which is populate
it in the callback.

>
>> There were 2 issues, one with gpio_requests failing as they were
>> never freed on the module unload/unbind. The other was with the
>> mmc devices being registered again. I have fixed both these issues
>> in this series, mainly by having a .teardown hook for twl4030 gpio
>> driver populated from all OMAP3 board files, which release all the
>> requested gpios and also unregister the mmc omap/platform device.
>
> Yes that's great.
>
> Regards,
>
> Tony


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

* [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window
@ 2012-02-24  4:14     ` Rajendra Nayak
  0 siblings, 0 replies; 46+ messages in thread
From: Rajendra Nayak @ 2012-02-24  4:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 24 February 2012 12:22 AM, Tony Lindgren wrote:
> * Rajendra Nayak<rnayak@ti.com>  [120223 03:09]:
>> Re-sending as these patches did not make it to the lists due to
>> issues with my 'git send-email'
>>
>> Hi Tony,
>>
>> This is a re-spin of your series to fix up the section
>> mismatch warnings noted by Russell with omap2_hsmmc_init().
>> The previous series had an issue around multiple insmod/rmmod
>> of the twl4030 gpio driver when built as a module as reported
>> by Russell again.
>
> OK, can you please rebase your patches on hsmmc branch in linux-omap
> at commit 0e91c8ddf0e0932da59ec1d116e34049791b0e73?

Ok, will do.

>
> Note that at least the hardcoded GPIO numbers are no longer needed.

Ok, I explained my rational in the other mail thread. Its always been
hardcoded GPIO numbers and this will change only with DT as Benoit
mentioned. I was just trying to make the hard-coding more readable.
Will remove it and do it how it was done earlier, which is populate
it in the callback.

>
>> There were 2 issues, one with gpio_requests failing as they were
>> never freed on the module unload/unbind. The other was with the
>> mmc devices being registered again. I have fixed both these issues
>> in this series, mainly by having a .teardown hook for twl4030 gpio
>> driver populated from all OMAP3 board files, which release all the
>> requested gpios and also unregister the mmc omap/platform device.
>
> Yes that's great.
>
> Regards,
>
> Tony

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-24  4:11         ` Rajendra Nayak
@ 2012-02-24  7:01           ` Igor Grinberg
  -1 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-24  7:01 UTC (permalink / raw)
  To: Rajendra Nayak
  Cc: Tony Lindgren, Steve Sakoman, linux-omap, linux-arm-kernel,
	Steve Sakoman

On 02/24/12 06:11, Rajendra Nayak wrote:
> On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
>> * Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
>>>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>>>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>>>> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>       {
>>>>           .mmc        = 1,
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>> -        .gpio_cd    = -EINVAL,
>>>> +        .gpio_cd    = OMAP_MAX_GPIO_LINES + 0,
>>>>           .gpio_wp    = -EINVAL,
>>
>> I don't have these changes, in my second revision of the patch.
>>
>> It's best not to hardcode the values here.
> 
> Ok, I just though doing it the other way is more round about
> hardcoding where in the board passes a hardcoded value to
> twl4030 gpio driver and the driver passes the *same* hardcoded
> value back to the board callback, which is then populated in
> mmc pdata. The board could as well directly hardcode it in the
> mmc pdata.
> That makes it much more readable than this round about
> hardcoding.
> But I'll go back to the old way if you think thats how we should
> handle this.

The "old" way is preferable. Thanks.

> 
>>
>>>> -
>>>> +        .deferred    = true,
>>>>       },
>>>>       {
>>>>           .mmc        = 2,
>>>> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>           .gpio_cd    = -EINVAL,
>>>>           .gpio_wp    = -EINVAL,
>>>>           .ocr_mask    = 0x00100000,    /* 3.3V */
>>>> +        .deferred    = true,
>>>
>>> Why do you defer this one?
>>> It does not use external GPIO chip, in fact it does not use CD/WP at all.
>>
>> Why do you have the following then to set gpio_cd?
> 
> There is only one instance of gpio_cd being populated for the
> first element in the array mmc[], which is already deferred.
> 
>>>> -    mmc[0].gpio_cd = gpio + 0;
> 
> Igor was asking about the second element in the array which never
> has gpio_cd populated. Its just initialized to -EINVAL and stays
> that way.

Exactly.

> 
>>
>>>>       },
>>>>       {}    /* Terminator */
>>>>   };
>>>> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>>>           pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>>>>       }
>>>>
>>>> -    /* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>> -    mmc[0].gpio_cd = gpio + 0;
>>>> -    omap2_hsmmc_init(mmc);
>>>> +    omap_hsmmc_deferred_add(mmc);
>>>>
>>>>       return 0;
>>>>   }
>>
>> Hmm I don't have omap_hsmmc_deferred_add() in my second version
>> of the patch either.
>>
>> Rajendra, please do the patches on that, now it's impossible to
>> see what else you've changed. That's the version posted here:
>>
>> http://www.spinics.net/lists/linux-omap/msg64884.html
> 
> Sorry for the mess up. I will make sure I have taken all changes/fixes
> from your reposts.
> 
> regards,
> Rajendra
>>
>>>> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>>>>       omap_serial_init();
>>>>       omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>>>>                    mt46h32m32lf6_sdrc_params);
>>>> +    omap_hsmmc_init(mmc);
>>>>       cm_t35_init_i2c();
>>>>       omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>>>>       cm_t35_init_ethernet();
>>>
>>> Other then the comment above, looks fine.
>>> I will probably be able to test this on Sunday.
>>
>> OK
>>
>>>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>>>> index a59ace0..11a6aa4 100644
>>>> --- a/arch/arm/mach-omap2/board-igep0020.c
>>>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>>>> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>       {
>>>>           .mmc        = 1,
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>> -        .gpio_cd    = -EINVAL,
>>>> +        .gpio_cd    = OMAP_MAX_GPIO_LINES + 0,
>>>>           .gpio_wp    = -EINVAL,
>>>> +        .deferred    = true,
>>>>       },
>>>>   #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>>>>       {
>>>> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>>           .gpio_cd    = -EINVAL,
>>>>           .gpio_wp    = -EINVAL,
>>>> +        .deferred    = true,
>>>
>>> same here, why defer it?
>>
>> Because it too sets gpio_cd in the callback.

Well, not this array element...

>>
>>> ditto
>>
>> ditto, that too sets gpio_cd..

Nope... ditto ;)

>>
>>>>       },
>>>>   #endif
>>>>       {}    /* Terminator */
>>>> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>>>>   {
>>>>       int r, lcd_bl_en;
>>>>
>>>> -    /* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>>       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
>>>> -    mmc[0].gpio_cd = gpio + 0;
>>
>> ..here. Same for the others. So maybe check is some are wrong?

I failed parsing the question...
Here only the first array element gets the gpio_cd value set.


-- 
Regards,
Igor.

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-24  7:01           ` Igor Grinberg
  0 siblings, 0 replies; 46+ messages in thread
From: Igor Grinberg @ 2012-02-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/24/12 06:11, Rajendra Nayak wrote:
> On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
>> * Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
>>>> --- a/arch/arm/mach-omap2/board-cm-t35.c
>>>> +++ b/arch/arm/mach-omap2/board-cm-t35.c
>>>> @@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>       {
>>>>           .mmc        = 1,
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>> -        .gpio_cd    = -EINVAL,
>>>> +        .gpio_cd    = OMAP_MAX_GPIO_LINES + 0,
>>>>           .gpio_wp    = -EINVAL,
>>
>> I don't have these changes, in my second revision of the patch.
>>
>> It's best not to hardcode the values here.
> 
> Ok, I just though doing it the other way is more round about
> hardcoding where in the board passes a hardcoded value to
> twl4030 gpio driver and the driver passes the *same* hardcoded
> value back to the board callback, which is then populated in
> mmc pdata. The board could as well directly hardcode it in the
> mmc pdata.
> That makes it much more readable than this round about
> hardcoding.
> But I'll go back to the old way if you think thats how we should
> handle this.

The "old" way is preferable. Thanks.

> 
>>
>>>> -
>>>> +        .deferred    = true,
>>>>       },
>>>>       {
>>>>           .mmc        = 2,
>>>> @@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>           .gpio_cd    = -EINVAL,
>>>>           .gpio_wp    = -EINVAL,
>>>>           .ocr_mask    = 0x00100000,    /* 3.3V */
>>>> +        .deferred    = true,
>>>
>>> Why do you defer this one?
>>> It does not use external GPIO chip, in fact it does not use CD/WP at all.
>>
>> Why do you have the following then to set gpio_cd?
> 
> There is only one instance of gpio_cd being populated for the
> first element in the array mmc[], which is already deferred.
> 
>>>> -    mmc[0].gpio_cd = gpio + 0;
> 
> Igor was asking about the second element in the array which never
> has gpio_cd populated. Its just initialized to -EINVAL and stays
> that way.

Exactly.

> 
>>
>>>>       },
>>>>       {}    /* Terminator */
>>>>   };
>>>> @@ -469,9 +470,7 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
>>>>           pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
>>>>       }
>>>>
>>>> -    /* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>> -    mmc[0].gpio_cd = gpio + 0;
>>>> -    omap2_hsmmc_init(mmc);
>>>> +    omap_hsmmc_deferred_add(mmc);
>>>>
>>>>       return 0;
>>>>   }
>>
>> Hmm I don't have omap_hsmmc_deferred_add() in my second version
>> of the patch either.
>>
>> Rajendra, please do the patches on that, now it's impossible to
>> see what else you've changed. That's the version posted here:
>>
>> http://www.spinics.net/lists/linux-omap/msg64884.html
> 
> Sorry for the mess up. I will make sure I have taken all changes/fixes
> from your reposts.
> 
> regards,
> Rajendra
>>
>>>> @@ -639,6 +638,7 @@ static void __init cm_t3x_common_init(void)
>>>>       omap_serial_init();
>>>>       omap_sdrc_init(mt46h32m32lf6_sdrc_params,
>>>>                    mt46h32m32lf6_sdrc_params);
>>>> +    omap_hsmmc_init(mmc);
>>>>       cm_t35_init_i2c();
>>>>       omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
>>>>       cm_t35_init_ethernet();
>>>
>>> Other then the comment above, looks fine.
>>> I will probably be able to test this on Sunday.
>>
>> OK
>>
>>>> diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
>>>> index a59ace0..11a6aa4 100644
>>>> --- a/arch/arm/mach-omap2/board-igep0020.c
>>>> +++ b/arch/arm/mach-omap2/board-igep0020.c
>>>> @@ -293,8 +293,9 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>       {
>>>>           .mmc        = 1,
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>> -        .gpio_cd    = -EINVAL,
>>>> +        .gpio_cd    = OMAP_MAX_GPIO_LINES + 0,
>>>>           .gpio_wp    = -EINVAL,
>>>> +        .deferred    = true,
>>>>       },
>>>>   #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
>>>>       {
>>>> @@ -302,6 +303,7 @@ static struct omap2_hsmmc_info mmc[] = {
>>>>           .caps        = MMC_CAP_4_BIT_DATA,
>>>>           .gpio_cd    = -EINVAL,
>>>>           .gpio_wp    = -EINVAL,
>>>> +        .deferred    = true,
>>>
>>> same here, why defer it?
>>
>> Because it too sets gpio_cd in the callback.

Well, not this array element...

>>
>>> ditto
>>
>> ditto, that too sets gpio_cd..

Nope... ditto ;)

>>
>>>>       },
>>>>   #endif
>>>>       {}    /* Terminator */
>>>> @@ -360,10 +362,8 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
>>>>   {
>>>>       int r, lcd_bl_en;
>>>>
>>>> -    /* gpio + 0 is "mmc0_cd" (input/IRQ) */
>>>>       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
>>>> -    mmc[0].gpio_cd = gpio + 0;
>>
>> ..here. Same for the others. So maybe check is some are wrong?

I failed parsing the question...
Here only the first array element gets the gpio_cd value set.


-- 
Regards,
Igor.

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

* Re: [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
  2012-02-24  4:11         ` Rajendra Nayak
@ 2012-02-24 22:19           ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-24 22:19 UTC (permalink / raw)
  To: Rajendra Nayak
  Cc: Igor Grinberg, linux-omap, linux-arm-kernel, Steve Sakoman,
	Steve Sakoman

* Rajendra Nayak <rnayak@ti.com> [120223 19:39]:
> On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
> >* Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
> >>>--- a/arch/arm/mach-omap2/board-cm-t35.c
> >>>+++ b/arch/arm/mach-omap2/board-cm-t35.c
> >>>@@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >>>  	{
> >>>  		.mmc		= 1,
> >>>  		.caps		= MMC_CAP_4_BIT_DATA,
> >>>-		.gpio_cd	= -EINVAL,
> >>>+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >>>  		.gpio_wp	= -EINVAL,
> >
> >I don't have these changes, in my second revision of the patch.
> >
> >It's best not to hardcode the values here.
> 
> Ok, I just though doing it the other way is more round about
> hardcoding where in the board passes a hardcoded value to
> twl4030 gpio driver and the driver passes the *same* hardcoded
> value back to the board callback, which is then populated in
> mmc pdata. The board could as well directly hardcode it in the
> mmc pdata. That makes it much more readable than this round about
> hardcoding.
> But I'll go back to the old way if you think thats how we should
> handle this.

Yes let's not change it, or if we need to change it, let's do
it in a separate patch.
 
> >
> >>>-
> >>>+		.deferred	= true,
> >>>  	},
> >>>  	{
> >>>  		.mmc		= 2,
> >>>@@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >>>  		.gpio_cd	= -EINVAL,
> >>>  		.gpio_wp	= -EINVAL,
> >>>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> >>>+		.deferred	= true,
> >>
> >>Why do you defer this one?
> >>It does not use external GPIO chip, in fact it does not use CD/WP at all.
> >
> >Why do you have the following then to set gpio_cd?
> 
> There is only one instance of gpio_cd being populated for the
> first element in the array mmc[], which is already deferred.
> 
> >>> -	mmc[0].gpio_cd = gpio + 0;
> 
> Igor was asking about the second element in the array which never
> has gpio_cd populated. Its just initialized to -EINVAL and stays
> that way.

Ah OK, sorry I forgot about that..
 
> Sorry for the mess up. I will make sure I have taken all changes/fixes
> from your reposts.

No problem, thanks.

Tony

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

* [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins
@ 2012-02-24 22:19           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-02-24 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

* Rajendra Nayak <rnayak@ti.com> [120223 19:39]:
> On Friday 24 February 2012 12:17 AM, Tony Lindgren wrote:
> >* Igor Grinberg<grinberg@compulab.co.il>  [120223 05:56]:
> >>>--- a/arch/arm/mach-omap2/board-cm-t35.c
> >>>+++ b/arch/arm/mach-omap2/board-cm-t35.c
> >>>@@ -411,9 +411,9 @@ static struct omap2_hsmmc_info mmc[] = {
> >>>  	{
> >>>  		.mmc		= 1,
> >>>  		.caps		= MMC_CAP_4_BIT_DATA,
> >>>-		.gpio_cd	= -EINVAL,
> >>>+		.gpio_cd	= OMAP_MAX_GPIO_LINES + 0,
> >>>  		.gpio_wp	= -EINVAL,
> >
> >I don't have these changes, in my second revision of the patch.
> >
> >It's best not to hardcode the values here.
> 
> Ok, I just though doing it the other way is more round about
> hardcoding where in the board passes a hardcoded value to
> twl4030 gpio driver and the driver passes the *same* hardcoded
> value back to the board callback, which is then populated in
> mmc pdata. The board could as well directly hardcode it in the
> mmc pdata. That makes it much more readable than this round about
> hardcoding.
> But I'll go back to the old way if you think thats how we should
> handle this.

Yes let's not change it, or if we need to change it, let's do
it in a separate patch.
 
> >
> >>>-
> >>>+		.deferred	= true,
> >>>  	},
> >>>  	{
> >>>  		.mmc		= 2,
> >>>@@ -422,6 +422,7 @@ static struct omap2_hsmmc_info mmc[] = {
> >>>  		.gpio_cd	= -EINVAL,
> >>>  		.gpio_wp	= -EINVAL,
> >>>  		.ocr_mask	= 0x00100000,	/* 3.3V */
> >>>+		.deferred	= true,
> >>
> >>Why do you defer this one?
> >>It does not use external GPIO chip, in fact it does not use CD/WP at all.
> >
> >Why do you have the following then to set gpio_cd?
> 
> There is only one instance of gpio_cd being populated for the
> first element in the array mmc[], which is already deferred.
> 
> >>> -	mmc[0].gpio_cd = gpio + 0;
> 
> Igor was asking about the second element in the array which never
> has gpio_cd populated. Its just initialized to -EINVAL and stays
> that way.

Ah OK, sorry I forgot about that..
 
> Sorry for the mess up. I will make sure I have taken all changes/fixes
> from your reposts.

No problem, thanks.

Tony

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

* Re: [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-02-23 11:40   ` Rajendra Nayak
@ 2012-03-19  9:08     ` Tomi Valkeinen
  -1 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-19  9:08 UTC (permalink / raw)
  To: Rajendra Nayak, tony; +Cc: linux-omap, linux-arm-kernel, Russell King

[-- Attachment #1: Type: text/plain, Size: 826 bytes --]

Hi,

On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> From: Tony Lindgren <tony@atomide.com>
> 
> Now that omap hsmmc init is split into two functions, it's safe
> to mark omap_hsmmc_init and omap_mux related functions to __init.
> 
> This basically reverts the following fixes for the case where
> TWL was compiled as a module:
> 
> a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> 
> Additionally it fixes up the remaining section warnings for
> all callers of omap_mux functions.

I only now noticed this patch. This breaks DSI, as the DSI muxing
functions are used during runtime and cannot be marked as __init.

Shall I make a new patch for dss tree that fixes this?

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-03-19  9:08     ` Tomi Valkeinen
  0 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-19  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> From: Tony Lindgren <tony@atomide.com>
> 
> Now that omap hsmmc init is split into two functions, it's safe
> to mark omap_hsmmc_init and omap_mux related functions to __init.
> 
> This basically reverts the following fixes for the case where
> TWL was compiled as a module:
> 
> a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> 
> Additionally it fixes up the remaining section warnings for
> all callers of omap_mux functions.

I only now noticed this patch. This breaks DSI, as the DSI muxing
functions are used during runtime and cannot be marked as __init.

Shall I make a new patch for dss tree that fixes this?

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120319/b22db85d/attachment.sig>

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

* Re: [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-03-19  9:08     ` Tomi Valkeinen
@ 2012-03-19 10:20       ` Tomi Valkeinen
  -1 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-19 10:20 UTC (permalink / raw)
  To: Rajendra Nayak, tony; +Cc: linux-omap, linux-arm-kernel, Russell King

[-- Attachment #1: Type: text/plain, Size: 2945 bytes --]

On Mon, 2012-03-19 at 11:08 +0200, Tomi Valkeinen wrote:
> Hi,
> 
> On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> > From: Tony Lindgren <tony@atomide.com>
> > 
> > Now that omap hsmmc init is split into two functions, it's safe
> > to mark omap_hsmmc_init and omap_mux related functions to __init.
> > 
> > This basically reverts the following fixes for the case where
> > TWL was compiled as a module:
> > 
> > a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> > 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> > 
> > Additionally it fixes up the remaining section warnings for
> > all callers of omap_mux functions.
> 
> I only now noticed this patch. This breaks DSI, as the DSI muxing
> functions are used during runtime and cannot be marked as __init.
> 
> Shall I make a new patch for dss tree that fixes this?

(too little coffee)

Obviously I can't make a fix in my tree for that, as the problematic
patch is not present there... So here's a patch to fix it, based on
arm-soc/for-next



From b00c2464de51ba6f297371b08bb7745c528fde59 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Mon, 19 Mar 2012 11:08:54 +0200
Subject: [PATCH] ARM: OMAP2+: Remove __init from DSI mux functions

Commit d1589f0912533e6cb2ac8fd6f1feb3d5989fe8cb (ARM: OMAP2+: Mark
omap_hsmmc_init and omap_mux related functions as __init) changed DSI
muxing functions to __init. This doesn't work, as the muxing functions
are used every time a DSI display is enabled or disabled.

This patch removes the __inits from DSI mux functions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/display.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/display.c
b/arch/arm/mach-omap2/display.c
index 9706c64..400fa37 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -125,7 +125,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags
flags)
 	}
 }
 
-static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -166,7 +166,7 @@ int __init omap_hdmi_init(enum omap_hdmi_flags
flags)
 	return 0;
 }
 
-static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -174,7 +174,7 @@ static int __init omap_dsi_enable_pads(int dsi_id,
unsigned lane_mask)
 	return 0;
 }
 
-static void __init omap_dsi_disable_pads(int dsi_id, unsigned
lane_mask)
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);
-- 
1.7.4.1



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-03-19 10:20       ` Tomi Valkeinen
  0 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-19 10:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-03-19 at 11:08 +0200, Tomi Valkeinen wrote:
> Hi,
> 
> On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> > From: Tony Lindgren <tony@atomide.com>
> > 
> > Now that omap hsmmc init is split into two functions, it's safe
> > to mark omap_hsmmc_init and omap_mux related functions to __init.
> > 
> > This basically reverts the following fixes for the case where
> > TWL was compiled as a module:
> > 
> > a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> > 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> > 
> > Additionally it fixes up the remaining section warnings for
> > all callers of omap_mux functions.
> 
> I only now noticed this patch. This breaks DSI, as the DSI muxing
> functions are used during runtime and cannot be marked as __init.
> 
> Shall I make a new patch for dss tree that fixes this?

(too little coffee)

Obviously I can't make a fix in my tree for that, as the problematic
patch is not present there... So here's a patch to fix it, based on
arm-soc/for-next



>From b00c2464de51ba6f297371b08bb7745c528fde59 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Mon, 19 Mar 2012 11:08:54 +0200
Subject: [PATCH] ARM: OMAP2+: Remove __init from DSI mux functions

Commit d1589f0912533e6cb2ac8fd6f1feb3d5989fe8cb (ARM: OMAP2+: Mark
omap_hsmmc_init and omap_mux related functions as __init) changed DSI
muxing functions to __init. This doesn't work, as the muxing functions
are used every time a DSI display is enabled or disabled.

This patch removes the __inits from DSI mux functions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/display.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/display.c
b/arch/arm/mach-omap2/display.c
index 9706c64..400fa37 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -125,7 +125,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags
flags)
 	}
 }
 
-static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -166,7 +166,7 @@ int __init omap_hdmi_init(enum omap_hdmi_flags
flags)
 	return 0;
 }
 
-static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -174,7 +174,7 @@ static int __init omap_dsi_enable_pads(int dsi_id,
unsigned lane_mask)
 	return 0;
 }
 
-static void __init omap_dsi_disable_pads(int dsi_id, unsigned
lane_mask)
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);
-- 
1.7.4.1


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120319/7bcea6e1/attachment.sig>

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

* Re: [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-03-19 10:20       ` Tomi Valkeinen
@ 2012-03-19 18:09         ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-03-19 18:09 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Rajendra Nayak, linux-omap, linux-arm-kernel, Russell King

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120319 03:23]:
> On Mon, 2012-03-19 at 11:08 +0200, Tomi Valkeinen wrote:
> > Hi,
> > 
> > On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> > > From: Tony Lindgren <tony@atomide.com>
> > > 
> > > Now that omap hsmmc init is split into two functions, it's safe
> > > to mark omap_hsmmc_init and omap_mux related functions to __init.
> > > 
> > > This basically reverts the following fixes for the case where
> > > TWL was compiled as a module:
> > > 
> > > a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> > > 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> > > 
> > > Additionally it fixes up the remaining section warnings for
> > > all callers of omap_mux functions.
> > 
> > I only now noticed this patch. This breaks DSI, as the DSI muxing
> > functions are used during runtime and cannot be marked as __init.
> > 
> > Shall I make a new patch for dss tree that fixes this?
> 
> (too little coffee)
> 
> Obviously I can't make a fix in my tree for that, as the problematic
> patch is not present there... So here's a patch to fix it, based on
> arm-soc/for-next

Thanks yeah those are not even using omap_mux_init* functions, so I
must have accidentally converted blindly those while fixing up the
omap_mux_init* calling functions, sorry.

Looks like only omap4_hdmi_mux_pads needs to be __init as it's
calling omap_mux_init_signal.

It gets called from omap_hdmi_init, and omap_hdmi_init and it's callers
are already marked __init. The reason it's not producing a section
warning is probably because it gets inlined.

I've updated your patch a bit for the comments a bit and marked
omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
below.

Regards,

Tony


From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Mon, 19 Mar 2012 11:08:54 +0200
Subject: [PATCH] ARM: OMAP2+: Remove __init from DSI mux functions

Commit d1589f0912533e6cb2ac8fd6f1feb3d5989fe8cb (ARM: OMAP2+: Mark
omap_hsmmc_init and omap_mux related functions as __init) changed DSI
muxing functions to __init. This doesn't work, as the muxing functions
are used every time a DSI display is enabled or disabled.

This patch removes the __inits from DSI mux functions that were
accidentally marked as __init, and makes omap4_hdmi_mux_pads __init
like it should be.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
[tony@atomide.com: update comments, mark omap4_hdmi_mux_pads __init]
Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -99,7 +99,7 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
-static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
+static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 {
 	u32 reg;
 	u16 control_i2c_1;
@@ -125,7 +125,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 	}
 }
 
-static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -166,7 +166,7 @@ int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 	return 0;
 }
 
-static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -174,7 +174,7 @@ static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 	return 0;
 }
 
-static void __init omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-03-19 18:09         ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-03-19 18:09 UTC (permalink / raw)
  To: linux-arm-kernel

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120319 03:23]:
> On Mon, 2012-03-19 at 11:08 +0200, Tomi Valkeinen wrote:
> > Hi,
> > 
> > On Thu, 2012-02-23 at 17:10 +0530, Rajendra Nayak wrote:
> > > From: Tony Lindgren <tony@atomide.com>
> > > 
> > > Now that omap hsmmc init is split into two functions, it's safe
> > > to mark omap_hsmmc_init and omap_mux related functions to __init.
> > > 
> > > This basically reverts the following fixes for the case where
> > > TWL was compiled as a module:
> > > 
> > > a98f77b (ARM: omap: fix section mismatch warning for sdp3430_twl_gpio_setup())
> > > 8930b4e (ARM: omap: fix section mismatch warnings in mux.c caused by hsmmc.c)
> > > 
> > > Additionally it fixes up the remaining section warnings for
> > > all callers of omap_mux functions.
> > 
> > I only now noticed this patch. This breaks DSI, as the DSI muxing
> > functions are used during runtime and cannot be marked as __init.
> > 
> > Shall I make a new patch for dss tree that fixes this?
> 
> (too little coffee)
> 
> Obviously I can't make a fix in my tree for that, as the problematic
> patch is not present there... So here's a patch to fix it, based on
> arm-soc/for-next

Thanks yeah those are not even using omap_mux_init* functions, so I
must have accidentally converted blindly those while fixing up the
omap_mux_init* calling functions, sorry.

Looks like only omap4_hdmi_mux_pads needs to be __init as it's
calling omap_mux_init_signal.

It gets called from omap_hdmi_init, and omap_hdmi_init and it's callers
are already marked __init. The reason it's not producing a section
warning is probably because it gets inlined.

I've updated your patch a bit for the comments a bit and marked
omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
below.

Regards,

Tony


From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Mon, 19 Mar 2012 11:08:54 +0200
Subject: [PATCH] ARM: OMAP2+: Remove __init from DSI mux functions

Commit d1589f0912533e6cb2ac8fd6f1feb3d5989fe8cb (ARM: OMAP2+: Mark
omap_hsmmc_init and omap_mux related functions as __init) changed DSI
muxing functions to __init. This doesn't work, as the muxing functions
are used every time a DSI display is enabled or disabled.

This patch removes the __inits from DSI mux functions that were
accidentally marked as __init, and makes omap4_hdmi_mux_pads __init
like it should be.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
[tony at atomide.com: update comments, mark omap4_hdmi_mux_pads __init]
Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -99,7 +99,7 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
-static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
+static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 {
 	u32 reg;
 	u16 control_i2c_1;
@@ -125,7 +125,7 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
 	}
 }
 
-static int __init omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 {
 	u32 enable_mask, enable_shift;
 	u32 pipd_mask, pipd_shift;
@@ -166,7 +166,7 @@ int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 	return 0;
 }
 
-static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		return omap4_dsi_mux_pads(dsi_id, lane_mask);
@@ -174,7 +174,7 @@ static int __init omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 	return 0;
 }
 
-static void __init omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
 	if (cpu_is_omap44xx())
 		omap4_dsi_mux_pads(dsi_id, 0);

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

* Re: [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-03-19 18:09         ` Tony Lindgren
@ 2012-03-20  7:30           ` Tomi Valkeinen
  -1 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-20  7:30 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Rajendra Nayak, linux-omap, linux-arm-kernel, Russell King

[-- Attachment #1: Type: text/plain, Size: 663 bytes --]

On Mon, 2012-03-19 at 11:09 -0700, Tony Lindgren wrote:

> I've updated your patch a bit for the comments a bit and marked
> omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
> below.

Hmm, is there something funny with these init changes now...

Initially the situation was that there were no __inits in display.c's
mux functions. Then "Mark omap_hsmmc_init..." patch added __inits to all
of them. My patch removed the __inits from dsi functions, but left them
to hdmi functions.

But now you modified my patch to add the __inits to hdmi functions.
Which should already have them from the "Mark omap_hsmmc_init..." patch.

 Tomi

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-03-20  7:30           ` Tomi Valkeinen
  0 siblings, 0 replies; 46+ messages in thread
From: Tomi Valkeinen @ 2012-03-20  7:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-03-19 at 11:09 -0700, Tony Lindgren wrote:

> I've updated your patch a bit for the comments a bit and marked
> omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
> below.

Hmm, is there something funny with these init changes now...

Initially the situation was that there were no __inits in display.c's
mux functions. Then "Mark omap_hsmmc_init..." patch added __inits to all
of them. My patch removed the __inits from dsi functions, but left them
to hdmi functions.

But now you modified my patch to add the __inits to hdmi functions.
Which should already have them from the "Mark omap_hsmmc_init..." patch.

 Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120320/9ca92661/attachment.sig>

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

* Re: [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
  2012-03-20  7:30           ` Tomi Valkeinen
@ 2012-03-20 22:17             ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-03-20 22:17 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Rajendra Nayak, linux-omap, linux-arm-kernel, Russell King

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120320 00:41]:
> On Mon, 2012-03-19 at 11:09 -0700, Tony Lindgren wrote:
> 
> > I've updated your patch a bit for the comments a bit and marked
> > omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
> > below.
> 
> Hmm, is there something funny with these init changes now...
> 
> Initially the situation was that there were no __inits in display.c's
> mux functions. Then "Mark omap_hsmmc_init..." patch added __inits to all
> of them. My patch removed the __inits from dsi functions, but left them
> to hdmi functions.
> 
> But now you modified my patch to add the __inits to hdmi functions.
> Which should already have them from the "Mark omap_hsmmc_init..." patch.

Looks like the original patch missed making omap4_hdmi_mux_pads __init
though. I'm just changing omap4_hdmi_mux_pads to make it __init like
it should be.

Regards,

Tony

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

* [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init
@ 2012-03-20 22:17             ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-03-20 22:17 UTC (permalink / raw)
  To: linux-arm-kernel

* Tomi Valkeinen <tomi.valkeinen@ti.com> [120320 00:41]:
> On Mon, 2012-03-19 at 11:09 -0700, Tony Lindgren wrote:
> 
> > I've updated your patch a bit for the comments a bit and marked
> > omap4_hdmi_mux_pads as __init, will apply to fixes. Updated patch
> > below.
> 
> Hmm, is there something funny with these init changes now...
> 
> Initially the situation was that there were no __inits in display.c's
> mux functions. Then "Mark omap_hsmmc_init..." patch added __inits to all
> of them. My patch removed the __inits from dsi functions, but left them
> to hdmi functions.
> 
> But now you modified my patch to add the __inits to hdmi functions.
> Which should already have them from the "Mark omap_hsmmc_init..." patch.

Looks like the original patch missed making omap4_hdmi_mux_pads __init
though. I'm just changing omap4_hdmi_mux_pads to make it __init like
it should be.

Regards,

Tony

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

end of thread, other threads:[~2012-03-20 22:17 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-23 11:40 [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window Rajendra Nayak
2012-02-23 11:40 ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 1/7] ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register} Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 2/7] ARM: OMAP: omap_device: Add omap_device_unregister() Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 3/7] mmc: omap_hsmmc: Make the driver support hotpluggable devices Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 4/7] mmc: omap_hsmmc: If probe fails, give our error messages Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 5/7] ARM: OMAP2+: Split omap2_hsmmc_init() to properly support I2C GPIO pins Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 14:28   ` Igor Grinberg
2012-02-23 14:28     ` Igor Grinberg
2012-02-23 18:47     ` Tony Lindgren
2012-02-23 18:47       ` Tony Lindgren
2012-02-24  4:11       ` Rajendra Nayak
2012-02-24  4:11         ` Rajendra Nayak
2012-02-24  7:01         ` Igor Grinberg
2012-02-24  7:01           ` Igor Grinberg
2012-02-24 22:19         ` Tony Lindgren
2012-02-24 22:19           ` Tony Lindgren
2012-02-24  3:24     ` Rajendra Nayak
2012-02-24  3:24       ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 6/7] ARM: OMAP3: Use .teardown of twl4030-gpio to clean board requests Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-02-23 14:55   ` Igor Grinberg
2012-02-23 14:55     ` Igor Grinberg
2012-02-24  3:43     ` Rajendra Nayak
2012-02-24  3:43       ` Rajendra Nayak
2012-02-23 11:40 ` [PATCH v2 7/7] ARM: OMAP2+: Mark omap_hsmmc_init and omap_mux related functions as __init Rajendra Nayak
2012-02-23 11:40   ` Rajendra Nayak
2012-03-19  9:08   ` Tomi Valkeinen
2012-03-19  9:08     ` Tomi Valkeinen
2012-03-19 10:20     ` Tomi Valkeinen
2012-03-19 10:20       ` Tomi Valkeinen
2012-03-19 18:09       ` Tony Lindgren
2012-03-19 18:09         ` Tony Lindgren
2012-03-20  7:30         ` Tomi Valkeinen
2012-03-20  7:30           ` Tomi Valkeinen
2012-03-20 22:17           ` Tony Lindgren
2012-03-20 22:17             ` Tony Lindgren
2012-02-23 18:52 ` [PATCH v2 0/7] omap hsmmc init cleanup and section warning fixes for v3.4 merge window Tony Lindgren
2012-02-23 18:52   ` Tony Lindgren
2012-02-24  4:14   ` Rajendra Nayak
2012-02-24  4:14     ` Rajendra Nayak

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.