All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/31] SDHCI and SDIO IRQ improvements
@ 2014-02-18 15:08 ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-18 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Anton Vorontsov, Barry Song, Ben Dooks, Chris Ball, linuxppc-dev,
	linux-tegra, Michal Simek, spear-devel, Stephen Warren,
	Thierry Reding, Thomas Gleixner, Viresh Kumar

The following patch series is targetted at two things - fixing the SDIO
interrupt handling, and fixing problems with the sdhci driver.

- the first two patches from Thomas Gleixner provide genirq support to
  allow us to fix the SDIO interrupt handling in a graceful manner.
- patch 3 adds support for avoiding the buggy sdio_irq thread - the
  problem is described in that commit.  Other solutions were explored,
  but this is the one which was settled on after discussions between
  Thomas, scheduler people and myself.
- patches 4 to 7 update sdhci to use a genirq to deal with the threaded
  part of the interrupts.
- patch 8 allows card interrupts to be received from a SDIO card while
  runtime suspended.  Without this patch, Wifi cards attached to a
  kernel with runtime PM support built in totally fail to work.  This
  allows them to work.  Tested in 4-bit mode.
- patches 9 onwards are cleanups and fixes to the sdhci code.

 drivers/mmc/core/sdio_irq.c        |  41 ++-
 drivers/mmc/host/sdhci-acpi.c      |   8 +
 drivers/mmc/host/sdhci-bcm-kona.c  |   4 +
 drivers/mmc/host/sdhci-bcm2835.c   |   4 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  13 +-
 drivers/mmc/host/sdhci-dove.c      |   4 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  82 ++---
 drivers/mmc/host/sdhci-esdhc.h     |   4 +-
 drivers/mmc/host/sdhci-of-arasan.c |   4 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  70 +++--
 drivers/mmc/host/sdhci-of-hlwd.c   |   4 +
 drivers/mmc/host/sdhci-pci.c       |   9 +-
 drivers/mmc/host/sdhci-pltfm.c     |   4 +
 drivers/mmc/host/sdhci-pxav2.c     |  14 +-
 drivers/mmc/host/sdhci-pxav3.c     |  13 +-
 drivers/mmc/host/sdhci-s3c.c       |  36 ++-
 drivers/mmc/host/sdhci-sirf.c      |   4 +
 drivers/mmc/host/sdhci-spear.c     |   5 +-
 drivers/mmc/host/sdhci-tegra.c     |  27 +-
 drivers/mmc/host/sdhci.c           | 606 ++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  20 +-
 include/linux/hardirq.h            |   1 +
 include/linux/interrupt.h          |   1 +
 include/linux/mmc/host.h           |   3 +
 include/linux/mmc/sdhci.h          |  14 +-
 kernel/irq/handle.c                |   4 +-
 kernel/irq/internals.h             |   1 +
 kernel/irq/manage.c                |  94 ++++--
 28 files changed, 608 insertions(+), 486 deletions(-)

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 00/31] SDHCI and SDIO IRQ improvements
@ 2014-02-18 15:08 ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-18 15:08 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Barry Song, spear-devel, Stephen Warren, Anton Vorontsov,
	Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra, Thomas Gleixner, linuxppc-dev

The following patch series is targetted at two things - fixing the SDIO
interrupt handling, and fixing problems with the sdhci driver.

- the first two patches from Thomas Gleixner provide genirq support to
  allow us to fix the SDIO interrupt handling in a graceful manner.
- patch 3 adds support for avoiding the buggy sdio_irq thread - the
  problem is described in that commit.  Other solutions were explored,
  but this is the one which was settled on after discussions between
  Thomas, scheduler people and myself.
- patches 4 to 7 update sdhci to use a genirq to deal with the threaded
  part of the interrupts.
- patch 8 allows card interrupts to be received from a SDIO card while
  runtime suspended.  Without this patch, Wifi cards attached to a
  kernel with runtime PM support built in totally fail to work.  This
  allows them to work.  Tested in 4-bit mode.
- patches 9 onwards are cleanups and fixes to the sdhci code.

 drivers/mmc/core/sdio_irq.c        |  41 ++-
 drivers/mmc/host/sdhci-acpi.c      |   8 +
 drivers/mmc/host/sdhci-bcm-kona.c  |   4 +
 drivers/mmc/host/sdhci-bcm2835.c   |   4 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  13 +-
 drivers/mmc/host/sdhci-dove.c      |   4 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  82 ++---
 drivers/mmc/host/sdhci-esdhc.h     |   4 +-
 drivers/mmc/host/sdhci-of-arasan.c |   4 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  70 +++--
 drivers/mmc/host/sdhci-of-hlwd.c   |   4 +
 drivers/mmc/host/sdhci-pci.c       |   9 +-
 drivers/mmc/host/sdhci-pltfm.c     |   4 +
 drivers/mmc/host/sdhci-pxav2.c     |  14 +-
 drivers/mmc/host/sdhci-pxav3.c     |  13 +-
 drivers/mmc/host/sdhci-s3c.c       |  36 ++-
 drivers/mmc/host/sdhci-sirf.c      |   4 +
 drivers/mmc/host/sdhci-spear.c     |   5 +-
 drivers/mmc/host/sdhci-tegra.c     |  27 +-
 drivers/mmc/host/sdhci.c           | 606 ++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  20 +-
 include/linux/hardirq.h            |   1 +
 include/linux/interrupt.h          |   1 +
 include/linux/mmc/host.h           |   3 +
 include/linux/mmc/sdhci.h          |  14 +-
 kernel/irq/handle.c                |   4 +-
 kernel/irq/internals.h             |   1 +
 kernel/irq/manage.c                |  94 ++++--
 28 files changed, 608 insertions(+), 486 deletions(-)

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 00/31] SDHCI and SDIO IRQ improvements
@ 2014-02-18 15:08 ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-18 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

The following patch series is targetted at two things - fixing the SDIO
interrupt handling, and fixing problems with the sdhci driver.

- the first two patches from Thomas Gleixner provide genirq support to
  allow us to fix the SDIO interrupt handling in a graceful manner.
- patch 3 adds support for avoiding the buggy sdio_irq thread - the
  problem is described in that commit.  Other solutions were explored,
  but this is the one which was settled on after discussions between
  Thomas, scheduler people and myself.
- patches 4 to 7 update sdhci to use a genirq to deal with the threaded
  part of the interrupts.
- patch 8 allows card interrupts to be received from a SDIO card while
  runtime suspended.  Without this patch, Wifi cards attached to a
  kernel with runtime PM support built in totally fail to work.  This
  allows them to work.  Tested in 4-bit mode.
- patches 9 onwards are cleanups and fixes to the sdhci code.

 drivers/mmc/core/sdio_irq.c        |  41 ++-
 drivers/mmc/host/sdhci-acpi.c      |   8 +
 drivers/mmc/host/sdhci-bcm-kona.c  |   4 +
 drivers/mmc/host/sdhci-bcm2835.c   |   4 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  13 +-
 drivers/mmc/host/sdhci-dove.c      |   4 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  82 ++---
 drivers/mmc/host/sdhci-esdhc.h     |   4 +-
 drivers/mmc/host/sdhci-of-arasan.c |   4 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  70 +++--
 drivers/mmc/host/sdhci-of-hlwd.c   |   4 +
 drivers/mmc/host/sdhci-pci.c       |   9 +-
 drivers/mmc/host/sdhci-pltfm.c     |   4 +
 drivers/mmc/host/sdhci-pxav2.c     |  14 +-
 drivers/mmc/host/sdhci-pxav3.c     |  13 +-
 drivers/mmc/host/sdhci-s3c.c       |  36 ++-
 drivers/mmc/host/sdhci-sirf.c      |   4 +
 drivers/mmc/host/sdhci-spear.c     |   5 +-
 drivers/mmc/host/sdhci-tegra.c     |  27 +-
 drivers/mmc/host/sdhci.c           | 606 ++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  20 +-
 include/linux/hardirq.h            |   1 +
 include/linux/interrupt.h          |   1 +
 include/linux/mmc/host.h           |   3 +
 include/linux/mmc/sdhci.h          |  14 +-
 kernel/irq/handle.c                |   4 +-
 kernel/irq/internals.h             |   1 +
 kernel/irq/manage.c                |  94 ++++--
 28 files changed, 608 insertions(+), 486 deletions(-)

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 01/31] genirq: Provide synchronize_hardirq()
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Thomas Gleixner

From: Thomas Gleixner <tglx@linutronix.de>

synchronize_irq() waits for hard irq and threaded handlers to complete
before returning. For some special cases we only need to make sure
that the hard interrupt part of the irq line is not in progress when
we disabled the - possibly shared - interrupt at the device level.

A proper use case for this was provided by Russell. The sdhci driver
requires some irq triggered functions to be run in thread context. The
current implementation of the thread context is a sdio private kthread
construct, which has quite some shortcomings. These can be avoided
when the thread is directly associated to the device interrupt via the
generic threaded irq infrastructure.

Though there is a corner case related to run time power management
where one side disables the device interrupts at the device level and
needs to make sure, that an already running hard interrupt handler has
completed before proceeding further. Though that hard interrupt
handler might wake the associated thread, which in turn can request
the runtime PM to reenable the device. Using synchronize_irq() leads
to an immediate deadlock of the irq thread waiting for the PM lock and
the synchronize_irq() waiting for the irq thread to complete.

Due to the fact that it is sufficient for this case to ensure that no
hard irq handler is executing a new function which avoids the check
for the thread is required.

Add a function, which just monitors the hard irq parts and ignores the
threaded handlers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 include/linux/hardirq.h |  1 +
 kernel/irq/manage.c     | 67 ++++++++++++++++++++++++++++++++++---------------
 2 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 12d5f972f23f..cba442ec3c66 100644
=-DO NOT APPLY-= a/include/linux/hardirq.h
=+DO NOT APPLY+= b/include/linux/hardirq.h
@@ -9,6 +9,7 @@
 
 
 extern void synchronize_irq(unsigned int irq);
=+DO NOT APPLY+=extern void synchronize_hardirq(unsigned int irq);
 
 #if defined(CONFIG_TINY_RCU)
 
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 481a13c43b17..67ac52d59fd3 100644
=-DO NOT APPLY-= a/kernel/irq/manage.c
=+DO NOT APPLY+= b/kernel/irq/manage.c
@@ -32,24 +32,10 @@ static int __init setup_forced_irqthreads(char *arg)
 early_param("threadirqs", setup_forced_irqthreads);
 #endif
 
-/**
- *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
- *	@irq: interrupt number to wait for
- *
- *	This function waits for any pending IRQ handlers for this interrupt
- *	to complete before returning. If you use this function while
- *	holding a resource the IRQ handler may need you will deadlock.
- *
- *	This function may be called - with care - from IRQ context.
- */
-void synchronize_irq(unsigned int irq)
=+DO NOT APPLY+=static void __synchronize_hardirq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	bool inprogress;
 
-	if (!desc)
-		return;
-
 	do {
 		unsigned long flags;
 
@@ -67,12 +53,53 @@ void synchronize_irq(unsigned int irq)
 
 		/* Oops, that failed? */
 	} while (inprogress);
=+DO NOT APPLY+=}
 
-	/*
-	 * We made sure that no hardirq handler is running. Now verify
-	 * that no threaded handlers are active.
-	 */
-	wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
=+DO NOT APPLY+= *	@irq: interrupt number to wait for
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function waits for any pending hard IRQ handlers for this
=+DO NOT APPLY+= *	interrupt to complete before returning. If you use this
=+DO NOT APPLY+= *	function while holding a resource the IRQ handler may need you
=+DO NOT APPLY+= *	will deadlock. It does not take associated threaded handlers into
=+DO NOT APPLY+= *	account.
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function may be called - with care - from IRQ context.
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void synchronize_hardirq(unsigned int irq)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (desc)
=+DO NOT APPLY+=		__synchronize_hardirq(desc);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL(synchronize_hardirq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
=+DO NOT APPLY+= *	@irq: interrupt number to wait for
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function waits for any pending IRQ handlers for this interrupt
=+DO NOT APPLY+= *	to complete before returning. If you use this function while
=+DO NOT APPLY+= *	holding a resource the IRQ handler may need you will deadlock.
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function may be called - with care - from IRQ context.
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void synchronize_irq(unsigned int irq)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (desc) {
=+DO NOT APPLY+=		__synchronize_hardirq(desc);
=+DO NOT APPLY+=		/*
=+DO NOT APPLY+=		 * We made sure that no hardirq handler is
=+DO NOT APPLY+=		 * running. Now verify that no threaded handlers are
=+DO NOT APPLY+=		 * active.
=+DO NOT APPLY+=		 */
=+DO NOT APPLY+=		wait_event(desc->wait_for_threads,
=+DO NOT APPLY+=			   !atomic_read(&desc->threads_active));
=+DO NOT APPLY+=	}
 }
 EXPORT_SYMBOL(synchronize_irq);
 
-- 
1.8.3.1


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

* [PATCH RFC 01/31] genirq: Provide synchronize_hardirq()
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Thomas Gleixner <tglx@linutronix.de>

synchronize_irq() waits for hard irq and threaded handlers to complete
before returning. For some special cases we only need to make sure
that the hard interrupt part of the irq line is not in progress when
we disabled the - possibly shared - interrupt at the device level.

A proper use case for this was provided by Russell. The sdhci driver
requires some irq triggered functions to be run in thread context. The
current implementation of the thread context is a sdio private kthread
construct, which has quite some shortcomings. These can be avoided
when the thread is directly associated to the device interrupt via the
generic threaded irq infrastructure.

Though there is a corner case related to run time power management
where one side disables the device interrupts at the device level and
needs to make sure, that an already running hard interrupt handler has
completed before proceeding further. Though that hard interrupt
handler might wake the associated thread, which in turn can request
the runtime PM to reenable the device. Using synchronize_irq() leads
to an immediate deadlock of the irq thread waiting for the PM lock and
the synchronize_irq() waiting for the irq thread to complete.

Due to the fact that it is sufficient for this case to ensure that no
hard irq handler is executing a new function which avoids the check
for the thread is required.

Add a function, which just monitors the hard irq parts and ignores the
threaded handlers.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 include/linux/hardirq.h |  1 +
 kernel/irq/manage.c     | 67 ++++++++++++++++++++++++++++++++++---------------
 2 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 12d5f972f23f..cba442ec3c66 100644
=-DO NOT APPLY-= a/include/linux/hardirq.h
=+DO NOT APPLY+= b/include/linux/hardirq.h
@@ -9,6 +9,7 @@
 
 
 extern void synchronize_irq(unsigned int irq);
=+DO NOT APPLY+=extern void synchronize_hardirq(unsigned int irq);
 
 #if defined(CONFIG_TINY_RCU)
 
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 481a13c43b17..67ac52d59fd3 100644
=-DO NOT APPLY-= a/kernel/irq/manage.c
=+DO NOT APPLY+= b/kernel/irq/manage.c
@@ -32,24 +32,10 @@ static int __init setup_forced_irqthreads(char *arg)
 early_param("threadirqs", setup_forced_irqthreads);
 #endif
 
-/**
- *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
- *	@irq: interrupt number to wait for
- *
- *	This function waits for any pending IRQ handlers for this interrupt
- *	to complete before returning. If you use this function while
- *	holding a resource the IRQ handler may need you will deadlock.
- *
- *	This function may be called - with care - from IRQ context.
- */
-void synchronize_irq(unsigned int irq)
=+DO NOT APPLY+=static void __synchronize_hardirq(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	bool inprogress;
 
-	if (!desc)
-		return;
-
 	do {
 		unsigned long flags;
 
@@ -67,12 +53,53 @@ void synchronize_irq(unsigned int irq)
 
 		/* Oops, that failed? */
 	} while (inprogress);
=+DO NOT APPLY+=}
 
-	/*
-	 * We made sure that no hardirq handler is running. Now verify
-	 * that no threaded handlers are active.
-	 */
-	wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
=+DO NOT APPLY+= *	@irq: interrupt number to wait for
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function waits for any pending hard IRQ handlers for this
=+DO NOT APPLY+= *	interrupt to complete before returning. If you use this
=+DO NOT APPLY+= *	function while holding a resource the IRQ handler may need you
=+DO NOT APPLY+= *	will deadlock. It does not take associated threaded handlers into
=+DO NOT APPLY+= *	account.
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function may be called - with care - from IRQ context.
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void synchronize_hardirq(unsigned int irq)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (desc)
=+DO NOT APPLY+=		__synchronize_hardirq(desc);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL(synchronize_hardirq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	synchronize_irq - wait for pending IRQ handlers (on other CPUs)
=+DO NOT APPLY+= *	@irq: interrupt number to wait for
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function waits for any pending IRQ handlers for this interrupt
=+DO NOT APPLY+= *	to complete before returning. If you use this function while
=+DO NOT APPLY+= *	holding a resource the IRQ handler may need you will deadlock.
=+DO NOT APPLY+= *
=+DO NOT APPLY+= *	This function may be called - with care - from IRQ context.
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void synchronize_irq(unsigned int irq)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (desc) {
=+DO NOT APPLY+=		__synchronize_hardirq(desc);
=+DO NOT APPLY+=		/*
=+DO NOT APPLY+=		 * We made sure that no hardirq handler is
=+DO NOT APPLY+=		 * running. Now verify that no threaded handlers are
=+DO NOT APPLY+=		 * active.
=+DO NOT APPLY+=		 */
=+DO NOT APPLY+=		wait_event(desc->wait_for_threads,
=+DO NOT APPLY+=			   !atomic_read(&desc->threads_active));
=+DO NOT APPLY+=	}
 }
 EXPORT_SYMBOL(synchronize_irq);
 
-- 
1.8.3.1

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

* [PATCH RFC 02/31] genirq: Provide irq_wake_thread()
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Thomas Gleixner

From: Thomas Gleixner <tglx@linutronix.de>

In course of the sdhci/sdio discussion with Russell about killing the
sdio kthread hackery we discovered the need to be able to wake an
interrupt thread from software.

The rationale for this is, that sdio hardware can lack proper
interrupt support for certain features. So the driver needs to poll
the status registers, but at the same time it needs to be woken up by
an hardware interrupt.

To be able to get rid of the home brewn kthread construct of sdio we
need a way to wake an irq thread independent of an actual hardware
interrupt.

Provide an irq_wake_thread() function which wakes up the thread which
is associated to a given dev_id. This allows sdio to invoke the irq
thread from the hardware irq handler via the IRQ_WAKE_THREAD return
value and provides a possibility to wake it via a timer for the
polling scenarios. That allows to simplify the sdio logic
significantly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 include/linux/interrupt.h |  1 +
 kernel/irq/handle.c       |  4 ++--
 kernel/irq/internals.h    |  1 +
 kernel/irq/manage.c       | 27 +++++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 0053adde0ed9..83c52e8b5221 100644
=-DO NOT APPLY-= a/include/linux/interrupt.h
=+DO NOT APPLY+= b/include/linux/interrupt.h
@@ -183,6 +183,7 @@ extern void disable_irq(unsigned int irq);
 extern void disable_percpu_irq(unsigned int irq);
 extern void enable_irq(unsigned int irq);
 extern void enable_percpu_irq(unsigned int irq, unsigned int type);
=+DO NOT APPLY+=extern void irq_wake_thread(unsigned int irq, void *dev_id);
 
 /* The following three functions are for the core kernel use only. */
 extern void suspend_device_irqs(void);
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 131ca176b497..bfec453557b4 100644
=-DO NOT APPLY-= a/kernel/irq/handle.c
=+DO NOT APPLY+= b/kernel/irq/handle.c
@@ -51,7 +51,7 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
 	       "but no thread function available.", irq, action->name);
 }
 
-static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
=+DO NOT APPLY+=void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
 {
 	/*
 	 * In case the thread crashed and was killed we just pretend that
@@ -157,7 +157,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
 				break;
 			}
 
-			irq_wake_thread(desc, action);
=+DO NOT APPLY+=			__irq_wake_thread(desc, action);
 
 			/* Fall through to add to randomness */
 		case IRQ_HANDLED:
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 001fa5bab490..d61ac29e32d0 100644
=-DO NOT APPLY-= a/kernel/irq/internals.h
=+DO NOT APPLY+= b/kernel/irq/internals.h
@@ -82,6 +82,7 @@ irqreturn_t handle_irq_event(struct irq_desc *desc);
 /* Resending of interrupts :*/
 void check_irq_resend(struct irq_desc *desc, unsigned int irq);
 bool irq_wait_for_poll(struct irq_desc *desc);
=+DO NOT APPLY+=void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action);
 
 #ifdef CONFIG_PROC_FS
 extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 67ac52d59fd3..5ce280a56905 100644
=-DO NOT APPLY-= a/kernel/irq/manage.c
=+DO NOT APPLY+= b/kernel/irq/manage.c
@@ -908,6 +908,33 @@ static int irq_thread(void *data)
 	return 0;
 }
 
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	irq_wake_thread - wake the irq thread for the action identified by dev_id
=+DO NOT APPLY+= *	@irq:		Interrupt line
=+DO NOT APPLY+= *	@dev_id:	Device identity for which the thread should be woken
=+DO NOT APPLY+= *
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void irq_wake_thread(unsigned int irq, void *dev_id)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=	struct irqaction *action;
=+DO NOT APPLY+=	unsigned long flags;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
=+DO NOT APPLY+=		return;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	raw_spin_lock_irqsave(&desc->lock, flags);
=+DO NOT APPLY+=	for (action = desc->action; action; action = action->next) {
=+DO NOT APPLY+=		if (action->dev_id == dev_id) {
=+DO NOT APPLY+=			if (action->thread)
=+DO NOT APPLY+=				__irq_wake_thread(desc, action);
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		}
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=	raw_spin_unlock_irqrestore(&desc->lock, flags);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(irq_wake_thread);
=+DO NOT APPLY+=
 static void irq_setup_forced_threading(struct irqaction *new)
 {
 	if (!force_irqthreads)
-- 
1.8.3.1


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

* [PATCH RFC 02/31] genirq: Provide irq_wake_thread()
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

From: Thomas Gleixner <tglx@linutronix.de>

In course of the sdhci/sdio discussion with Russell about killing the
sdio kthread hackery we discovered the need to be able to wake an
interrupt thread from software.

The rationale for this is, that sdio hardware can lack proper
interrupt support for certain features. So the driver needs to poll
the status registers, but at the same time it needs to be woken up by
an hardware interrupt.

To be able to get rid of the home brewn kthread construct of sdio we
need a way to wake an irq thread independent of an actual hardware
interrupt.

Provide an irq_wake_thread() function which wakes up the thread which
is associated to a given dev_id. This allows sdio to invoke the irq
thread from the hardware irq handler via the IRQ_WAKE_THREAD return
value and provides a possibility to wake it via a timer for the
polling scenarios. That allows to simplify the sdio logic
significantly.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 include/linux/interrupt.h |  1 +
 kernel/irq/handle.c       |  4 ++--
 kernel/irq/internals.h    |  1 +
 kernel/irq/manage.c       | 27 +++++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 0053adde0ed9..83c52e8b5221 100644
=-DO NOT APPLY-= a/include/linux/interrupt.h
=+DO NOT APPLY+= b/include/linux/interrupt.h
@@ -183,6 +183,7 @@ extern void disable_irq(unsigned int irq);
 extern void disable_percpu_irq(unsigned int irq);
 extern void enable_irq(unsigned int irq);
 extern void enable_percpu_irq(unsigned int irq, unsigned int type);
=+DO NOT APPLY+=extern void irq_wake_thread(unsigned int irq, void *dev_id);
 
 /* The following three functions are for the core kernel use only. */
 extern void suspend_device_irqs(void);
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 131ca176b497..bfec453557b4 100644
=-DO NOT APPLY-= a/kernel/irq/handle.c
=+DO NOT APPLY+= b/kernel/irq/handle.c
@@ -51,7 +51,7 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
 	       "but no thread function available.", irq, action->name);
 }
 
-static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
=+DO NOT APPLY+=void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
 {
 	/*
 	 * In case the thread crashed and was killed we just pretend that
@@ -157,7 +157,7 @@ handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
 				break;
 			}
 
-			irq_wake_thread(desc, action);
=+DO NOT APPLY+=			__irq_wake_thread(desc, action);
 
 			/* Fall through to add to randomness */
 		case IRQ_HANDLED:
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 001fa5bab490..d61ac29e32d0 100644
=-DO NOT APPLY-= a/kernel/irq/internals.h
=+DO NOT APPLY+= b/kernel/irq/internals.h
@@ -82,6 +82,7 @@ irqreturn_t handle_irq_event(struct irq_desc *desc);
 /* Resending of interrupts :*/
 void check_irq_resend(struct irq_desc *desc, unsigned int irq);
 bool irq_wait_for_poll(struct irq_desc *desc);
=+DO NOT APPLY+=void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action);
 
 #ifdef CONFIG_PROC_FS
 extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 67ac52d59fd3..5ce280a56905 100644
=-DO NOT APPLY-= a/kernel/irq/manage.c
=+DO NOT APPLY+= b/kernel/irq/manage.c
@@ -908,6 +908,33 @@ static int irq_thread(void *data)
 	return 0;
 }
 
=+DO NOT APPLY+=/**
=+DO NOT APPLY+= *	irq_wake_thread - wake the irq thread for the action identified by dev_id
=+DO NOT APPLY+= *	@irq:		Interrupt line
=+DO NOT APPLY+= *	@dev_id:	Device identity for which the thread should be woken
=+DO NOT APPLY+= *
=+DO NOT APPLY+= */
=+DO NOT APPLY+=void irq_wake_thread(unsigned int irq, void *dev_id)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct irq_desc *desc = irq_to_desc(irq);
=+DO NOT APPLY+=	struct irqaction *action;
=+DO NOT APPLY+=	unsigned long flags;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
=+DO NOT APPLY+=		return;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	raw_spin_lock_irqsave(&desc->lock, flags);
=+DO NOT APPLY+=	for (action = desc->action; action; action = action->next) {
=+DO NOT APPLY+=		if (action->dev_id == dev_id) {
=+DO NOT APPLY+=			if (action->thread)
=+DO NOT APPLY+=				__irq_wake_thread(desc, action);
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		}
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=	raw_spin_unlock_irqrestore(&desc->lock, flags);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(irq_wake_thread);
=+DO NOT APPLY+=
 static void irq_setup_forced_threading(struct irqaction *new)
 {
 	if (!force_irqthreads)
-- 
1.8.3.1

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

* [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Rather than the SDIO support spawning it's own thread for handling card
interrupts, use the generic IRQ infrastructure for this, triggering it
from the host interface's interrupt handling directly.

This avoids a race between the parent thread waiting to receive an
interrupt response from the card, and the slow startup from the sdio
irq thread, which can occur as a result of high system load (eg, while
udev is running.)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h    |  3 +++
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index aaa90460ed23..f23d73993dc6 100644
=-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
=+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
@@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
 	return ret;
 }
 
=+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	mmc_claim_host(host);
=+DO NOT APPLY+=	host->sdio_irq_pending = true;
=+DO NOT APPLY+=	process_sdio_pending_irqs(host);
=+DO NOT APPLY+=	mmc_release_host(host);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
=+DO NOT APPLY+=
 static int sdio_irq_thread(void *_host)
 {
 	struct mmc_host *host = _host;
@@ -189,14 +198,20 @@ static int sdio_card_irq_get(struct mmc_card *card)
 	WARN_ON(!host->claimed);
 
 	if (!host->sdio_irqs++) {
-		atomic_set(&host->sdio_irq_thread_abort, 0);
-		host->sdio_irq_thread =
-			kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
-				mmc_hostname(host));
-		if (IS_ERR(host->sdio_irq_thread)) {
-			int err = PTR_ERR(host->sdio_irq_thread);
-			host->sdio_irqs--;
-			return err;
=+DO NOT APPLY+=		if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
=+DO NOT APPLY+=			atomic_set(&host->sdio_irq_thread_abort, 0);
=+DO NOT APPLY+=			host->sdio_irq_thread =
=+DO NOT APPLY+=				kthread_run(sdio_irq_thread, host,
=+DO NOT APPLY+=					    "ksdioirqd/%s", mmc_hostname(host));
=+DO NOT APPLY+=			if (IS_ERR(host->sdio_irq_thread)) {
=+DO NOT APPLY+=				int err = PTR_ERR(host->sdio_irq_thread);
=+DO NOT APPLY+=				host->sdio_irqs--;
=+DO NOT APPLY+=				return err;
=+DO NOT APPLY+=			}
=+DO NOT APPLY+=		} else {
=+DO NOT APPLY+=			mmc_host_clk_hold(host);
=+DO NOT APPLY+=			host->ops->enable_sdio_irq(host, 1);
=+DO NOT APPLY+=			mmc_host_clk_release(host);
 		}
 	}
 
@@ -211,8 +226,14 @@ static int sdio_card_irq_put(struct mmc_card *card)
 	BUG_ON(host->sdio_irqs < 1);
 
 	if (!--host->sdio_irqs) {
-		atomic_set(&host->sdio_irq_thread_abort, 1);
-		kthread_stop(host->sdio_irq_thread);
=+DO NOT APPLY+=		if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
=+DO NOT APPLY+=			atomic_set(&host->sdio_irq_thread_abort, 1);
=+DO NOT APPLY+=			kthread_stop(host->sdio_irq_thread);
=+DO NOT APPLY+=		} else {
=+DO NOT APPLY+=			mmc_host_clk_hold(host);
=+DO NOT APPLY+=			host->ops->enable_sdio_irq(host, 0);
=+DO NOT APPLY+=			mmc_host_clk_release(host);
=+DO NOT APPLY+=		}
 	}
 
 	return 0;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 99f5709ac343..52bcfd4233e7 100644
=-DO NOT APPLY-= a/include/linux/mmc/host.h
=+DO NOT APPLY+= b/include/linux/mmc/host.h
@@ -282,6 +282,7 @@ struct mmc_host {
 				 MMC_CAP2_PACKED_WR)
 #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)	/* Don't power up before scan */
 #define MMC_CAP2_SANITIZE	(1 << 15)		/* Support Sanitize */
=+DO NOT APPLY+=#define MMC_CAP2_SDIO_NOTHREAD	(1 << 16)	/* don't have separate thread */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
@@ -397,6 +398,8 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
 	wake_up_process(host->sdio_irq_thread);
 }
 
=+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host);
=+DO NOT APPLY+=
 #ifdef CONFIG_REGULATOR
 int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
-- 
1.8.3.1


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

* [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than the SDIO support spawning it's own thread for handling card
interrupts, use the generic IRQ infrastructure for this, triggering it
from the host interface's interrupt handling directly.

This avoids a race between the parent thread waiting to receive an
interrupt response from the card, and the slow startup from the sdio
irq thread, which can occur as a result of high system load (eg, while
udev is running.)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h    |  3 +++
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index aaa90460ed23..f23d73993dc6 100644
=-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
=+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
@@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
 	return ret;
 }
 
=+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	mmc_claim_host(host);
=+DO NOT APPLY+=	host->sdio_irq_pending = true;
=+DO NOT APPLY+=	process_sdio_pending_irqs(host);
=+DO NOT APPLY+=	mmc_release_host(host);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
=+DO NOT APPLY+=
 static int sdio_irq_thread(void *_host)
 {
 	struct mmc_host *host = _host;
@@ -189,14 +198,20 @@ static int sdio_card_irq_get(struct mmc_card *card)
 	WARN_ON(!host->claimed);
 
 	if (!host->sdio_irqs++) {
-		atomic_set(&host->sdio_irq_thread_abort, 0);
-		host->sdio_irq_thread =
-			kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
-				mmc_hostname(host));
-		if (IS_ERR(host->sdio_irq_thread)) {
-			int err = PTR_ERR(host->sdio_irq_thread);
-			host->sdio_irqs--;
-			return err;
=+DO NOT APPLY+=		if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
=+DO NOT APPLY+=			atomic_set(&host->sdio_irq_thread_abort, 0);
=+DO NOT APPLY+=			host->sdio_irq_thread =
=+DO NOT APPLY+=				kthread_run(sdio_irq_thread, host,
=+DO NOT APPLY+=					    "ksdioirqd/%s", mmc_hostname(host));
=+DO NOT APPLY+=			if (IS_ERR(host->sdio_irq_thread)) {
=+DO NOT APPLY+=				int err = PTR_ERR(host->sdio_irq_thread);
=+DO NOT APPLY+=				host->sdio_irqs--;
=+DO NOT APPLY+=				return err;
=+DO NOT APPLY+=			}
=+DO NOT APPLY+=		} else {
=+DO NOT APPLY+=			mmc_host_clk_hold(host);
=+DO NOT APPLY+=			host->ops->enable_sdio_irq(host, 1);
=+DO NOT APPLY+=			mmc_host_clk_release(host);
 		}
 	}
 
@@ -211,8 +226,14 @@ static int sdio_card_irq_put(struct mmc_card *card)
 	BUG_ON(host->sdio_irqs < 1);
 
 	if (!--host->sdio_irqs) {
-		atomic_set(&host->sdio_irq_thread_abort, 1);
-		kthread_stop(host->sdio_irq_thread);
=+DO NOT APPLY+=		if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
=+DO NOT APPLY+=			atomic_set(&host->sdio_irq_thread_abort, 1);
=+DO NOT APPLY+=			kthread_stop(host->sdio_irq_thread);
=+DO NOT APPLY+=		} else {
=+DO NOT APPLY+=			mmc_host_clk_hold(host);
=+DO NOT APPLY+=			host->ops->enable_sdio_irq(host, 0);
=+DO NOT APPLY+=			mmc_host_clk_release(host);
=+DO NOT APPLY+=		}
 	}
 
 	return 0;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 99f5709ac343..52bcfd4233e7 100644
=-DO NOT APPLY-= a/include/linux/mmc/host.h
=+DO NOT APPLY+= b/include/linux/mmc/host.h
@@ -282,6 +282,7 @@ struct mmc_host {
 				 MMC_CAP2_PACKED_WR)
 #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14)	/* Don't power up before scan */
 #define MMC_CAP2_SANITIZE	(1 << 15)		/* Support Sanitize */
=+DO NOT APPLY+=#define MMC_CAP2_SDIO_NOTHREAD	(1 << 16)	/* don't have separate thread */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
@@ -397,6 +398,8 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
 	wake_up_process(host->sdio_irq_thread);
 }
 
=+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host);
=+DO NOT APPLY+=
 #ifdef CONFIG_REGULATOR
 int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
-- 
1.8.3.1

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

* [PATCH RFC 04/31] mmc: sdhci: clean up interrupt handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

sdhci interrupt handling is a mess; there is a lot of code doing very
similar things.  Let's clean this up a bit:

1. set's clear down cmd, data and bus power interrupts in one go - we're
   always going to handle these.
2. use a do { } while () loop for looping while there are pending
   interrupts.
3. group clearing of bits in intmask into one place.

This results in the code becoming simpler and easier to read.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 124 ++++++++++++++++++++++-------------------------
 1 file changed, 58 insertions(+), 66 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9ddef4763541..d44033bc6f1b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2427,7 +2427,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 {
 	irqreturn_t result;
 	struct sdhci_host *host = dev_id;
-	u32 intmask, unexpected = 0;
=+DO NOT APPLY+=	u32 intmask, mask, unexpected = 0;
 	int cardint = 0, max_loops = 16;
 
 	spin_lock(&host->lock);
@@ -2440,88 +2440,80 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 	}
 
 	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-
 	if (!intmask || intmask == 0xffffffff) {
 		result = IRQ_NONE;
 		goto out;
 	}
 
-again:
-	DBG("*** %s got interrupt: 0x%08x\n",
-		mmc_hostname(host->mmc), intmask);
-
-	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
-		u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			      SDHCI_CARD_PRESENT;
-
-		/*
-		 * There is a observation on i.mx esdhc.  INSERT bit will be
-		 * immediately set again when it gets cleared, if a card is
-		 * inserted.  We have to mask the irq to prevent interrupt
-		 * storm which will freeze the system.  And the REMOVE gets
-		 * the same situation.
-		 *
-		 * More testing are needed here to ensure it works for other
-		 * platforms though.
-		 */
-		sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
-						SDHCI_INT_CARD_REMOVE);
-		sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
-						  SDHCI_INT_CARD_INSERT);
-
-		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
-			     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
-		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
-		tasklet_schedule(&host->card_tasklet);
-	}
=+DO NOT APPLY+=	do {
=+DO NOT APPLY+=		/* Clear selected interrupts. */
=+DO NOT APPLY+=		mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
=+DO NOT APPLY+=				  SDHCI_INT_BUS_POWER);
=+DO NOT APPLY+=		sdhci_writel(host, mask, SDHCI_INT_STATUS);
 
-	if (intmask & SDHCI_INT_CMD_MASK) {
-		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
-			SDHCI_INT_STATUS);
-		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
-	}
=+DO NOT APPLY+=		DBG("*** %s got interrupt: 0x%08x\n",
=+DO NOT APPLY+=			mmc_hostname(host->mmc), intmask);
 
-	if (intmask & SDHCI_INT_DATA_MASK) {
-		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
-			SDHCI_INT_STATUS);
-		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
-	}
=+DO NOT APPLY+=		if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
=+DO NOT APPLY+=			u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=				      SDHCI_CARD_PRESENT;
 
-	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
=+DO NOT APPLY+=			/*
=+DO NOT APPLY+=			 * There is a observation on i.mx esdhc.  INSERT
=+DO NOT APPLY+=			 * bit will be immediately set again when it gets
=+DO NOT APPLY+=			 * cleared, if a card is inserted.  We have to mask
=+DO NOT APPLY+=			 * the irq to prevent interrupt storm which will
=+DO NOT APPLY+=			 * freeze the system.  And the REMOVE gets the
=+DO NOT APPLY+=			 * same situation.
=+DO NOT APPLY+=			 *
=+DO NOT APPLY+=			 * More testing are needed here to ensure it works
=+DO NOT APPLY+=			 * for other platforms though.
=+DO NOT APPLY+=			 */
=+DO NOT APPLY+=			sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
=+DO NOT APPLY+=							SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=							  SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=
=+DO NOT APPLY+=			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
=+DO NOT APPLY+=			tasklet_schedule(&host->card_tasklet);
=+DO NOT APPLY+=		}
 
-	intmask &= ~SDHCI_INT_ERROR;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CMD_MASK)
=+DO NOT APPLY+=			sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
 
-	if (intmask & SDHCI_INT_BUS_POWER) {
-		pr_err("%s: Card is consuming too much power!\n",
-			mmc_hostname(host->mmc));
-		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
-	}
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_DATA_MASK)
=+DO NOT APPLY+=			sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
 
-	intmask &= ~SDHCI_INT_BUS_POWER;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_BUS_POWER)
=+DO NOT APPLY+=			pr_err("%s: Card is consuming too much power!\n",
=+DO NOT APPLY+=				mmc_hostname(host->mmc));
 
-	if (intmask & SDHCI_INT_CARD_INT)
-		cardint = 1;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CARD_INT)
=+DO NOT APPLY+=			cardint = 1;
 
-	intmask &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
=+DO NOT APPLY+=			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
=+DO NOT APPLY+=			     SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
=+DO NOT APPLY+=			     SDHCI_INT_CARD_INT);
 
-	if (intmask) {
-		unexpected |= intmask;
-		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
-	}
=+DO NOT APPLY+=		if (intmask) {
=+DO NOT APPLY+=			unexpected |= intmask;
=+DO NOT APPLY+=			sdhci_writel(host, intmask, SDHCI_INT_STATUS);
=+DO NOT APPLY+=		}
 
-	result = IRQ_HANDLED;
=+DO NOT APPLY+=		result = IRQ_HANDLED;
 
-	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
=+DO NOT APPLY+=		intmask = sdhci_readl(host, SDHCI_INT_STATUS);
 
-	/*
-	 * If we know we'll call the driver to signal SDIO IRQ, disregard
-	 * further indications of Card Interrupt in the status to avoid a
-	 * needless loop.
-	 */
-	if (cardint)
-		intmask &= ~SDHCI_INT_CARD_INT;
-	if (intmask && --max_loops)
-		goto again;
=+DO NOT APPLY+=		/*
=+DO NOT APPLY+=		 * If we know we'll call the driver to signal SDIO IRQ,
=+DO NOT APPLY+=		 * disregard further indications of Card Interrupt in
=+DO NOT APPLY+=		 * the status to avoid a needless loop.
=+DO NOT APPLY+=		 */
=+DO NOT APPLY+=		if (cardint)
=+DO NOT APPLY+=			intmask &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=	} while (intmask && --max_loops);
 out:
 	spin_unlock(&host->lock);
 
-- 
1.8.3.1


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

* [PATCH RFC 04/31] mmc: sdhci: clean up interrupt handling
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

sdhci interrupt handling is a mess; there is a lot of code doing very
similar things.  Let's clean this up a bit:

1. set's clear down cmd, data and bus power interrupts in one go - we're
   always going to handle these.
2. use a do { } while () loop for looping while there are pending
   interrupts.
3. group clearing of bits in intmask into one place.

This results in the code becoming simpler and easier to read.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 124 ++++++++++++++++++++++-------------------------
 1 file changed, 58 insertions(+), 66 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9ddef4763541..d44033bc6f1b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2427,7 +2427,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 {
 	irqreturn_t result;
 	struct sdhci_host *host = dev_id;
-	u32 intmask, unexpected = 0;
=+DO NOT APPLY+=	u32 intmask, mask, unexpected = 0;
 	int cardint = 0, max_loops = 16;
 
 	spin_lock(&host->lock);
@@ -2440,88 +2440,80 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 	}
 
 	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-
 	if (!intmask || intmask == 0xffffffff) {
 		result = IRQ_NONE;
 		goto out;
 	}
 
-again:
-	DBG("*** %s got interrupt: 0x%08x\n",
-		mmc_hostname(host->mmc), intmask);
-
-	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
-		u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			      SDHCI_CARD_PRESENT;
-
-		/*
-		 * There is a observation on i.mx esdhc.  INSERT bit will be
-		 * immediately set again when it gets cleared, if a card is
-		 * inserted.  We have to mask the irq to prevent interrupt
-		 * storm which will freeze the system.  And the REMOVE gets
-		 * the same situation.
-		 *
-		 * More testing are needed here to ensure it works for other
-		 * platforms though.
-		 */
-		sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
-						SDHCI_INT_CARD_REMOVE);
-		sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
-						  SDHCI_INT_CARD_INSERT);
-
-		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
-			     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
-		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
-		tasklet_schedule(&host->card_tasklet);
-	}
=+DO NOT APPLY+=	do {
=+DO NOT APPLY+=		/* Clear selected interrupts. */
=+DO NOT APPLY+=		mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
=+DO NOT APPLY+=				  SDHCI_INT_BUS_POWER);
=+DO NOT APPLY+=		sdhci_writel(host, mask, SDHCI_INT_STATUS);
 
-	if (intmask & SDHCI_INT_CMD_MASK) {
-		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
-			SDHCI_INT_STATUS);
-		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
-	}
=+DO NOT APPLY+=		DBG("*** %s got interrupt: 0x%08x\n",
=+DO NOT APPLY+=			mmc_hostname(host->mmc), intmask);
 
-	if (intmask & SDHCI_INT_DATA_MASK) {
-		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
-			SDHCI_INT_STATUS);
-		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
-	}
=+DO NOT APPLY+=		if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
=+DO NOT APPLY+=			u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=				      SDHCI_CARD_PRESENT;
 
-	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
=+DO NOT APPLY+=			/*
=+DO NOT APPLY+=			 * There is a observation on i.mx esdhc.  INSERT
=+DO NOT APPLY+=			 * bit will be immediately set again when it gets
=+DO NOT APPLY+=			 * cleared, if a card is inserted.  We have to mask
=+DO NOT APPLY+=			 * the irq to prevent interrupt storm which will
=+DO NOT APPLY+=			 * freeze the system.  And the REMOVE gets the
=+DO NOT APPLY+=			 * same situation.
=+DO NOT APPLY+=			 *
=+DO NOT APPLY+=			 * More testing are needed here to ensure it works
=+DO NOT APPLY+=			 * for other platforms though.
=+DO NOT APPLY+=			 */
=+DO NOT APPLY+=			sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
=+DO NOT APPLY+=							SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=							  SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=
=+DO NOT APPLY+=			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
=+DO NOT APPLY+=			tasklet_schedule(&host->card_tasklet);
=+DO NOT APPLY+=		}
 
-	intmask &= ~SDHCI_INT_ERROR;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CMD_MASK)
=+DO NOT APPLY+=			sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
 
-	if (intmask & SDHCI_INT_BUS_POWER) {
-		pr_err("%s: Card is consuming too much power!\n",
-			mmc_hostname(host->mmc));
-		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
-	}
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_DATA_MASK)
=+DO NOT APPLY+=			sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
 
-	intmask &= ~SDHCI_INT_BUS_POWER;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_BUS_POWER)
=+DO NOT APPLY+=			pr_err("%s: Card is consuming too much power!\n",
=+DO NOT APPLY+=				mmc_hostname(host->mmc));
 
-	if (intmask & SDHCI_INT_CARD_INT)
-		cardint = 1;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CARD_INT)
=+DO NOT APPLY+=			cardint = 1;
 
-	intmask &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
=+DO NOT APPLY+=			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
=+DO NOT APPLY+=			     SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
=+DO NOT APPLY+=			     SDHCI_INT_CARD_INT);
 
-	if (intmask) {
-		unexpected |= intmask;
-		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
-	}
=+DO NOT APPLY+=		if (intmask) {
=+DO NOT APPLY+=			unexpected |= intmask;
=+DO NOT APPLY+=			sdhci_writel(host, intmask, SDHCI_INT_STATUS);
=+DO NOT APPLY+=		}
 
-	result = IRQ_HANDLED;
=+DO NOT APPLY+=		result = IRQ_HANDLED;
 
-	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
=+DO NOT APPLY+=		intmask = sdhci_readl(host, SDHCI_INT_STATUS);
 
-	/*
-	 * If we know we'll call the driver to signal SDIO IRQ, disregard
-	 * further indications of Card Interrupt in the status to avoid a
-	 * needless loop.
-	 */
-	if (cardint)
-		intmask &= ~SDHCI_INT_CARD_INT;
-	if (intmask && --max_loops)
-		goto again;
=+DO NOT APPLY+=		/*
=+DO NOT APPLY+=		 * If we know we'll call the driver to signal SDIO IRQ,
=+DO NOT APPLY+=		 * disregard further indications of Card Interrupt in
=+DO NOT APPLY+=		 * the status to avoid a needless loop.
=+DO NOT APPLY+=		 */
=+DO NOT APPLY+=		if (cardint)
=+DO NOT APPLY+=			intmask &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=	} while (intmask && --max_loops);
 out:
 	spin_unlock(&host->lock);
 
-- 
1.8.3.1

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

* [PATCH RFC 05/31] mmc: sdhci: clean up sdio interrupt enable handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

We don't need to change the SDHCI_SDIO_IRQ_ENABLED flag when we're
merely receiving an interrupt - IRQ handling thread in the MMC core
will either re-enable or disable the interrupt via the enable_sdio_irq
callback, which will update this status appropriately.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d44033bc6f1b..dda992abf187 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1709,24 +1709,14 @@ static int sdhci_get_ro(struct mmc_host *mmc)
 
 static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
-	if (host->flags & SDHCI_DEVICE_DEAD)
-		goto out;
-
-	if (enable)
-		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
-	else
-		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
-
 	/* SDIO IRQ will be enabled as appropriate in runtime resume */
-	if (host->runtime_suspended)
-		goto out;
-
-	if (enable)
-		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
-	else
-		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
-out:
-	mmiowb();
=+DO NOT APPLY+=	if (!(host->flags & SDHCI_DEVICE_DEAD) || host->runtime_suspended) {
=+DO NOT APPLY+=		if (enable)
=+DO NOT APPLY+=			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=		else
=+DO NOT APPLY+=			sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=		mmiowb();
=+DO NOT APPLY+=	}
 }
 
 static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1734,9 +1724,18 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 	struct sdhci_host *host = mmc_priv(mmc);
 	unsigned long flags;
 
=+DO NOT APPLY+=	sdhci_runtime_pm_get(host);
=+DO NOT APPLY+=
 	spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=	if (enable)
=+DO NOT APPLY+=		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
=+DO NOT APPLY+=	else
=+DO NOT APPLY+=		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
=+DO NOT APPLY+=
 	sdhci_enable_sdio_irq_nolock(host, enable);
 	spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_runtime_pm_put(host);
 }
 
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
@@ -2724,7 +2723,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
 	host->runtime_suspended = false;
 
 	/* Enable SDIO IRQ */
-	if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
=+DO NOT APPLY+=	if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
 		sdhci_enable_sdio_irq_nolock(host, true);
 
 	/* Enable Card Detection */
-- 
1.8.3.1


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

* [PATCH RFC 05/31] mmc: sdhci: clean up sdio interrupt enable handling
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need to change the SDHCI_SDIO_IRQ_ENABLED flag when we're
merely receiving an interrupt - IRQ handling thread in the MMC core
will either re-enable or disable the interrupt via the enable_sdio_irq
callback, which will update this status appropriately.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d44033bc6f1b..dda992abf187 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1709,24 +1709,14 @@ static int sdhci_get_ro(struct mmc_host *mmc)
 
 static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
-	if (host->flags & SDHCI_DEVICE_DEAD)
-		goto out;
-
-	if (enable)
-		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
-	else
-		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
-
 	/* SDIO IRQ will be enabled as appropriate in runtime resume */
-	if (host->runtime_suspended)
-		goto out;
-
-	if (enable)
-		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
-	else
-		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
-out:
-	mmiowb();
=+DO NOT APPLY+=	if (!(host->flags & SDHCI_DEVICE_DEAD) || host->runtime_suspended) {
=+DO NOT APPLY+=		if (enable)
=+DO NOT APPLY+=			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=		else
=+DO NOT APPLY+=			sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=		mmiowb();
=+DO NOT APPLY+=	}
 }
 
 static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1734,9 +1724,18 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 	struct sdhci_host *host = mmc_priv(mmc);
 	unsigned long flags;
 
=+DO NOT APPLY+=	sdhci_runtime_pm_get(host);
=+DO NOT APPLY+=
 	spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=	if (enable)
=+DO NOT APPLY+=		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
=+DO NOT APPLY+=	else
=+DO NOT APPLY+=		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
=+DO NOT APPLY+=
 	sdhci_enable_sdio_irq_nolock(host, enable);
 	spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_runtime_pm_put(host);
 }
 
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
@@ -2724,7 +2723,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
 	host->runtime_suspended = false;
 
 	/* Enable SDIO IRQ */
-	if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
=+DO NOT APPLY+=	if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
 		sdhci_enable_sdio_irq_nolock(host, true);
 
 	/* Enable Card Detection */
-- 
1.8.3.1

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

* [PATCH RFC 06/31] mmc: sdhci: convert to new SDIO IRQ handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Use a generic threaded interrupt handler for SDIO interrupt handling,
rather than allowing the SDIO core code to buggily spawn its own
thread.  This results in host drivers to be more in control of how
SDIO interrupts are acknowledged in the hardware, rather than having
the internals of the SDIO core placed upon them, possibly resulting
in sub-standard handling.

At least one SDHCI implementation specifies a very specific sequence
to deal with a card interrupt.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 62 +++++++++++++++++++++++++++++------------------
 include/linux/mmc/sdhci.h |  2 ++
 2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dda992abf187..79a989357ac7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2424,10 +2424,10 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 
 static irqreturn_t sdhci_irq(int irq, void *dev_id)
 {
-	irqreturn_t result;
=+DO NOT APPLY+=	irqreturn_t result = IRQ_NONE;
 	struct sdhci_host *host = dev_id;
 	u32 intmask, mask, unexpected = 0;
-	int cardint = 0, max_loops = 16;
=+DO NOT APPLY+=	int max_loops = 16;
 
 	spin_lock(&host->lock);
 
@@ -2488,8 +2488,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			pr_err("%s: Card is consuming too much power!\n",
 				mmc_hostname(host->mmc));
 
-		if (intmask & SDHCI_INT_CARD_INT)
-			cardint = 1;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CARD_INT) {
=+DO NOT APPLY+=			sdhci_enable_sdio_irq_nolock(host, false);
=+DO NOT APPLY+=			host->thread_isr |= SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=			result = IRQ_WAKE_THREAD;
=+DO NOT APPLY+=		}
 
 		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
 			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
@@ -2501,17 +2504,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			sdhci_writel(host, intmask, SDHCI_INT_STATUS);
 		}
 
-		result = IRQ_HANDLED;
=+DO NOT APPLY+=		if (result == IRQ_NONE)
=+DO NOT APPLY+=			result = IRQ_HANDLED;
 
 		intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-
-		/*
-		 * If we know we'll call the driver to signal SDIO IRQ,
-		 * disregard further indications of Card Interrupt in
-		 * the status to avoid a needless loop.
-		 */
-		if (cardint)
-			intmask &= ~SDHCI_INT_CARD_INT;
 	} while (intmask && --max_loops);
 out:
 	spin_unlock(&host->lock);
@@ -2521,15 +2517,33 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			   mmc_hostname(host->mmc), unexpected);
 		sdhci_dumpregs(host);
 	}
-	/*
-	 * We have to delay this as it calls back into the driver.
-	 */
-	if (cardint)
-		mmc_signal_sdio_irq(host->mmc);
 
 	return result;
 }
 
=+DO NOT APPLY+=static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_id;
=+DO NOT APPLY+=	unsigned long flags;
=+DO NOT APPLY+=	u32 isr;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=	isr = host->thread_isr;
=+DO NOT APPLY+=	host->thread_isr = 0;
=+DO NOT APPLY+=	spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (isr & SDHCI_INT_CARD_INT) {
=+DO NOT APPLY+=		sdio_run_irqs(host->mmc);
=+DO NOT APPLY+=
=+DO NOT APPLY+=		spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=		if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
=+DO NOT APPLY+=			sdhci_enable_sdio_irq_nolock(host, true);
=+DO NOT APPLY+=		spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return isr ? IRQ_HANDLED : IRQ_NONE;
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 /*****************************************************************************\
  *                                                                           *
  * Suspend/resume                                                            *
@@ -2599,8 +2613,9 @@ int sdhci_resume_host(struct sdhci_host *host)
 	}
 
 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
-		ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
-				  mmc_hostname(host->mmc), host);
=+DO NOT APPLY+=		ret = request_threaded_irq(host->irq, sdhci_irq,
=+DO NOT APPLY+=					   sdhci_thread_irq, IRQF_SHARED,
=+DO NOT APPLY+=					   mmc_hostname(host->mmc), host);
 		if (ret)
 			return ret;
 	} else {
@@ -2679,7 +2694,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	synchronize_irq(host->irq);
=+DO NOT APPLY+=	synchronize_hardirq(host->irq);
 
 	spin_lock_irqsave(&host->lock, flags);
 	host->runtime_suspended = true;
@@ -2935,6 +2950,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	mmc->max_discard_to = (1 << 27) / host->timeout_clk;
 
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
=+DO NOT APPLY+=	mmc->caps2 |= MMC_CAP2_SDIO_NOTHREAD;
 
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
 		host->flags |= SDHCI_AUTO_CMD12;
@@ -3223,8 +3239,8 @@ int sdhci_add_host(struct sdhci_host *host)
 
 	sdhci_init(host, 0);
 
-	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
-		mmc_hostname(mmc), host);
=+DO NOT APPLY+=	ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
=+DO NOT APPLY+=				   IRQF_SHARED,	mmc_hostname(mmc), host);
 	if (ret) {
 		pr_err("%s: Failed to request IRQ %d: %d\n",
 		       mmc_hostname(mmc), host->irq, ret);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 362927c48f97..db880b285793 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -175,6 +175,8 @@ struct sdhci_host {
 	unsigned int            ocr_avail_mmc;
 	u32 ocr_mask;		/* available voltages */
 
=+DO NOT APPLY+=	u32			thread_isr;
=+DO NOT APPLY+=
 	wait_queue_head_t	buf_ready_int;	/* Waitqueue for Buffer Read Ready interrupt */
 	unsigned int		tuning_done;	/* Condition flag set when CMD19 succeeds */
 
-- 
1.8.3.1


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

* [PATCH RFC 06/31] mmc: sdhci: convert to new SDIO IRQ handling
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Use a generic threaded interrupt handler for SDIO interrupt handling,
rather than allowing the SDIO core code to buggily spawn its own
thread.  This results in host drivers to be more in control of how
SDIO interrupts are acknowledged in the hardware, rather than having
the internals of the SDIO core placed upon them, possibly resulting
in sub-standard handling.

At least one SDHCI implementation specifies a very specific sequence
to deal with a card interrupt.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 62 +++++++++++++++++++++++++++++------------------
 include/linux/mmc/sdhci.h |  2 ++
 2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dda992abf187..79a989357ac7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2424,10 +2424,10 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 
 static irqreturn_t sdhci_irq(int irq, void *dev_id)
 {
-	irqreturn_t result;
=+DO NOT APPLY+=	irqreturn_t result = IRQ_NONE;
 	struct sdhci_host *host = dev_id;
 	u32 intmask, mask, unexpected = 0;
-	int cardint = 0, max_loops = 16;
=+DO NOT APPLY+=	int max_loops = 16;
 
 	spin_lock(&host->lock);
 
@@ -2488,8 +2488,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			pr_err("%s: Card is consuming too much power!\n",
 				mmc_hostname(host->mmc));
 
-		if (intmask & SDHCI_INT_CARD_INT)
-			cardint = 1;
=+DO NOT APPLY+=		if (intmask & SDHCI_INT_CARD_INT) {
=+DO NOT APPLY+=			sdhci_enable_sdio_irq_nolock(host, false);
=+DO NOT APPLY+=			host->thread_isr |= SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=			result = IRQ_WAKE_THREAD;
=+DO NOT APPLY+=		}
 
 		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
 			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
@@ -2501,17 +2504,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			sdhci_writel(host, intmask, SDHCI_INT_STATUS);
 		}
 
-		result = IRQ_HANDLED;
=+DO NOT APPLY+=		if (result == IRQ_NONE)
=+DO NOT APPLY+=			result = IRQ_HANDLED;
 
 		intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-
-		/*
-		 * If we know we'll call the driver to signal SDIO IRQ,
-		 * disregard further indications of Card Interrupt in
-		 * the status to avoid a needless loop.
-		 */
-		if (cardint)
-			intmask &= ~SDHCI_INT_CARD_INT;
 	} while (intmask && --max_loops);
 out:
 	spin_unlock(&host->lock);
@@ -2521,15 +2517,33 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			   mmc_hostname(host->mmc), unexpected);
 		sdhci_dumpregs(host);
 	}
-	/*
-	 * We have to delay this as it calls back into the driver.
-	 */
-	if (cardint)
-		mmc_signal_sdio_irq(host->mmc);
 
 	return result;
 }
 
=+DO NOT APPLY+=static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_id;
=+DO NOT APPLY+=	unsigned long flags;
=+DO NOT APPLY+=	u32 isr;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=	isr = host->thread_isr;
=+DO NOT APPLY+=	host->thread_isr = 0;
=+DO NOT APPLY+=	spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (isr & SDHCI_INT_CARD_INT) {
=+DO NOT APPLY+=		sdio_run_irqs(host->mmc);
=+DO NOT APPLY+=
=+DO NOT APPLY+=		spin_lock_irqsave(&host->lock, flags);
=+DO NOT APPLY+=		if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
=+DO NOT APPLY+=			sdhci_enable_sdio_irq_nolock(host, true);
=+DO NOT APPLY+=		spin_unlock_irqrestore(&host->lock, flags);
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return isr ? IRQ_HANDLED : IRQ_NONE;
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 /*****************************************************************************\
  *                                                                           *
  * Suspend/resume                                                            *
@@ -2599,8 +2613,9 @@ int sdhci_resume_host(struct sdhci_host *host)
 	}
 
 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
-		ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
-				  mmc_hostname(host->mmc), host);
=+DO NOT APPLY+=		ret = request_threaded_irq(host->irq, sdhci_irq,
=+DO NOT APPLY+=					   sdhci_thread_irq, IRQF_SHARED,
=+DO NOT APPLY+=					   mmc_hostname(host->mmc), host);
 		if (ret)
 			return ret;
 	} else {
@@ -2679,7 +2694,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	synchronize_irq(host->irq);
=+DO NOT APPLY+=	synchronize_hardirq(host->irq);
 
 	spin_lock_irqsave(&host->lock, flags);
 	host->runtime_suspended = true;
@@ -2935,6 +2950,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	mmc->max_discard_to = (1 << 27) / host->timeout_clk;
 
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
=+DO NOT APPLY+=	mmc->caps2 |= MMC_CAP2_SDIO_NOTHREAD;
 
 	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
 		host->flags |= SDHCI_AUTO_CMD12;
@@ -3223,8 +3239,8 @@ int sdhci_add_host(struct sdhci_host *host)
 
 	sdhci_init(host, 0);
 
-	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
-		mmc_hostname(mmc), host);
=+DO NOT APPLY+=	ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
=+DO NOT APPLY+=				   IRQF_SHARED,	mmc_hostname(mmc), host);
 	if (ret) {
 		pr_err("%s: Failed to request IRQ %d: %d\n",
 		       mmc_hostname(mmc), host->irq, ret);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 362927c48f97..db880b285793 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -175,6 +175,8 @@ struct sdhci_host {
 	unsigned int            ocr_avail_mmc;
 	u32 ocr_mask;		/* available voltages */
 
=+DO NOT APPLY+=	u32			thread_isr;
=+DO NOT APPLY+=
 	wait_queue_head_t	buf_ready_int;	/* Waitqueue for Buffer Read Ready interrupt */
 	unsigned int		tuning_done;	/* Condition flag set when CMD19 succeeds */
 
-- 
1.8.3.1

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

There's no requirement to have the card tasklet separate now that we
have a threaded interrupt handler, so kill this and move the called
code into the threaded part of the handler.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 23 +++++++++--------------
 include/linux/mmc/sdhci.h |  3 +--
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 79a989357ac7..dfec8aab1a4a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2124,15 +2124,6 @@ static const struct mmc_host_ops sdhci_ops = {
  *                                                                           *
 \*****************************************************************************/
 
-static void sdhci_tasklet_card(unsigned long param)
-{
-	struct sdhci_host *host = (struct sdhci_host*)param;
-
-	sdhci_card_event(host->mmc);
-
-	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
-}
-
 static void sdhci_tasklet_finish(unsigned long param)
 {
 	struct sdhci_host *host;
@@ -2475,7 +2466,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
 			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
 				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
-			tasklet_schedule(&host->card_tasklet);
=+DO NOT APPLY+=
=+DO NOT APPLY+=			host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=						       SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			result = IRQ_WAKE_THREAD;
 		}
 
 		if (intmask & SDHCI_INT_CMD_MASK)
@@ -2532,6 +2526,11 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
 	host->thread_isr = 0;
 	spin_unlock_irqrestore(&host->lock, flags);
 
=+DO NOT APPLY+=	if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
=+DO NOT APPLY+=		sdhci_card_event(host->mmc);
=+DO NOT APPLY+=		mmc_detect_change(host->mmc, msecs_to_jiffies(200));
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
 	if (isr & SDHCI_INT_CARD_INT) {
 		sdio_run_irqs(host->mmc);
 
@@ -3221,8 +3220,6 @@ int sdhci_add_host(struct sdhci_host *host)
 	/*
 	 * Init tasklets.
 	 */
-	tasklet_init(&host->card_tasklet,
-		sdhci_tasklet_card, (unsigned long)host);
 	tasklet_init(&host->finish_tasklet,
 		sdhci_tasklet_finish, (unsigned long)host);
 
@@ -3287,7 +3284,6 @@ int sdhci_add_host(struct sdhci_host *host)
 	free_irq(host->irq, host);
 #endif
 untasklet:
-	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
 	return ret;
@@ -3331,7 +3327,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
 	del_timer_sync(&host->timer);
 
-	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
 	if (host->vmmc) {
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index db880b285793..da7b526bdbf1 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -162,8 +162,7 @@ struct sdhci_host {
 	dma_addr_t adma_addr;	/* Mapped ADMA descr. table */
 	dma_addr_t align_addr;	/* Mapped bounce buffer */
 
-	struct tasklet_struct card_tasklet;	/* Tasklet structures */
-	struct tasklet_struct finish_tasklet;
=+DO NOT APPLY+=	struct tasklet_struct finish_tasklet;	/* Tasklet structures */
 
 	struct timer_list timer;	/* Timer for timeouts */
 
-- 
1.8.3.1


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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

There's no requirement to have the card tasklet separate now that we
have a threaded interrupt handler, so kill this and move the called
code into the threaded part of the handler.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 23 +++++++++--------------
 include/linux/mmc/sdhci.h |  3 +--
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 79a989357ac7..dfec8aab1a4a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2124,15 +2124,6 @@ static const struct mmc_host_ops sdhci_ops = {
  *                                                                           *
 \*****************************************************************************/
 
-static void sdhci_tasklet_card(unsigned long param)
-{
-	struct sdhci_host *host = (struct sdhci_host*)param;
-
-	sdhci_card_event(host->mmc);
-
-	mmc_detect_change(host->mmc, msecs_to_jiffies(200));
-}
-
 static void sdhci_tasklet_finish(unsigned long param)
 {
 	struct sdhci_host *host;
@@ -2475,7 +2466,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
 			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
 				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
-			tasklet_schedule(&host->card_tasklet);
=+DO NOT APPLY+=
=+DO NOT APPLY+=			host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=						       SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			result = IRQ_WAKE_THREAD;
 		}
 
 		if (intmask & SDHCI_INT_CMD_MASK)
@@ -2532,6 +2526,11 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
 	host->thread_isr = 0;
 	spin_unlock_irqrestore(&host->lock, flags);
 
=+DO NOT APPLY+=	if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
=+DO NOT APPLY+=		sdhci_card_event(host->mmc);
=+DO NOT APPLY+=		mmc_detect_change(host->mmc, msecs_to_jiffies(200));
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
 	if (isr & SDHCI_INT_CARD_INT) {
 		sdio_run_irqs(host->mmc);
 
@@ -3221,8 +3220,6 @@ int sdhci_add_host(struct sdhci_host *host)
 	/*
 	 * Init tasklets.
 	 */
-	tasklet_init(&host->card_tasklet,
-		sdhci_tasklet_card, (unsigned long)host);
 	tasklet_init(&host->finish_tasklet,
 		sdhci_tasklet_finish, (unsigned long)host);
 
@@ -3287,7 +3284,6 @@ int sdhci_add_host(struct sdhci_host *host)
 	free_irq(host->irq, host);
 #endif
 untasklet:
-	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
 	return ret;
@@ -3331,7 +3327,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
 	del_timer_sync(&host->timer);
 
-	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
 	if (host->vmmc) {
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index db880b285793..da7b526bdbf1 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -162,8 +162,7 @@ struct sdhci_host {
 	dma_addr_t adma_addr;	/* Mapped ADMA descr. table */
 	dma_addr_t align_addr;	/* Mapped bounce buffer */
 
-	struct tasklet_struct card_tasklet;	/* Tasklet structures */
-	struct tasklet_struct finish_tasklet;
=+DO NOT APPLY+=	struct tasklet_struct finish_tasklet;	/* Tasklet structures */
 
 	struct timer_list timer;	/* Timer for timeouts */
 
-- 
1.8.3.1

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

* [PATCH RFC 08/31] mmc: sdhci: allow sdio interrupts while sdhci runtime suspended
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Allow SDIO interrupts to be received while the SDHCI host is runtime
suspended.  We do this by leaving the AHB clock enabled while the
host is runtime suspended so we can access the SDHCI registers, and
so read and raise the SDIO card interrupt.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++++++----
 drivers/mmc/host/sdhci.c           |  7 +++----
 drivers/mmc/host/sdhci.h           |  5 +++++
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b841bb7cd371..b0b4eea8d232 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1170,8 +1170,10 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
 
 	ret = sdhci_runtime_suspend_host(host);
 
-	clk_disable_unprepare(imx_data->clk_per);
-	clk_disable_unprepare(imx_data->clk_ipg);
=+DO NOT APPLY+=	if (!sdhci_sdio_irq_enabled(host)) {
=+DO NOT APPLY+=		clk_disable_unprepare(imx_data->clk_per);
=+DO NOT APPLY+=		clk_disable_unprepare(imx_data->clk_ipg);
=+DO NOT APPLY+=	}
 	clk_disable_unprepare(imx_data->clk_ahb);
 
 	return ret;
@@ -1183,8 +1185,10 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
-	clk_prepare_enable(imx_data->clk_per);
-	clk_prepare_enable(imx_data->clk_ipg);
=+DO NOT APPLY+=	if (!sdhci_sdio_irq_enabled(host)) {
=+DO NOT APPLY+=		clk_prepare_enable(imx_data->clk_per);
=+DO NOT APPLY+=		clk_prepare_enable(imx_data->clk_ipg);
=+DO NOT APPLY+=	}
 	clk_prepare_enable(imx_data->clk_ahb);
 
 	return sdhci_runtime_resume_host(host);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dfec8aab1a4a..576ded2406d9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1709,8 +1709,7 @@ static int sdhci_get_ro(struct mmc_host *mmc)
 
 static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
-	/* SDIO IRQ will be enabled as appropriate in runtime resume */
-	if (!(host->flags & SDHCI_DEVICE_DEAD) || host->runtime_suspended) {
=+DO NOT APPLY+=	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
 		if (enable)
 			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
 		else
@@ -2422,7 +2421,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
 	spin_lock(&host->lock);
 
-	if (host->runtime_suspended) {
=+DO NOT APPLY+=	if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
 		spin_unlock(&host->lock);
 		pr_warning("%s: got irq while runtime suspended\n",
 		       mmc_hostname(host->mmc));
@@ -2690,7 +2689,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	}
 
 	spin_lock_irqsave(&host->lock, flags);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK & ~SDHCI_INT_CARD_INT);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	synchronize_hardirq(host->irq);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0a3ed01887db..fc6f81d2f377 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -397,6 +397,11 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
 extern void sdhci_send_command(struct sdhci_host *host,
 				struct mmc_command *cmd);
 
=+DO NOT APPLY+=static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
 extern int sdhci_resume_host(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 08/31] mmc: sdhci: allow sdio interrupts while sdhci runtime suspended
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Allow SDIO interrupts to be received while the SDHCI host is runtime
suspended.  We do this by leaving the AHB clock enabled while the
host is runtime suspended so we can access the SDHCI registers, and
so read and raise the SDIO card interrupt.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++++++----
 drivers/mmc/host/sdhci.c           |  7 +++----
 drivers/mmc/host/sdhci.h           |  5 +++++
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b841bb7cd371..b0b4eea8d232 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1170,8 +1170,10 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
 
 	ret = sdhci_runtime_suspend_host(host);
 
-	clk_disable_unprepare(imx_data->clk_per);
-	clk_disable_unprepare(imx_data->clk_ipg);
=+DO NOT APPLY+=	if (!sdhci_sdio_irq_enabled(host)) {
=+DO NOT APPLY+=		clk_disable_unprepare(imx_data->clk_per);
=+DO NOT APPLY+=		clk_disable_unprepare(imx_data->clk_ipg);
=+DO NOT APPLY+=	}
 	clk_disable_unprepare(imx_data->clk_ahb);
 
 	return ret;
@@ -1183,8 +1185,10 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 
-	clk_prepare_enable(imx_data->clk_per);
-	clk_prepare_enable(imx_data->clk_ipg);
=+DO NOT APPLY+=	if (!sdhci_sdio_irq_enabled(host)) {
=+DO NOT APPLY+=		clk_prepare_enable(imx_data->clk_per);
=+DO NOT APPLY+=		clk_prepare_enable(imx_data->clk_ipg);
=+DO NOT APPLY+=	}
 	clk_prepare_enable(imx_data->clk_ahb);
 
 	return sdhci_runtime_resume_host(host);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dfec8aab1a4a..576ded2406d9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1709,8 +1709,7 @@ static int sdhci_get_ro(struct mmc_host *mmc)
 
 static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
-	/* SDIO IRQ will be enabled as appropriate in runtime resume */
-	if (!(host->flags & SDHCI_DEVICE_DEAD) || host->runtime_suspended) {
=+DO NOT APPLY+=	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
 		if (enable)
 			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
 		else
@@ -2422,7 +2421,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
 	spin_lock(&host->lock);
 
-	if (host->runtime_suspended) {
=+DO NOT APPLY+=	if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
 		spin_unlock(&host->lock);
 		pr_warning("%s: got irq while runtime suspended\n",
 		       mmc_hostname(host->mmc));
@@ -2690,7 +2689,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	}
 
 	spin_lock_irqsave(&host->lock, flags);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK & ~SDHCI_INT_CARD_INT);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	synchronize_hardirq(host->irq);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0a3ed01887db..fc6f81d2f377 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -397,6 +397,11 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
 extern void sdhci_send_command(struct sdhci_host *host,
 				struct mmc_command *cmd);
 
=+DO NOT APPLY+=static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
 extern int sdhci_resume_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 09/31] mmc: sdhci: more efficient interrupt enable register handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Rather than wasting cycles read-modify-writing the interrupt enable
registers, cache the value locally instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 98 +++++++++++++++++++++++------------------------
 include/linux/mmc/sdhci.h |  3 ++
 2 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 576ded2406d9..84cd0fd820d9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -131,27 +131,6 @@ static void sdhci_dumpregs(struct sdhci_host *host)
  *                                                                           *
 \*****************************************************************************/
 
-static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
-{
-	u32 ier;
-
-	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-	ier &= ~clear;
-	ier |= set;
-	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
-	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
-}
-
-static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
-{
-	sdhci_clear_set_irqs(host, 0, irqs);
-}
-
-static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
-{
-	sdhci_clear_set_irqs(host, irqs, 0);
-}
-
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
 	u32 present, irqs;
@@ -165,9 +144,12 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
 
 	if (enable)
-		sdhci_unmask_irqs(host, irqs);
=+DO NOT APPLY+=		host->ier |= irqs;
 	else
-		sdhci_mask_irqs(host, irqs);
=+DO NOT APPLY+=		host->ier &= ~irqs;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
 static void sdhci_enable_card_detection(struct sdhci_host *host)
@@ -183,17 +165,12 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
-	u32 uninitialized_var(ier);
-
 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
 		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
 			SDHCI_CARD_PRESENT))
 			return;
 	}
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
-		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-
 	if (host->ops->platform_reset_enter)
 		host->ops->platform_reset_enter(host, mask);
 
@@ -224,8 +201,10 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 	if (host->ops->platform_reset_exit)
 		host->ops->platform_reset_exit(host, mask);
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
-		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
=+DO NOT APPLY+=	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
=+DO NOT APPLY+=	}
 
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
@@ -242,11 +221,14 @@ static void sdhci_init(struct sdhci_host *host, int soft)
 	else
 		sdhci_reset(host, SDHCI_RESET_ALL);
 
-	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
-		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
-		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
-		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
-		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
=+DO NOT APPLY+=	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
=+DO NOT APPLY+=		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
=+DO NOT APPLY+=		    SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
=+DO NOT APPLY+=		    SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
=+DO NOT APPLY+=		    SDHCI_INT_RESPONSE;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
 	if (soft) {
 		/* force clock reconfiguration */
@@ -721,9 +703,12 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
 
 	if (host->flags & SDHCI_REQ_USE_DMA)
-		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
=+DO NOT APPLY+=		host->ier = (host->ier & ~pio_irqs) | dma_irqs;
 	else
-		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
=+DO NOT APPLY+=		host->ier = (host->ier & ~dma_irqs) | pio_irqs;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
 static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
@@ -1711,9 +1696,12 @@ static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
 	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
 		if (enable)
-			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=			host->ier |= SDHCI_INT_CARD_INT;
 		else
-			sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=			host->ier &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 		mmiowb();
 	}
 }
@@ -1855,7 +1843,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct sdhci_host *host;
 	u16 ctrl;
-	u32 ier;
 	int tuning_loop_counter = MAX_TUNING_LOOP;
 	unsigned long timeout;
 	int err = 0;
@@ -1909,8 +1896,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * to make sure we don't hit a controller bug, we _only_
 	 * enable Buffer Read Ready interrupt here.
 	 */
-	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-	sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
=+DO NOT APPLY+=	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
 
 	/*
 	 * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
@@ -2043,7 +2030,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
 		err = 0;
 
-	sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 	spin_unlock_irqrestore(&host->lock, flags);
 	sdhci_runtime_pm_put(host);
 
@@ -2458,10 +2446,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			 * More testing are needed here to ensure it works
 			 * for other platforms though.
 			 */
-			sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
-							SDHCI_INT_CARD_REMOVE);
-			sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
-							  SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=			host->ier &= ~(SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=				       SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			host->ier |= present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=					       SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=			sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=			sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
 			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
 				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
@@ -2590,7 +2580,9 @@ int sdhci_suspend_host(struct sdhci_host *host)
 	}
 
 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
-		sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=		host->ier = 0;
=+DO NOT APPLY+=		sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 		free_irq(host->irq, host);
 	} else {
 		sdhci_enable_irq_wakeups(host);
@@ -2689,7 +2681,9 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	}
 
 	spin_lock_irqsave(&host->lock, flags);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK & ~SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=	host->ier &= SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	synchronize_hardirq(host->irq);
@@ -3279,7 +3273,8 @@ int sdhci_add_host(struct sdhci_host *host)
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
 	sdhci_reset(host, SDHCI_RESET_ALL);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
 #endif
 untasklet:
@@ -3321,7 +3316,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 	if (!dead)
 		sdhci_reset(host, SDHCI_RESET_ALL);
 
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
 
 	del_timer_sync(&host->timer);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index da7b526bdbf1..493c57aee4cb 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -176,6 +176,9 @@ struct sdhci_host {
 
 	u32			thread_isr;
 
=+DO NOT APPLY+=	/* cached registers */
=+DO NOT APPLY+=	u32			ier;
=+DO NOT APPLY+=
 	wait_queue_head_t	buf_ready_int;	/* Waitqueue for Buffer Read Ready interrupt */
 	unsigned int		tuning_done;	/* Condition flag set when CMD19 succeeds */
 
-- 
1.8.3.1


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

* [PATCH RFC 09/31] mmc: sdhci: more efficient interrupt enable register handling
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than wasting cycles read-modify-writing the interrupt enable
registers, cache the value locally instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 98 +++++++++++++++++++++++------------------------
 include/linux/mmc/sdhci.h |  3 ++
 2 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 576ded2406d9..84cd0fd820d9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -131,27 +131,6 @@ static void sdhci_dumpregs(struct sdhci_host *host)
  *                                                                           *
 \*****************************************************************************/
 
-static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
-{
-	u32 ier;
-
-	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-	ier &= ~clear;
-	ier |= set;
-	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
-	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
-}
-
-static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
-{
-	sdhci_clear_set_irqs(host, 0, irqs);
-}
-
-static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
-{
-	sdhci_clear_set_irqs(host, irqs, 0);
-}
-
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
 	u32 present, irqs;
@@ -165,9 +144,12 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
 
 	if (enable)
-		sdhci_unmask_irqs(host, irqs);
=+DO NOT APPLY+=		host->ier |= irqs;
 	else
-		sdhci_mask_irqs(host, irqs);
=+DO NOT APPLY+=		host->ier &= ~irqs;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
 static void sdhci_enable_card_detection(struct sdhci_host *host)
@@ -183,17 +165,12 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
-	u32 uninitialized_var(ier);
-
 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
 		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
 			SDHCI_CARD_PRESENT))
 			return;
 	}
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
-		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-
 	if (host->ops->platform_reset_enter)
 		host->ops->platform_reset_enter(host, mask);
 
@@ -224,8 +201,10 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 	if (host->ops->platform_reset_exit)
 		host->ops->platform_reset_exit(host, mask);
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
-		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
=+DO NOT APPLY+=	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
=+DO NOT APPLY+=	}
 
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
@@ -242,11 +221,14 @@ static void sdhci_init(struct sdhci_host *host, int soft)
 	else
 		sdhci_reset(host, SDHCI_RESET_ALL);
 
-	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
-		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
-		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
-		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
-		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
=+DO NOT APPLY+=	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
=+DO NOT APPLY+=		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
=+DO NOT APPLY+=		    SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
=+DO NOT APPLY+=		    SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
=+DO NOT APPLY+=		    SDHCI_INT_RESPONSE;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
 	if (soft) {
 		/* force clock reconfiguration */
@@ -721,9 +703,12 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
 	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
 
 	if (host->flags & SDHCI_REQ_USE_DMA)
-		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
=+DO NOT APPLY+=		host->ier = (host->ier & ~pio_irqs) | dma_irqs;
 	else
-		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
=+DO NOT APPLY+=		host->ier = (host->ier & ~dma_irqs) | pio_irqs;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
 static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
@@ -1711,9 +1696,12 @@ static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
 {
 	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
 		if (enable)
-			sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=			host->ier |= SDHCI_INT_CARD_INT;
 		else
-			sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=			host->ier &= ~SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 		mmiowb();
 	}
 }
@@ -1855,7 +1843,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct sdhci_host *host;
 	u16 ctrl;
-	u32 ier;
 	int tuning_loop_counter = MAX_TUNING_LOOP;
 	unsigned long timeout;
 	int err = 0;
@@ -1909,8 +1896,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * to make sure we don't hit a controller bug, we _only_
 	 * enable Buffer Read Ready interrupt here.
 	 */
-	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
-	sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
=+DO NOT APPLY+=	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
 
 	/*
 	 * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
@@ -2043,7 +2030,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
 		err = 0;
 
-	sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 	spin_unlock_irqrestore(&host->lock, flags);
 	sdhci_runtime_pm_put(host);
 
@@ -2458,10 +2446,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 			 * More testing are needed here to ensure it works
 			 * for other platforms though.
 			 */
-			sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
-							SDHCI_INT_CARD_REMOVE);
-			sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
-							  SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=			host->ier &= ~(SDHCI_INT_CARD_INSERT |
=+DO NOT APPLY+=				       SDHCI_INT_CARD_REMOVE);
=+DO NOT APPLY+=			host->ier |= present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=					       SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=			sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=			sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 
 			sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
 				     SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
@@ -2590,7 +2580,9 @@ int sdhci_suspend_host(struct sdhci_host *host)
 	}
 
 	if (!device_may_wakeup(mmc_dev(host->mmc))) {
-		sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=		host->ier = 0;
=+DO NOT APPLY+=		sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 		free_irq(host->irq, host);
 	} else {
 		sdhci_enable_irq_wakeups(host);
@@ -2689,7 +2681,9 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 	}
 
 	spin_lock_irqsave(&host->lock, flags);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK & ~SDHCI_INT_CARD_INT);
=+DO NOT APPLY+=	host->ier &= SDHCI_INT_CARD_INT;
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	synchronize_hardirq(host->irq);
@@ -3279,7 +3273,8 @@ int sdhci_add_host(struct sdhci_host *host)
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
 	sdhci_reset(host, SDHCI_RESET_ALL);
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
 #endif
 untasklet:
@@ -3321,7 +3316,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 	if (!dead)
 		sdhci_reset(host, SDHCI_RESET_ALL);
 
-	sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
 
 	del_timer_sync(&host->timer);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index da7b526bdbf1..493c57aee4cb 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -176,6 +176,9 @@ struct sdhci_host {
 
 	u32			thread_isr;
 
=+DO NOT APPLY+=	/* cached registers */
=+DO NOT APPLY+=	u32			ier;
=+DO NOT APPLY+=
 	wait_queue_head_t	buf_ready_int;	/* Waitqueue for Buffer Read Ready interrupt */
 	unsigned int		tuning_done;	/* Condition flag set when CMD19 succeeds */
 
-- 
1.8.3.1

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

* [PATCH RFC 10/31] mmc: sdhci: plug hole in disabling card detection interrupts
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

When we disable card detection interrupts, we should disable both the
insert and remove interrupts irrespective of the current state - this
avoids races between the hardware card detect changing state before
we've read that updated state and altered the interrupt mask.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 84cd0fd820d9..5fe211dfb792 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -133,20 +133,21 @@ static void sdhci_dumpregs(struct sdhci_host *host)
 
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
-	u32 present, irqs;
=+DO NOT APPLY+=	u32 present;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
 	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		return;
 
-	present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			      SDHCI_CARD_PRESENT;
-	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=	if (enable) {
=+DO NOT APPLY+=		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=				      SDHCI_CARD_PRESENT;
 
-	if (enable)
-		host->ier |= irqs;
-	else
-		host->ier &= ~irqs;
=+DO NOT APPLY+=		host->ier |= present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=				       SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=	} else {
=+DO NOT APPLY+=		host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=	}
 
 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
-- 
1.8.3.1


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

* [PATCH RFC 10/31] mmc: sdhci: plug hole in disabling card detection interrupts
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

When we disable card detection interrupts, we should disable both the
insert and remove interrupts irrespective of the current state - this
avoids races between the hardware card detect changing state before
we've read that updated state and altered the interrupt mask.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 84cd0fd820d9..5fe211dfb792 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -133,20 +133,21 @@ static void sdhci_dumpregs(struct sdhci_host *host)
 
 static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
 {
-	u32 present, irqs;
=+DO NOT APPLY+=	u32 present;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
 	    (host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		return;
 
-	present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			      SDHCI_CARD_PRESENT;
-	irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=	if (enable) {
=+DO NOT APPLY+=		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=				      SDHCI_CARD_PRESENT;
 
-	if (enable)
-		host->ier |= irqs;
-	else
-		host->ier &= ~irqs;
=+DO NOT APPLY+=		host->ier |= present ? SDHCI_INT_CARD_REMOVE :
=+DO NOT APPLY+=				       SDHCI_INT_CARD_INSERT;
=+DO NOT APPLY+=	} else {
=+DO NOT APPLY+=		host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
=+DO NOT APPLY+=	}
 
 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
-- 
1.8.3.1

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

* [PATCH RFC 11/31] mmc: sdhci: convert generic bus width setup to library function
  2014-02-18 15:08 ` Russell King - ARM Linux
  (?)
@ 2014-02-18 15:09   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Michal Simek, Anton Vorontsov, Ben Dooks, Barry Song,
	Viresh Kumar, Stephen Warren, Thierry Reding, linuxppc-dev,
	spear-devel, linux-tegra

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  6 ++---
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  6 ++---
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  6 ++---
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 ++---
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  8 +++----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  2 +-
 drivers/mmc/host/sdhci-tegra.c     |  5 ++---
 drivers/mmc/host/sdhci.c           | 45 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  5 +++--
 19 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 9ce17f6e4014..b138bfdd3843 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -102,10 +102,12 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 7a190fe4dff1..bf851a6e4e8e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -208,6 +208,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index f6d8d67c545f..7ab69af979b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -133,6 +133,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_b = bcm2835_sdhci_readb,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index f2cc26633cb2..5e0cc9c47887 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -82,6 +82,7 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 8424839660f8..7eef4890fd22 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b0b4eea8d232..568239d84cbe 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -668,7 +668,7 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 	return -ENOSYS;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -686,8 +686,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
 			SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
@@ -888,7 +886,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_max_clock = esdhc_pltfm_get_max_clock,
 	.get_min_clock = esdhc_pltfm_get_min_clock,
 	.get_ro = esdhc_pltfm_get_ro,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
 };
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f7c7cf62437d..9bb1dd263a45 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -54,6 +54,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 0b249970b119..86b8326e77c3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -269,7 +269,7 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
 		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -289,8 +289,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
 			ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
-
-	return 0;
 }
 
 static const struct sdhci_ops sdhci_esdhc_ops = {
@@ -310,7 +308,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.platform_resume = esdhc_of_resume,
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 57c514a81ca5..4d5d0015e392 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 0955777b6c7e..59cc938b450d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1011,7 +1011,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
 	return 0;
 }
 
-static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -1032,8 +1032,6 @@ static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
@@ -1061,7 +1059,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
-	.platform_bus_width	= sdhci_pci_bus_width,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_pci_set_bus_width,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bef250e95418..40b0fe224f9d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d51e061ec576..d24c282e5eb8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -88,7 +88,7 @@ static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 	u16 tmp;
@@ -107,14 +107,12 @@ static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
 	}
 	writew(tmp, host->ioaddr + SD_CE_ATA_2);
 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.platform_reset_exit = pxav2_set_private_registers,
-	.platform_bus_width = pxav2_mmc_set_width,
=+DO NOT APPLY+=	.set_bus_width = pxav2_mmc_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 793dacd3b841..89c932d9685e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -172,6 +172,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 6debda952155..1c4ebd69d4e5 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -330,14 +330,14 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 }
 
 /**
- * sdhci_s3c_platform_bus_width - support 8bit buswidth
=+DO NOT APPLY+= * sdhci_s3c_set_bus_width - support 8bit buswidth
  * @host: The SDHCI host being queried
  * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  *
  * We have 8-bit width support but is not a v3 controller.
  * So we add platform_bus_width() and support 8bit width.
  */
-static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -359,15 +359,13 @@ static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static struct sdhci_ops sdhci_s3c_ops = {
 	.get_max_clock		= sdhci_s3c_get_max_clk,
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
-	.platform_bus_width	= sdhci_s3c_platform_bus_width,
=+DO NOT APPLY+=	.set_bus_width		= sdhci_s3c_set_bus_width,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 696122c1b468..16fcd48f9556 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -29,6 +29,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 2dba9f8d1760..549e9e0edb27 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,7 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
-	/* Nothing to do for now. */
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a835898a68dd..feed799b827a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -127,7 +127,7 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
=+DO NOT APPLY+=static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 {
 	u32 ctrl;
 
@@ -144,7 +144,6 @@ static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
 			ctrl &= ~SDHCI_CTRL_4BITBUS;
 	}
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	return 0;
 }
 
 static const struct sdhci_ops tegra_sdhci_ops = {
@@ -152,7 +151,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
-	.platform_bus_width = tegra_sdhci_buswidth,
=+DO NOT APPLY+=	.set_bus_width = tegra_sdhci_set_bus_width,
 	.platform_reset_exit = tegra_sdhci_reset_exit,
 };
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5fe211dfb792..ad744941fdf8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1413,6 +1413,27 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u8 ctrl;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=	if (width == MMC_BUS_WIDTH_8) {
=+DO NOT APPLY+=		ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=	} else {
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=		if (width == MMC_BUS_WIDTH_4)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		else
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1458,29 +1479,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
 
-	/*
-	 * If your platform has 8-bit width support but is not a v3 controller,
-	 * or if it requires special setup code, you should implement that in
-	 * platform_bus_width().
-	 */
-	if (host->ops->platform_bus_width) {
-		host->ops->platform_bus_width(host, ios->bus_width);
-	} else {
-		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-		if (ios->bus_width == MMC_BUS_WIDTH_8) {
-			ctrl &= ~SDHCI_CTRL_4BITBUS;
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl |= SDHCI_CTRL_8BITBUS;
-		} else {
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl &= ~SDHCI_CTRL_8BITBUS;
-			if (ios->bus_width == MMC_BUS_WIDTH_4)
-				ctrl |= SDHCI_CTRL_4BITBUS;
-			else
-				ctrl &= ~SDHCI_CTRL_4BITBUS;
-		}
-		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	}
=+DO NOT APPLY+=	host->ops->set_bus_width(host, ios->bus_width);
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index fc6f81d2f377..0301f928eb11 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -281,8 +281,7 @@ struct sdhci_ops {
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
 	unsigned int	(*get_min_clock)(struct sdhci_host *host);
 	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
-	int		(*platform_bus_width)(struct sdhci_host *host,
-					       int width);
=+DO NOT APPLY+=	void		(*set_bus_width)(struct sdhci_host *host, int width);
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
@@ -402,6 +401,8 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
 extern int sdhci_resume_host(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 11/31] mmc: sdhci: convert generic bus width setup to library function
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Barry Song, spear-devel, Stephen Warren, Anton Vorontsov,
	Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra, linuxppc-dev

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  6 ++---
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  6 ++---
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  6 ++---
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 ++---
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  8 +++----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  2 +-
 drivers/mmc/host/sdhci-tegra.c     |  5 ++---
 drivers/mmc/host/sdhci.c           | 45 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  5 +++--
 19 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 9ce17f6e4014..b138bfdd3843 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -102,10 +102,12 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 7a190fe4dff1..bf851a6e4e8e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -208,6 +208,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index f6d8d67c545f..7ab69af979b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -133,6 +133,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_b = bcm2835_sdhci_readb,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index f2cc26633cb2..5e0cc9c47887 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -82,6 +82,7 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 8424839660f8..7eef4890fd22 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b0b4eea8d232..568239d84cbe 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -668,7 +668,7 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 	return -ENOSYS;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -686,8 +686,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
 			SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
@@ -888,7 +886,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_max_clock = esdhc_pltfm_get_max_clock,
 	.get_min_clock = esdhc_pltfm_get_min_clock,
 	.get_ro = esdhc_pltfm_get_ro,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
 };
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f7c7cf62437d..9bb1dd263a45 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -54,6 +54,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 0b249970b119..86b8326e77c3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -269,7 +269,7 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
 		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -289,8 +289,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
 			ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
-
-	return 0;
 }
 
 static const struct sdhci_ops sdhci_esdhc_ops = {
@@ -310,7 +308,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.platform_resume = esdhc_of_resume,
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 57c514a81ca5..4d5d0015e392 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 0955777b6c7e..59cc938b450d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1011,7 +1011,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
 	return 0;
 }
 
-static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -1032,8 +1032,6 @@ static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
@@ -1061,7 +1059,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
-	.platform_bus_width	= sdhci_pci_bus_width,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_pci_set_bus_width,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bef250e95418..40b0fe224f9d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d51e061ec576..d24c282e5eb8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -88,7 +88,7 @@ static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 	u16 tmp;
@@ -107,14 +107,12 @@ static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
 	}
 	writew(tmp, host->ioaddr + SD_CE_ATA_2);
 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.platform_reset_exit = pxav2_set_private_registers,
-	.platform_bus_width = pxav2_mmc_set_width,
=+DO NOT APPLY+=	.set_bus_width = pxav2_mmc_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 793dacd3b841..89c932d9685e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -172,6 +172,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 6debda952155..1c4ebd69d4e5 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -330,14 +330,14 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 }
 
 /**
- * sdhci_s3c_platform_bus_width - support 8bit buswidth
=+DO NOT APPLY+= * sdhci_s3c_set_bus_width - support 8bit buswidth
  * @host: The SDHCI host being queried
  * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  *
  * We have 8-bit width support but is not a v3 controller.
  * So we add platform_bus_width() and support 8bit width.
  */
-static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -359,15 +359,13 @@ static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static struct sdhci_ops sdhci_s3c_ops = {
 	.get_max_clock		= sdhci_s3c_get_max_clk,
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
-	.platform_bus_width	= sdhci_s3c_platform_bus_width,
=+DO NOT APPLY+=	.set_bus_width		= sdhci_s3c_set_bus_width,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 696122c1b468..16fcd48f9556 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -29,6 +29,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 2dba9f8d1760..549e9e0edb27 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,7 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
-	/* Nothing to do for now. */
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a835898a68dd..feed799b827a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -127,7 +127,7 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
=+DO NOT APPLY+=static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 {
 	u32 ctrl;
 
@@ -144,7 +144,6 @@ static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
 			ctrl &= ~SDHCI_CTRL_4BITBUS;
 	}
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	return 0;
 }
 
 static const struct sdhci_ops tegra_sdhci_ops = {
@@ -152,7 +151,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
-	.platform_bus_width = tegra_sdhci_buswidth,
=+DO NOT APPLY+=	.set_bus_width = tegra_sdhci_set_bus_width,
 	.platform_reset_exit = tegra_sdhci_reset_exit,
 };
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5fe211dfb792..ad744941fdf8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1413,6 +1413,27 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u8 ctrl;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=	if (width == MMC_BUS_WIDTH_8) {
=+DO NOT APPLY+=		ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=	} else {
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=		if (width == MMC_BUS_WIDTH_4)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		else
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1458,29 +1479,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
 
-	/*
-	 * If your platform has 8-bit width support but is not a v3 controller,
-	 * or if it requires special setup code, you should implement that in
-	 * platform_bus_width().
-	 */
-	if (host->ops->platform_bus_width) {
-		host->ops->platform_bus_width(host, ios->bus_width);
-	} else {
-		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-		if (ios->bus_width == MMC_BUS_WIDTH_8) {
-			ctrl &= ~SDHCI_CTRL_4BITBUS;
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl |= SDHCI_CTRL_8BITBUS;
-		} else {
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl &= ~SDHCI_CTRL_8BITBUS;
-			if (ios->bus_width == MMC_BUS_WIDTH_4)
-				ctrl |= SDHCI_CTRL_4BITBUS;
-			else
-				ctrl &= ~SDHCI_CTRL_4BITBUS;
-		}
-		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	}
=+DO NOT APPLY+=	host->ops->set_bus_width(host, ios->bus_width);
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index fc6f81d2f377..0301f928eb11 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -281,8 +281,7 @@ struct sdhci_ops {
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
 	unsigned int	(*get_min_clock)(struct sdhci_host *host);
 	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
-	int		(*platform_bus_width)(struct sdhci_host *host,
-					       int width);
=+DO NOT APPLY+=	void		(*set_bus_width)(struct sdhci_host *host, int width);
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
@@ -402,6 +401,8 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
 extern int sdhci_resume_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 11/31] mmc: sdhci: convert generic bus width setup to library function
@ 2014-02-18 15:09   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  6 ++---
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  6 ++---
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  6 ++---
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 ++---
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  8 +++----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  2 +-
 drivers/mmc/host/sdhci-tegra.c     |  5 ++---
 drivers/mmc/host/sdhci.c           | 45 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  5 +++--
 19 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 9ce17f6e4014..b138bfdd3843 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -102,10 +102,12 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 7a190fe4dff1..bf851a6e4e8e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -208,6 +208,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index f6d8d67c545f..7ab69af979b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -133,6 +133,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_b = bcm2835_sdhci_readb,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index f2cc26633cb2..5e0cc9c47887 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -82,6 +82,7 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 8424839660f8..7eef4890fd22 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b0b4eea8d232..568239d84cbe 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -668,7 +668,7 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 	return -ENOSYS;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -686,8 +686,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
 			SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
@@ -888,7 +886,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_max_clock = esdhc_pltfm_get_max_clock,
 	.get_min_clock = esdhc_pltfm_get_min_clock,
 	.get_ro = esdhc_pltfm_get_ro,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
 };
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f7c7cf62437d..9bb1dd263a45 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -54,6 +54,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 0b249970b119..86b8326e77c3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -269,7 +269,7 @@ static void esdhc_of_platform_init(struct sdhci_host *host)
 		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 }
 
-static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 {
 	u32 ctrl;
 
@@ -289,8 +289,6 @@ static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
 
 	clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
 			ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
-
-	return 0;
 }
 
 static const struct sdhci_ops sdhci_esdhc_ops = {
@@ -310,7 +308,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.platform_resume = esdhc_of_resume,
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
-	.platform_bus_width = esdhc_pltfm_bus_width,
=+DO NOT APPLY+=	.set_bus_width = esdhc_pltfm_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 57c514a81ca5..4d5d0015e392 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 0955777b6c7e..59cc938b450d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1011,7 +1011,7 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
 	return 0;
 }
 
-static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -1032,8 +1032,6 @@ static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
@@ -1061,7 +1059,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
-	.platform_bus_width	= sdhci_pci_bus_width,
=+DO NOT APPLY+=	.set_bus_width	= sdhci_pci_set_bus_width,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bef250e95418..40b0fe224f9d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d51e061ec576..d24c282e5eb8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -88,7 +88,7 @@ static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 	u16 tmp;
@@ -107,14 +107,12 @@ static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
 	}
 	writew(tmp, host->ioaddr + SD_CE_ATA_2);
 	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.platform_reset_exit = pxav2_set_private_registers,
-	.platform_bus_width = pxav2_mmc_set_width,
=+DO NOT APPLY+=	.set_bus_width = pxav2_mmc_set_bus_width,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 793dacd3b841..89c932d9685e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -172,6 +172,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 6debda952155..1c4ebd69d4e5 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -330,14 +330,14 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 }
 
 /**
- * sdhci_s3c_platform_bus_width - support 8bit buswidth
=+DO NOT APPLY+= * sdhci_s3c_set_bus_width - support 8bit buswidth
  * @host: The SDHCI host being queried
  * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  *
  * We have 8-bit width support but is not a v3 controller.
  * So we add platform_bus_width() and support 8bit width.
  */
-static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+=static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
 {
 	u8 ctrl;
 
@@ -359,15 +359,13 @@ static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
 	}
 
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-
-	return 0;
 }
 
 static struct sdhci_ops sdhci_s3c_ops = {
 	.get_max_clock		= sdhci_s3c_get_max_clk,
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
-	.platform_bus_width	= sdhci_s3c_platform_bus_width,
=+DO NOT APPLY+=	.set_bus_width		= sdhci_s3c_set_bus_width,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 696122c1b468..16fcd48f9556 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -29,6 +29,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 2dba9f8d1760..549e9e0edb27 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,7 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
-	/* Nothing to do for now. */
=+DO NOT APPLY+=	.set_bus_width = sdhci_set_bus_width,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a835898a68dd..feed799b827a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -127,7 +127,7 @@ static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
 	}
 }
 
-static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
=+DO NOT APPLY+=static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 {
 	u32 ctrl;
 
@@ -144,7 +144,6 @@ static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
 			ctrl &= ~SDHCI_CTRL_4BITBUS;
 	}
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	return 0;
 }
 
 static const struct sdhci_ops tegra_sdhci_ops = {
@@ -152,7 +151,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
-	.platform_bus_width = tegra_sdhci_buswidth,
=+DO NOT APPLY+=	.set_bus_width = tegra_sdhci_set_bus_width,
 	.platform_reset_exit = tegra_sdhci_reset_exit,
 };
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5fe211dfb792..ad744941fdf8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1413,6 +1413,27 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u8 ctrl;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=	if (width == MMC_BUS_WIDTH_8) {
=+DO NOT APPLY+=		ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=	} else {
=+DO NOT APPLY+=		if (host->version >= SDHCI_SPEC_300)
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_8BITBUS;
=+DO NOT APPLY+=		if (width == MMC_BUS_WIDTH_4)
=+DO NOT APPLY+=			ctrl |= SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=		else
=+DO NOT APPLY+=			ctrl &= ~SDHCI_CTRL_4BITBUS;
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1458,29 +1479,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
 
-	/*
-	 * If your platform has 8-bit width support but is not a v3 controller,
-	 * or if it requires special setup code, you should implement that in
-	 * platform_bus_width().
-	 */
-	if (host->ops->platform_bus_width) {
-		host->ops->platform_bus_width(host, ios->bus_width);
-	} else {
-		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-		if (ios->bus_width == MMC_BUS_WIDTH_8) {
-			ctrl &= ~SDHCI_CTRL_4BITBUS;
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl |= SDHCI_CTRL_8BITBUS;
-		} else {
-			if (host->version >= SDHCI_SPEC_300)
-				ctrl &= ~SDHCI_CTRL_8BITBUS;
-			if (ios->bus_width == MMC_BUS_WIDTH_4)
-				ctrl |= SDHCI_CTRL_4BITBUS;
-			else
-				ctrl &= ~SDHCI_CTRL_4BITBUS;
-		}
-		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
-	}
=+DO NOT APPLY+=	host->ops->set_bus_width(host, ios->bus_width);
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index fc6f81d2f377..0301f928eb11 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -281,8 +281,7 @@ struct sdhci_ops {
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
 	unsigned int	(*get_min_clock)(struct sdhci_host *host);
 	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
-	int		(*platform_bus_width)(struct sdhci_host *host,
-					       int width);
=+DO NOT APPLY+=	void		(*set_bus_width)(struct sdhci_host *host, int width);
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
@@ -402,6 +401,8 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
 extern int sdhci_resume_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 12/31] mmc: sdhci: convert reset into a library function
  2014-02-18 15:08 ` Russell King - ARM Linux
  (?)
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Michal Simek, Anton Vorontsov, Ben Dooks, Barry Song,
	Viresh Kumar, Stephen Warren, Thierry Reding, linuxppc-dev,
	spear-devel, linux-tegra

Rather than having platform_reset_enter/platform_reset_exit methods,
turn the core of the reset handling into a library function which
platforms can call at the appropriate moment in their (new) reset
method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 +++--
 drivers/mmc/host/sdhci-pxav3.c     |  6 +++--
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  6 +++--
 drivers/mmc/host/sdhci.c           | 47 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  4 ++--
 19 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index b138bfdd3843..1ded6690be43 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -103,11 +103,13 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index bf851a6e4e8e..4c82ecb7a71e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -209,6 +209,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 7ab69af979b4..289b1c80d5fc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -134,6 +134,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 5e0cc9c47887..87af66bb1ea8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -83,6 +83,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset          = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 7eef4890fd22..4c0191bff85d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -87,6 +87,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 568239d84cbe..b1d74fa33c5f 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -888,6 +888,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_ro = esdhc_pltfm_get_ro,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 9bb1dd263a45..faef21740584 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -55,6 +55,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 86b8326e77c3..4530f9957f20 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 4d5d0015e392..fb01958cb18e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -59,6 +59,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 59cc938b450d..88a6c6b87d70 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1060,6 +1060,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
=+DO NOT APPLY+=	.reset		= sdhci_reset,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 40b0fe224f9d..bfbf467b61c7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d24c282e5eb8..2eee0c8b88eb 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -51,11 +51,13 @@
 #define MMC_CARD		0x1000
 #define MMC_WIDTH		0x0100
 
-static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav2_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		u16 tmp = 0;
 
@@ -111,8 +113,8 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
-	.platform_reset_exit = pxav2_set_private_registers,
 	.set_bus_width = pxav2_mmc_set_bus_width,
=+DO NOT APPLY+=	.reset         = pxav2_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 89c932d9685e..e6ea46c4d233 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,11 +57,13 @@
 #define SDCE_MISC_INT		(1<<2)
 #define SDCE_MISC_INT_EN	(1<<1)
 
-static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav3_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		/*
 		 * tune timing of read data/command when crc error happen
@@ -168,11 +170,11 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
-	.platform_reset_exit = pxav3_set_private_registers,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = pxav3_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 1c4ebd69d4e5..619047be00c9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -366,6 +366,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
=+DO NOT APPLY+=	.reset			= sdhci_reset,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 16fcd48f9556..5d79e10e1ba2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -30,6 +30,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 549e9e0edb27..ef990974a522 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -38,6 +38,7 @@ struct spear_sdhci {
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index feed799b827a..7754c0319fda 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -108,12 +108,14 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
 	return mmc_gpio_get_ro(host->mmc);
 }
 
-static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (!(mask & SDHCI_RESET_ALL))
 		return;
 
@@ -152,7 +154,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
 	.set_bus_width = tegra_sdhci_set_bus_width,
-	.platform_reset_exit = tegra_sdhci_reset_exit,
=+DO NOT APPLY+=	.reset      = tegra_sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ad744941fdf8..10540192d544 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -163,17 +163,9 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
 	sdhci_set_card_detection(host, false);
 }
 
-static void sdhci_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
-	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
-		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			SDHCI_CARD_PRESENT))
-			return;
-	}
-
-	if (host->ops->platform_reset_enter)
-		host->ops->platform_reset_enter(host, mask);
 
 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
@@ -198,9 +190,18 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 		timeout--;
 		mdelay(1);
 	}
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_reset);
=+DO NOT APPLY+=
=+DO NOT APPLY+=static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
=+DO NOT APPLY+=		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=			SDHCI_CARD_PRESENT))
=+DO NOT APPLY+=			return;
=+DO NOT APPLY+=	}
 
-	if (host->ops->platform_reset_exit)
-		host->ops->platform_reset_exit(host, mask);
=+DO NOT APPLY+=	host->ops->reset(host, mask);
 
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
 		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
@@ -218,9 +219,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
 static void sdhci_init(struct sdhci_host *host, int soft)
 {
 	if (soft)
-		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
 	else
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
 		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
@@ -962,8 +963,8 @@ static void sdhci_finish_data(struct sdhci_host *host)
 		 * upon error conditions.
 		 */
 		if (data->error) {
-			sdhci_reset(host, SDHCI_RESET_CMD);
-			sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_DATA);
 		}
 
 		sdhci_send_command(host, data->stop);
@@ -1585,7 +1586,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	 * it on each ios seems to solve the problem.
 	 */
 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
-		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -2082,8 +2083,8 @@ static void sdhci_card_event(struct mmc_host *mmc)
 		pr_err("%s: Resetting controller.\n",
 			mmc_hostname(host->mmc));
 
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
@@ -2151,8 +2152,8 @@ static void sdhci_tasklet_finish(unsigned long param)
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 	}
 
 	host->mrq = NULL;
@@ -2789,7 +2790,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (debug_quirks2)
 		host->quirks2 = debug_quirks2;
 
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
@@ -3272,7 +3273,7 @@ int sdhci_add_host(struct sdhci_host *host)
 
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
@@ -3314,7 +3315,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 #endif
 
 	if (!dead)
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0301f928eb11..7d84cb3b0e00 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -285,8 +285,7 @@ struct sdhci_ops {
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
-	void	(*platform_reset_enter)(struct sdhci_host *host, u8 mask);
-	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=	void		(*reset)(struct sdhci_host *host, u8 mask);
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
@@ -402,6 +401,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 }
 
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 12/31] mmc: sdhci: convert reset into a library function
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Barry Song, spear-devel, Stephen Warren, Anton Vorontsov,
	Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra, linuxppc-dev

Rather than having platform_reset_enter/platform_reset_exit methods,
turn the core of the reset handling into a library function which
platforms can call at the appropriate moment in their (new) reset
method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 +++--
 drivers/mmc/host/sdhci-pxav3.c     |  6 +++--
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  6 +++--
 drivers/mmc/host/sdhci.c           | 47 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  4 ++--
 19 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index b138bfdd3843..1ded6690be43 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -103,11 +103,13 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index bf851a6e4e8e..4c82ecb7a71e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -209,6 +209,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 7ab69af979b4..289b1c80d5fc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -134,6 +134,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 5e0cc9c47887..87af66bb1ea8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -83,6 +83,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset          = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 7eef4890fd22..4c0191bff85d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -87,6 +87,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 568239d84cbe..b1d74fa33c5f 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -888,6 +888,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_ro = esdhc_pltfm_get_ro,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 9bb1dd263a45..faef21740584 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -55,6 +55,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 86b8326e77c3..4530f9957f20 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 4d5d0015e392..fb01958cb18e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -59,6 +59,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 59cc938b450d..88a6c6b87d70 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1060,6 +1060,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
=+DO NOT APPLY+=	.reset		= sdhci_reset,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 40b0fe224f9d..bfbf467b61c7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d24c282e5eb8..2eee0c8b88eb 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -51,11 +51,13 @@
 #define MMC_CARD		0x1000
 #define MMC_WIDTH		0x0100
 
-static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav2_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		u16 tmp = 0;
 
@@ -111,8 +113,8 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
-	.platform_reset_exit = pxav2_set_private_registers,
 	.set_bus_width = pxav2_mmc_set_bus_width,
=+DO NOT APPLY+=	.reset         = pxav2_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 89c932d9685e..e6ea46c4d233 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,11 +57,13 @@
 #define SDCE_MISC_INT		(1<<2)
 #define SDCE_MISC_INT_EN	(1<<1)
 
-static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav3_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		/*
 		 * tune timing of read data/command when crc error happen
@@ -168,11 +170,11 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
-	.platform_reset_exit = pxav3_set_private_registers,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = pxav3_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 1c4ebd69d4e5..619047be00c9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -366,6 +366,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
=+DO NOT APPLY+=	.reset			= sdhci_reset,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 16fcd48f9556..5d79e10e1ba2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -30,6 +30,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 549e9e0edb27..ef990974a522 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -38,6 +38,7 @@ struct spear_sdhci {
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index feed799b827a..7754c0319fda 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -108,12 +108,14 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
 	return mmc_gpio_get_ro(host->mmc);
 }
 
-static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (!(mask & SDHCI_RESET_ALL))
 		return;
 
@@ -152,7 +154,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
 	.set_bus_width = tegra_sdhci_set_bus_width,
-	.platform_reset_exit = tegra_sdhci_reset_exit,
=+DO NOT APPLY+=	.reset      = tegra_sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ad744941fdf8..10540192d544 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -163,17 +163,9 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
 	sdhci_set_card_detection(host, false);
 }
 
-static void sdhci_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
-	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
-		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			SDHCI_CARD_PRESENT))
-			return;
-	}
-
-	if (host->ops->platform_reset_enter)
-		host->ops->platform_reset_enter(host, mask);
 
 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
@@ -198,9 +190,18 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 		timeout--;
 		mdelay(1);
 	}
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_reset);
=+DO NOT APPLY+=
=+DO NOT APPLY+=static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
=+DO NOT APPLY+=		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=			SDHCI_CARD_PRESENT))
=+DO NOT APPLY+=			return;
=+DO NOT APPLY+=	}
 
-	if (host->ops->platform_reset_exit)
-		host->ops->platform_reset_exit(host, mask);
=+DO NOT APPLY+=	host->ops->reset(host, mask);
 
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
 		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
@@ -218,9 +219,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
 static void sdhci_init(struct sdhci_host *host, int soft)
 {
 	if (soft)
-		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
 	else
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
 		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
@@ -962,8 +963,8 @@ static void sdhci_finish_data(struct sdhci_host *host)
 		 * upon error conditions.
 		 */
 		if (data->error) {
-			sdhci_reset(host, SDHCI_RESET_CMD);
-			sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_DATA);
 		}
 
 		sdhci_send_command(host, data->stop);
@@ -1585,7 +1586,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	 * it on each ios seems to solve the problem.
 	 */
 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
-		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -2082,8 +2083,8 @@ static void sdhci_card_event(struct mmc_host *mmc)
 		pr_err("%s: Resetting controller.\n",
 			mmc_hostname(host->mmc));
 
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
@@ -2151,8 +2152,8 @@ static void sdhci_tasklet_finish(unsigned long param)
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 	}
 
 	host->mrq = NULL;
@@ -2789,7 +2790,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (debug_quirks2)
 		host->quirks2 = debug_quirks2;
 
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
@@ -3272,7 +3273,7 @@ int sdhci_add_host(struct sdhci_host *host)
 
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
@@ -3314,7 +3315,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 #endif
 
 	if (!dead)
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0301f928eb11..7d84cb3b0e00 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -285,8 +285,7 @@ struct sdhci_ops {
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
-	void	(*platform_reset_enter)(struct sdhci_host *host, u8 mask);
-	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=	void		(*reset)(struct sdhci_host *host, u8 mask);
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
@@ -402,6 +401,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 }
 
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 12/31] mmc: sdhci: convert reset into a library function
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than having platform_reset_enter/platform_reset_exit methods,
turn the core of the reset handling into a library function which
platforms can call at the appropriate moment in their (new) reset
method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc-imx.c |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  6 +++--
 drivers/mmc/host/sdhci-pxav3.c     |  6 +++--
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  6 +++--
 drivers/mmc/host/sdhci.c           | 47 +++++++++++++++++++-------------------
 drivers/mmc/host/sdhci.h           |  4 ++--
 19 files changed, 53 insertions(+), 31 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index b138bfdd3843..1ded6690be43 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -103,11 +103,13 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index bf851a6e4e8e..4c82ecb7a71e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -209,6 +209,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 7ab69af979b4..289b1c80d5fc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -134,6 +134,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 5e0cc9c47887..87af66bb1ea8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -83,6 +83,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.get_max_clock	= sdhci_cns3xxx_get_max_clk,
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset          = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 7eef4890fd22..4c0191bff85d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -87,6 +87,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 568239d84cbe..b1d74fa33c5f 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -888,6 +888,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_ro = esdhc_pltfm_get_ro,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 9bb1dd263a45..faef21740584 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -55,6 +55,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 86b8326e77c3..4530f9957f20 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 4d5d0015e392..fb01958cb18e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -59,6 +59,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 59cc938b450d..88a6c6b87d70 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1060,6 +1060,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
=+DO NOT APPLY+=	.reset		= sdhci_reset,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 40b0fe224f9d..bfbf467b61c7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index d24c282e5eb8..2eee0c8b88eb 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -51,11 +51,13 @@
 #define MMC_CARD		0x1000
 #define MMC_WIDTH		0x0100
 
-static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav2_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		u16 tmp = 0;
 
@@ -111,8 +113,8 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
-	.platform_reset_exit = pxav2_set_private_registers,
 	.set_bus_width = pxav2_mmc_set_bus_width,
=+DO NOT APPLY+=	.reset         = pxav2_reset,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 89c932d9685e..e6ea46c4d233 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,11 +57,13 @@
 #define SDCE_MISC_INT		(1<<2)
 #define SDCE_MISC_INT_EN	(1<<1)
 
-static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void pxav3_reset(struct sdhci_host *host, u8 mask)
 {
 	struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
 	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (mask == SDHCI_RESET_ALL) {
 		/*
 		 * tune timing of read data/command when crc error happen
@@ -168,11 +170,11 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
-	.platform_reset_exit = pxav3_set_private_registers,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = pxav3_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 1c4ebd69d4e5..619047be00c9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -366,6 +366,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.set_clock		= sdhci_s3c_set_clock,
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
=+DO NOT APPLY+=	.reset			= sdhci_reset,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 16fcd48f9556..5d79e10e1ba2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -30,6 +30,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 549e9e0edb27..ef990974a522 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -38,6 +38,7 @@ struct spear_sdhci {
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_bus_width = sdhci_set_bus_width,
=+DO NOT APPLY+=	.reset = sdhci_reset,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index feed799b827a..7754c0319fda 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -108,12 +108,14 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
 	return mmc_gpio_get_ro(host->mmc);
 }
 
-static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
 
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
 	if (!(mask & SDHCI_RESET_ALL))
 		return;
 
@@ -152,7 +154,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
 	.set_bus_width = tegra_sdhci_set_bus_width,
-	.platform_reset_exit = tegra_sdhci_reset_exit,
=+DO NOT APPLY+=	.reset      = tegra_sdhci_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ad744941fdf8..10540192d544 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -163,17 +163,9 @@ static void sdhci_disable_card_detection(struct sdhci_host *host)
 	sdhci_set_card_detection(host, false);
 }
 
-static void sdhci_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
-	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
-		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
-			SDHCI_CARD_PRESENT))
-			return;
-	}
-
-	if (host->ops->platform_reset_enter)
-		host->ops->platform_reset_enter(host, mask);
 
 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
@@ -198,9 +190,18 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 		timeout--;
 		mdelay(1);
 	}
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_reset);
=+DO NOT APPLY+=
=+DO NOT APPLY+=static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
=+DO NOT APPLY+=		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
=+DO NOT APPLY+=			SDHCI_CARD_PRESENT))
=+DO NOT APPLY+=			return;
=+DO NOT APPLY+=	}
 
-	if (host->ops->platform_reset_exit)
-		host->ops->platform_reset_exit(host, mask);
=+DO NOT APPLY+=	host->ops->reset(host, mask);
 
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
 		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
@@ -218,9 +219,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
 static void sdhci_init(struct sdhci_host *host, int soft)
 {
 	if (soft)
-		sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
 	else
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
 		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
@@ -962,8 +963,8 @@ static void sdhci_finish_data(struct sdhci_host *host)
 		 * upon error conditions.
 		 */
 		if (data->error) {
-			sdhci_reset(host, SDHCI_RESET_CMD);
-			sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=			sdhci_do_reset(host, SDHCI_RESET_DATA);
 		}
 
 		sdhci_send_command(host, data->stop);
@@ -1585,7 +1586,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 	 * it on each ios seems to solve the problem.
 	 */
 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
-		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -2082,8 +2083,8 @@ static void sdhci_card_event(struct mmc_host *mmc)
 		pr_err("%s: Resetting controller.\n",
 			mmc_hostname(host->mmc));
 
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
@@ -2151,8 +2152,8 @@ static void sdhci_tasklet_finish(unsigned long param)
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
-		sdhci_reset(host, SDHCI_RESET_CMD);
-		sdhci_reset(host, SDHCI_RESET_DATA);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_CMD);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_DATA);
 	}
 
 	host->mrq = NULL;
@@ -2789,7 +2790,7 @@ int sdhci_add_host(struct sdhci_host *host)
 	if (debug_quirks2)
 		host->quirks2 = debug_quirks2;
 
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
@@ -3272,7 +3273,7 @@ int sdhci_add_host(struct sdhci_host *host)
 
 #ifdef SDHCI_USE_LEDS_CLASS
 reset:
-	sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=	sdhci_do_reset(host, SDHCI_RESET_ALL);
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
 	free_irq(host->irq, host);
@@ -3314,7 +3315,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 #endif
 
 	if (!dead)
-		sdhci_reset(host, SDHCI_RESET_ALL);
=+DO NOT APPLY+=		sdhci_do_reset(host, SDHCI_RESET_ALL);
 
 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 0301f928eb11..7d84cb3b0e00 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -285,8 +285,7 @@ struct sdhci_ops {
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
-	void	(*platform_reset_enter)(struct sdhci_host *host, u8 mask);
-	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=	void		(*reset)(struct sdhci_host *host, u8 mask);
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
@@ -402,6 +401,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 }
 
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
=+DO NOT APPLY+=void sdhci_reset(struct sdhci_host *host, u8 mask);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 13/31] mmc: sdhci: move FSL ESDHC reset handling quirk into esdhc code
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

The Freescale esdhc driver is the only driver which needs the interrupt
registers restored after a reset.  Move this quirk to be part of the
ESDHC driver implementation.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 10 +++++++++-
 drivers/mmc/host/sdhci-esdhc.h     |  3 +--
 drivers/mmc/host/sdhci.c           |  5 -----
 include/linux/mmc/sdhci.h          |  2 --
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b1d74fa33c5f..812c5772d900 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -876,6 +876,14 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 	return esdhc_change_pinstate(host, uhs);
 }
 
=+DO NOT APPLY+=static void esdhc_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 static struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl_le,
 	.read_w = esdhc_readw_le,
@@ -888,7 +896,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_ro = esdhc_pltfm_get_ro,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
-	.reset = sdhci_reset,
=+DO NOT APPLY+=	.reset = esdhc_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index a7d9f95a7b03..de69bddc3afc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc.h
@@ -22,8 +22,7 @@
 				SDHCI_QUIRK_NO_BUSY_IRQ | \
 				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
-				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
-				SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
=+DO NOT APPLY+=				SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
 #define ESDHC_SYSTEM_CONTROL	0x2c
 #define ESDHC_CLOCK_MASK	0x0000fff0
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 10540192d544..bcf4f9ec0ea4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -203,11 +203,6 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
 
 	host->ops->reset(host, mask);
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
-		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
-		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
-	}
-
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
 			host->ops->enable_dma(host);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 493c57aee4cb..801579313789 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -61,8 +61,6 @@ struct sdhci_host {
 #define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
-/* Controller losing signal/interrupt enable states after reset */
-#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET		(1<<19)
 /* Controller has to be forced to use block size of 2048 bytes */
 #define SDHCI_QUIRK_FORCE_BLK_SZ_2048			(1<<20)
 /* Controller cannot do multi-block transfers */
-- 
1.8.3.1


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

* [PATCH RFC 13/31] mmc: sdhci: move FSL ESDHC reset handling quirk into esdhc code
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

The Freescale esdhc driver is the only driver which needs the interrupt
registers restored after a reset.  Move this quirk to be part of the
ESDHC driver implementation.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 10 +++++++++-
 drivers/mmc/host/sdhci-esdhc.h     |  3 +--
 drivers/mmc/host/sdhci.c           |  5 -----
 include/linux/mmc/sdhci.h          |  2 --
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b1d74fa33c5f..812c5772d900 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -876,6 +876,14 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 	return esdhc_change_pinstate(host, uhs);
 }
 
=+DO NOT APPLY+=static void esdhc_reset(struct sdhci_host *host, u8 mask)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	sdhci_reset(host, mask);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
=+DO NOT APPLY+=	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
 static struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl_le,
 	.read_w = esdhc_readw_le,
@@ -888,7 +896,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.get_ro = esdhc_pltfm_get_ro,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.set_uhs_signaling = esdhc_set_uhs_signaling,
-	.reset = sdhci_reset,
=+DO NOT APPLY+=	.reset = esdhc_reset,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index a7d9f95a7b03..de69bddc3afc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc.h
@@ -22,8 +22,7 @@
 				SDHCI_QUIRK_NO_BUSY_IRQ | \
 				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
-				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
-				SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
=+DO NOT APPLY+=				SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
 #define ESDHC_SYSTEM_CONTROL	0x2c
 #define ESDHC_CLOCK_MASK	0x0000fff0
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 10540192d544..bcf4f9ec0ea4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -203,11 +203,6 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
 
 	host->ops->reset(host, mask);
 
-	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) {
-		sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
-		sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
-	}
-
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
 		if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
 			host->ops->enable_dma(host);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 493c57aee4cb..801579313789 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -61,8 +61,6 @@ struct sdhci_host {
 #define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
-/* Controller losing signal/interrupt enable states after reset */
-#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET		(1<<19)
 /* Controller has to be forced to use block size of 2048 bytes */
 #define SDHCI_QUIRK_FORCE_BLK_SZ_2048			(1<<20)
 /* Controller cannot do multi-block transfers */
-- 
1.8.3.1

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

* [PATCH RFC 14/31] mmc: sdhci: avoid sync'ing the SG if there's no misalignment
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

On read, we don't need to sync the whole scatterlist and then check
whether any segments need copying - if we check first, we avoid
potentially expensive cache handling.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bcf4f9ec0ea4..e918e17c39e4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -602,6 +602,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	u8 *align;
 	char *buffer;
 	unsigned long flags;
=+DO NOT APPLY+=	bool has_unaligned;
 
 	if (data->flags & MMC_DATA_READ)
 		direction = DMA_FROM_DEVICE;
@@ -614,7 +615,15 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
 
-	if (data->flags & MMC_DATA_READ) {
=+DO NOT APPLY+=	/* Do a quick scan of the SG list for any unaligned mappings */
=+DO NOT APPLY+=	has_unaligned = false;
=+DO NOT APPLY+=	for_each_sg(data->sg, sg, host->sg_count, i)
=+DO NOT APPLY+=		if (sg_dma_address(sg) & 3) {
=+DO NOT APPLY+=			has_unaligned = true;
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (has_unaligned && data->flags & MMC_DATA_READ) {
 		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
 			data->sg_len, direction);
 
-- 
1.8.3.1


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

* [PATCH RFC 14/31] mmc: sdhci: avoid sync'ing the SG if there's no misalignment
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On read, we don't need to sync the whole scatterlist and then check
whether any segments need copying - if we check first, we avoid
potentially expensive cache handling.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bcf4f9ec0ea4..e918e17c39e4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -602,6 +602,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	u8 *align;
 	char *buffer;
 	unsigned long flags;
=+DO NOT APPLY+=	bool has_unaligned;
 
 	if (data->flags & MMC_DATA_READ)
 		direction = DMA_FROM_DEVICE;
@@ -614,7 +615,15 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
 
-	if (data->flags & MMC_DATA_READ) {
=+DO NOT APPLY+=	/* Do a quick scan of the SG list for any unaligned mappings */
=+DO NOT APPLY+=	has_unaligned = false;
=+DO NOT APPLY+=	for_each_sg(data->sg, sg, host->sg_count, i)
=+DO NOT APPLY+=		if (sg_dma_address(sg) & 3) {
=+DO NOT APPLY+=			has_unaligned = true;
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (has_unaligned && data->flags & MMC_DATA_READ) {
 		dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
 			data->sg_len, direction);
 
-- 
1.8.3.1

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

* [PATCH RFC 15/31] mmc: sdhci: convert ADMA descriptors to a coherent allocation
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Rather than using the streaming API, use the coherent allocator to
provide this memory, thereby eliminating cache flushing of it each
time we map and unmap it.  This results in a 7.5% increase in
transfer speed with a UHS-1 card operating in 3.3v mode at a clock
of 49.5MHz.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e918e17c39e4..d046b4eee335 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -44,6 +44,8 @@
 
 #define MAX_TUNING_LOOP 40
 
=+DO NOT APPLY+=#define ADMA_SIZE	((128 * 2 + 1) * 4)
=+DO NOT APPLY+=
 static unsigned int debug_quirks = 0;
 static unsigned int debug_quirks2;
 
@@ -481,11 +483,6 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 	else
 		direction = DMA_TO_DEVICE;
 
-	/*
-	 * The ADMA descriptor table is mapped further down as we
-	 * need to fill it with data first.
-	 */
-
 	host->align_addr = dma_map_single(mmc_dev(host->mmc),
 		host->align_buffer, 128 * 4, direction);
 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
@@ -546,7 +543,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 		 * If this triggers then we have a calculation bug
 		 * somewhere. :/
 		 */
-		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
=+DO NOT APPLY+=		WARN_ON((desc - host->adma_desc) > ADMA_SIZE);
 	}
 
 	if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
@@ -574,17 +571,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 			host->align_addr, 128 * 4, direction);
 	}
 
-	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
-		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
-	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
-		goto unmap_entries;
-	BUG_ON(host->adma_addr & 0x3);
-
 	return 0;
 
-unmap_entries:
-	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-		data->sg_len, direction);
 unmap_align:
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
@@ -609,9 +597,6 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	else
 		direction = DMA_TO_DEVICE;
 
-	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
-		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
-
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
 
@@ -2854,15 +2839,29 @@ int sdhci_add_host(struct sdhci_host *host)
 		 * (128) and potentially one alignment transfer for
 		 * each of those entries.
 		 */
-		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
=+DO NOT APPLY+=		host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
=+DO NOT APPLY+=						     ADMA_SIZE, &host->adma_addr,
=+DO NOT APPLY+=						     GFP_KERNEL);
 		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
 		if (!host->adma_desc || !host->align_buffer) {
-			kfree(host->adma_desc);
=+DO NOT APPLY+=			dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=					  host->adma_desc, host->adma_addr);
 			kfree(host->align_buffer);
 			pr_warning("%s: Unable to allocate ADMA "
 				"buffers. Falling back to standard DMA.\n",
 				mmc_hostname(mmc));
 			host->flags &= ~SDHCI_USE_ADMA;
=+DO NOT APPLY+=			host->adma_desc = NULL;
=+DO NOT APPLY+=			host->align_buffer = NULL;
=+DO NOT APPLY+=		} else if (host->adma_addr & 3) {
=+DO NOT APPLY+=			pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
=+DO NOT APPLY+=				   mmc_hostname(mmc));
=+DO NOT APPLY+=			host->flags &= ~SDHCI_USE_ADMA;
=+DO NOT APPLY+=			dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=					  host->adma_desc, host->adma_addr);
=+DO NOT APPLY+=			kfree(host->align_buffer);
=+DO NOT APPLY+=			host->adma_desc = NULL;
=+DO NOT APPLY+=			host->align_buffer = NULL;
 		}
 	}
 
@@ -3339,7 +3338,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 		regulator_put(host->vqmmc);
 	}
 
-	kfree(host->adma_desc);
=+DO NOT APPLY+=	if (host->adma_desc)
=+DO NOT APPLY+=		dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=				  host->adma_desc, host->adma_addr);
 	kfree(host->align_buffer);
 
 	host->adma_desc = NULL;
-- 
1.8.3.1


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

* [PATCH RFC 15/31] mmc: sdhci: convert ADMA descriptors to a coherent allocation
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than using the streaming API, use the coherent allocator to
provide this memory, thereby eliminating cache flushing of it each
time we map and unmap it.  This results in a 7.5% increase in
transfer speed with a UHS-1 card operating in 3.3v mode at a clock
of 49.5MHz.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 43 ++++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e918e17c39e4..d046b4eee335 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -44,6 +44,8 @@
 
 #define MAX_TUNING_LOOP 40
 
=+DO NOT APPLY+=#define ADMA_SIZE	((128 * 2 + 1) * 4)
=+DO NOT APPLY+=
 static unsigned int debug_quirks = 0;
 static unsigned int debug_quirks2;
 
@@ -481,11 +483,6 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 	else
 		direction = DMA_TO_DEVICE;
 
-	/*
-	 * The ADMA descriptor table is mapped further down as we
-	 * need to fill it with data first.
-	 */
-
 	host->align_addr = dma_map_single(mmc_dev(host->mmc),
 		host->align_buffer, 128 * 4, direction);
 	if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
@@ -546,7 +543,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 		 * If this triggers then we have a calculation bug
 		 * somewhere. :/
 		 */
-		WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
=+DO NOT APPLY+=		WARN_ON((desc - host->adma_desc) > ADMA_SIZE);
 	}
 
 	if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
@@ -574,17 +571,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
 			host->align_addr, 128 * 4, direction);
 	}
 
-	host->adma_addr = dma_map_single(mmc_dev(host->mmc),
-		host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
-	if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
-		goto unmap_entries;
-	BUG_ON(host->adma_addr & 0x3);
-
 	return 0;
 
-unmap_entries:
-	dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-		data->sg_len, direction);
 unmap_align:
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
@@ -609,9 +597,6 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 	else
 		direction = DMA_TO_DEVICE;
 
-	dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
-		(128 * 2 + 1) * 4, DMA_TO_DEVICE);
-
 	dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
 		128 * 4, direction);
 
@@ -2854,15 +2839,29 @@ int sdhci_add_host(struct sdhci_host *host)
 		 * (128) and potentially one alignment transfer for
 		 * each of those entries.
 		 */
-		host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
=+DO NOT APPLY+=		host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
=+DO NOT APPLY+=						     ADMA_SIZE, &host->adma_addr,
=+DO NOT APPLY+=						     GFP_KERNEL);
 		host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
 		if (!host->adma_desc || !host->align_buffer) {
-			kfree(host->adma_desc);
=+DO NOT APPLY+=			dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=					  host->adma_desc, host->adma_addr);
 			kfree(host->align_buffer);
 			pr_warning("%s: Unable to allocate ADMA "
 				"buffers. Falling back to standard DMA.\n",
 				mmc_hostname(mmc));
 			host->flags &= ~SDHCI_USE_ADMA;
=+DO NOT APPLY+=			host->adma_desc = NULL;
=+DO NOT APPLY+=			host->align_buffer = NULL;
=+DO NOT APPLY+=		} else if (host->adma_addr & 3) {
=+DO NOT APPLY+=			pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
=+DO NOT APPLY+=				   mmc_hostname(mmc));
=+DO NOT APPLY+=			host->flags &= ~SDHCI_USE_ADMA;
=+DO NOT APPLY+=			dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=					  host->adma_desc, host->adma_addr);
=+DO NOT APPLY+=			kfree(host->align_buffer);
=+DO NOT APPLY+=			host->adma_desc = NULL;
=+DO NOT APPLY+=			host->align_buffer = NULL;
 		}
 	}
 
@@ -3339,7 +3338,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 		regulator_put(host->vqmmc);
 	}
 
-	kfree(host->adma_desc);
=+DO NOT APPLY+=	if (host->adma_desc)
=+DO NOT APPLY+=		dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
=+DO NOT APPLY+=				  host->adma_desc, host->adma_addr);
 	kfree(host->align_buffer);
 
 	host->adma_desc = NULL;
-- 
1.8.3.1

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

* [PATCH RFC 16/31] mmc: sdhci: clean up sdhci_update_clock()/sdhci_set_clock()
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Only one caller to sdhci_set_clock() needs to check whether the
requested clock frequency was the same as the currently set frequency,
yet we work around this in several other sites via sdhci_update_clock().
Rather than doing this, move those checks out into sdhci_do_set_ios(),
which then allows sdhci_update_clock() to be eliminated.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c |  3 ---
 drivers/mmc/host/sdhci.c         | 21 +++++----------------
 2 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 87af66bb1ea8..fa11f63b78a0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -30,9 +30,6 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk;
 	unsigned long timeout;
 
-	if (clock == host->clock)
-		return;
-
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d046b4eee335..6e0ffaa84ba0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1119,9 +1119,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk = 0;
 	unsigned long timeout;
 
-	if (clock && clock == host->clock)
-		return;
-
 	host->mmc->actual_clock = 0;
 
 	if (host->ops->set_clock) {
@@ -1228,15 +1225,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	host->clock = clock;
 }
 
-static inline void sdhci_update_clock(struct sdhci_host *host)
-{
-	unsigned int clock;
-
-	clock = host->clock;
-	host->clock = 0;
-	sdhci_set_clock(host, clock);
-}
-
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
 	u8 pwr = 0;
@@ -1453,7 +1441,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
 		sdhci_enable_preset_value(host, false);
 
-	sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=	if (!ios->clock || ios->clock != host->clock)
=+DO NOT APPLY+=		sdhci_set_clock(host, ios->clock);
 
 	if (ios->power_mode == MMC_POWER_OFF)
 		vdd_bit = sdhci_set_power(host, -1);
@@ -1521,7 +1510,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			sdhci_update_clock(host);
=+DO NOT APPLY+=			sdhci_set_clock(host, host->clock);
 		}
 
 
@@ -1565,7 +1554,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		/* Re-enable SD Clock */
-		sdhci_update_clock(host);
=+DO NOT APPLY+=		sdhci_set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2137,7 +2126,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 		/* Some controllers need this kick or reset won't work here */
 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			sdhci_update_clock(host);
=+DO NOT APPLY+=			sdhci_set_clock(host, host->clock);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
-- 
1.8.3.1


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

* [PATCH RFC 16/31] mmc: sdhci: clean up sdhci_update_clock()/sdhci_set_clock()
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Only one caller to sdhci_set_clock() needs to check whether the
requested clock frequency was the same as the currently set frequency,
yet we work around this in several other sites via sdhci_update_clock().
Rather than doing this, move those checks out into sdhci_do_set_ios(),
which then allows sdhci_update_clock() to be eliminated.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c |  3 ---
 drivers/mmc/host/sdhci.c         | 21 +++++----------------
 2 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 87af66bb1ea8..fa11f63b78a0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -30,9 +30,6 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk;
 	unsigned long timeout;
 
-	if (clock == host->clock)
-		return;
-
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d046b4eee335..6e0ffaa84ba0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1119,9 +1119,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk = 0;
 	unsigned long timeout;
 
-	if (clock && clock == host->clock)
-		return;
-
 	host->mmc->actual_clock = 0;
 
 	if (host->ops->set_clock) {
@@ -1228,15 +1225,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	host->clock = clock;
 }
 
-static inline void sdhci_update_clock(struct sdhci_host *host)
-{
-	unsigned int clock;
-
-	clock = host->clock;
-	host->clock = 0;
-	sdhci_set_clock(host, clock);
-}
-
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
 	u8 pwr = 0;
@@ -1453,7 +1441,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
 		sdhci_enable_preset_value(host, false);
 
-	sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=	if (!ios->clock || ios->clock != host->clock)
=+DO NOT APPLY+=		sdhci_set_clock(host, ios->clock);
 
 	if (ios->power_mode == MMC_POWER_OFF)
 		vdd_bit = sdhci_set_power(host, -1);
@@ -1521,7 +1510,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			sdhci_update_clock(host);
=+DO NOT APPLY+=			sdhci_set_clock(host, host->clock);
 		}
 
 
@@ -1565,7 +1554,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		/* Re-enable SD Clock */
-		sdhci_update_clock(host);
=+DO NOT APPLY+=		sdhci_set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2137,7 +2126,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 		/* Some controllers need this kick or reset won't work here */
 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			sdhci_update_clock(host);
=+DO NOT APPLY+=			sdhci_set_clock(host, host->clock);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
-- 
1.8.3.1

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

* [PATCH RFC 17/31] mmc: sdhci: move setting host->clock into sdhci_do_set_ios()
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball, Ben Dooks

We don't need implementations to do this, since the only time it's
necessary is when we change the clock, and the only place that happens
is in sdhci_do_set_ios().  So, move it there, and remove it from the
iMX platform backend.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c   | 4 +---
 drivers/mmc/host/sdhci-esdhc-imx.c | 4 +---
 drivers/mmc/host/sdhci-of-esdhc.c  | 4 +---
 drivers/mmc/host/sdhci-s3c.c       | 3 ---
 drivers/mmc/host/sdhci.c           | 9 ++++-----
 5 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index fa11f63b78a0..f11fb908ad78 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -33,7 +33,7 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	while (host->max_clk / div > clock) {
 		/*
@@ -72,8 +72,6 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-out:
-	host->clock = clock;
 }
 
 static const struct sdhci_ops sdhci_cns3xxx_ops = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 812c5772d900..1e68a77c9987 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -605,7 +605,7 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 			writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
 					host->ioaddr + ESDHC_VENDOR_SPEC);
 		}
-		goto out;
=+DO NOT APPLY+=		return;
 	}
 
 	if (esdhc_is_usdhc(imx_data) && !imx_data->is_ddr)
@@ -645,8 +645,6 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 	}
 
 	mdelay(1);
-out:
-	host->clock = clock;
 }
 
 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 4530f9957f20..d814b3ecb1f7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -205,7 +205,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	u32 temp;
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	/* Workaround to reduce the clock frequency for p1010 esdhc */
 	if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
@@ -238,8 +238,6 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 		| (pre_div << ESDHC_PREDIV_SHIFT));
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 	mdelay(1);
-out:
-	host->clock = clock;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 619047be00c9..e7865d1da1f2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -299,7 +299,6 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 	/* If the clock is going off, set to 0 at clock control register */
 	if (clock == 0) {
 		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
-		host->clock = clock;
 		return;
 	}
 
@@ -307,8 +306,6 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
 
-	host->clock = clock;
-
 	clk = SDHCI_CLOCK_INT_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6e0ffaa84ba0..5fdf9f927a99 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1130,7 +1130,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	if (host->version >= SDHCI_SPEC_300) {
 		if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
@@ -1220,9 +1220,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
-out:
-	host->clock = clock;
 }
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
@@ -1441,8 +1438,10 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
 		sdhci_enable_preset_value(host, false);
 
-	if (!ios->clock || ios->clock != host->clock)
=+DO NOT APPLY+=	if (!ios->clock || ios->clock != host->clock) {
 		sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=		host->clock = ios->clock;
=+DO NOT APPLY+=	}
 
 	if (ios->power_mode == MMC_POWER_OFF)
 		vdd_bit = sdhci_set_power(host, -1);
-- 
1.8.3.1


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

* [PATCH RFC 17/31] mmc: sdhci: move setting host->clock into sdhci_do_set_ios()
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need implementations to do this, since the only time it's
necessary is when we change the clock, and the only place that happens
is in sdhci_do_set_ios().  So, move it there, and remove it from the
iMX platform backend.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c   | 4 +---
 drivers/mmc/host/sdhci-esdhc-imx.c | 4 +---
 drivers/mmc/host/sdhci-of-esdhc.c  | 4 +---
 drivers/mmc/host/sdhci-s3c.c       | 3 ---
 drivers/mmc/host/sdhci.c           | 9 ++++-----
 5 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index fa11f63b78a0..f11fb908ad78 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -33,7 +33,7 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	while (host->max_clk / div > clock) {
 		/*
@@ -72,8 +72,6 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-out:
-	host->clock = clock;
 }
 
 static const struct sdhci_ops sdhci_cns3xxx_ops = {
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 812c5772d900..1e68a77c9987 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -605,7 +605,7 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 			writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
 					host->ioaddr + ESDHC_VENDOR_SPEC);
 		}
-		goto out;
=+DO NOT APPLY+=		return;
 	}
 
 	if (esdhc_is_usdhc(imx_data) && !imx_data->is_ddr)
@@ -645,8 +645,6 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 	}
 
 	mdelay(1);
-out:
-	host->clock = clock;
 }
 
 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 4530f9957f20..d814b3ecb1f7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -205,7 +205,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	u32 temp;
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	/* Workaround to reduce the clock frequency for p1010 esdhc */
 	if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
@@ -238,8 +238,6 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 		| (pre_div << ESDHC_PREDIV_SHIFT));
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 	mdelay(1);
-out:
-	host->clock = clock;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 619047be00c9..e7865d1da1f2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -299,7 +299,6 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 	/* If the clock is going off, set to 0 at clock control register */
 	if (clock == 0) {
 		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
-		host->clock = clock;
 		return;
 	}
 
@@ -307,8 +306,6 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
 
-	host->clock = clock;
-
 	clk = SDHCI_CLOCK_INT_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6e0ffaa84ba0..5fdf9f927a99 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1130,7 +1130,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-		goto out;
=+DO NOT APPLY+=		return;
 
 	if (host->version >= SDHCI_SPEC_300) {
 		if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
@@ -1220,9 +1220,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
-out:
-	host->clock = clock;
 }
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
@@ -1441,8 +1438,10 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
 		sdhci_enable_preset_value(host, false);
 
-	if (!ios->clock || ios->clock != host->clock)
=+DO NOT APPLY+=	if (!ios->clock || ios->clock != host->clock) {
 		sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=		host->clock = ios->clock;
=+DO NOT APPLY+=	}
 
 	if (ios->power_mode == MMC_POWER_OFF)
 		vdd_bit = sdhci_set_power(host, -1);
-- 
1.8.3.1

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

* [PATCH RFC 18/31] mmc: sdhci: move setting mmc->actual_clock into set_clock handlers
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball, Ben Dooks

Move the setting of mmc->actual_clock to zero into the set_clock
handlers themselves.  This will allow us to clean up the calling
logic for the set_clock() method, and turn sdhci_set_clock() into
a library function.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c   | 2 ++
 drivers/mmc/host/sdhci-esdhc-imx.c | 2 ++
 drivers/mmc/host/sdhci-of-esdhc.c  | 3 ++-
 drivers/mmc/host/sdhci-s3c.c       | 4 ++++
 drivers/mmc/host/sdhci.c           | 4 ++--
 5 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index f11fb908ad78..416f4a4c2e35 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -30,6 +30,8 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk;
 	unsigned long timeout;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1e68a77c9987..ce8939ff97a4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -600,6 +600,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 	u32 temp, val;
 
 	if (clock == 0) {
=+DO NOT APPLY+=		host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 		if (esdhc_is_usdhc(imx_data)) {
 			val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
 			writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index d814b3ecb1f7..c4f8cd3f83c8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -199,11 +199,12 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 
 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 {
-
 	int pre_div = 2;
 	int div = 1;
 	u32 temp;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	if (clock == 0)
 		return;
 
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index e7865d1da1f2..18579555a5f7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -188,6 +188,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	int src;
 	u32 ctrl;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	/* don't bother if the clock is going off. */
 	if (clock == 0)
 		return;
@@ -296,6 +298,8 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 	unsigned long timeout;
 	u16 clk = 0;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	/* If the clock is going off, set to 0 at clock control register */
 	if (clock == 0) {
 		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5fdf9f927a99..c370e6bd7ecd 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1119,14 +1119,14 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk = 0;
 	unsigned long timeout;
 
-	host->mmc->actual_clock = 0;
-
 	if (host->ops->set_clock) {
 		host->ops->set_clock(host, clock);
 		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
 			return;
 	}
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-- 
1.8.3.1


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

* [PATCH RFC 18/31] mmc: sdhci: move setting mmc->actual_clock into set_clock handlers
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Move the setting of mmc->actual_clock to zero into the set_clock
handlers themselves.  This will allow us to clean up the calling
logic for the set_clock() method, and turn sdhci_set_clock() into
a library function.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-cns3xxx.c   | 2 ++
 drivers/mmc/host/sdhci-esdhc-imx.c | 2 ++
 drivers/mmc/host/sdhci-of-esdhc.c  | 3 ++-
 drivers/mmc/host/sdhci-s3c.c       | 4 ++++
 drivers/mmc/host/sdhci.c           | 4 ++--
 5 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index f11fb908ad78..416f4a4c2e35 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -30,6 +30,8 @@ static void sdhci_cns3xxx_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk;
 	unsigned long timeout;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 1e68a77c9987..ce8939ff97a4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -600,6 +600,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
 	u32 temp, val;
 
 	if (clock == 0) {
=+DO NOT APPLY+=		host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 		if (esdhc_is_usdhc(imx_data)) {
 			val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
 			writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index d814b3ecb1f7..c4f8cd3f83c8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -199,11 +199,12 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 
 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 {
-
 	int pre_div = 2;
 	int div = 1;
 	u32 temp;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	if (clock == 0)
 		return;
 
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index e7865d1da1f2..18579555a5f7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -188,6 +188,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	int src;
 	u32 ctrl;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	/* don't bother if the clock is going off. */
 	if (clock == 0)
 		return;
@@ -296,6 +298,8 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 	unsigned long timeout;
 	u16 clk = 0;
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	/* If the clock is going off, set to 0 at clock control register */
 	if (clock == 0) {
 		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5fdf9f927a99..c370e6bd7ecd 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1119,14 +1119,14 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	u16 clk = 0;
 	unsigned long timeout;
 
-	host->mmc->actual_clock = 0;
-
 	if (host->ops->set_clock) {
 		host->ops->set_clock(host, clock);
 		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
 			return;
 	}
 
=+DO NOT APPLY+=	host->mmc->actual_clock = 0;
=+DO NOT APPLY+=
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
-- 
1.8.3.1

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

* [PATCH RFC 19/31] mmc: sdhci: convert sdhci_set_clock() into a library function
  2014-02-18 15:08 ` Russell King - ARM Linux
  (?)
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Michal Simek, Anton Vorontsov, Ben Dooks, Barry Song,
	Viresh Kumar, Stephen Warren, Thierry Reding, linuxppc-dev,
	spear-devel, linux-tegra

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  3 +--
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc.h     |  1 -
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       | 19 ++++++++++++++-----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 17 ++++++-----------
 drivers/mmc/host/sdhci.h           |  1 +
 include/linux/mmc/sdhci.h          |  2 --
 19 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 1ded6690be43..c20964e577e9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -101,12 +101,14 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 4c82ecb7a71e..77b14b1a24bc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -205,6 +205,7 @@ static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
 }
 
 static struct sdhci_ops sdhci_bcm_kona_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 289b1c80d5fc..74906d6008e1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -131,6 +131,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_l = bcm2835_sdhci_readl,
 	.read_w = bcm2835_sdhci_readw,
 	.read_b = bcm2835_sdhci_readb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 416f4a4c2e35..587d73ef33ff 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -89,8 +89,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
-		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
-		  SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4c0191bff85d..4f4216115aed 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index de69bddc3afc..3497cfaf683c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc.h
@@ -20,7 +20,6 @@
 
 #define ESDHC_DEFAULT_QUIRKS	(SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
 				SDHCI_QUIRK_NO_BUSY_IRQ | \
-				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
 				SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index faef21740584..f0ee594f25d1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -52,6 +52,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_arasan_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index fb01958cb18e..a4a1f0f2c0a0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 88a6c6b87d70..01ee60d17b04 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1058,6 +1058,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_pci_ops = {
=+DO NOT APPLY+=	.set_clock	= sdhci_set_clock,
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bfbf467b61c7..1fb89f44bd58 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 2eee0c8b88eb..db5257bf032e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -112,6 +112,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock     = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e6ea46c4d233..3d6b574528ea 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -170,6 +170,7 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 18579555a5f7..63496bd62196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -57,6 +57,8 @@ struct sdhci_s3c {
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
=+DO NOT APPLY+=
=+DO NOT APPLY+=	bool			no_divider;
 };
 
 /**
@@ -69,6 +71,7 @@ struct sdhci_s3c {
  */
 struct sdhci_s3c_drv_data {
 	unsigned int	sdhci_quirks;
=+DO NOT APPLY+=	bool		no_divider;
 };
 
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
@@ -153,7 +156,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
 	 * If controller uses a non-standard clock division, find the best clock
 	 * speed possible with selected clock source and skip the division.
 	 */
-	if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (ourhost->no_divider) {
 		rate = clk_round_rate(clksrc, wanted);
 		return wanted - rate;
 	}
@@ -191,8 +194,10 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	host->mmc->actual_clock = 0;
 
 	/* don't bother if the clock is going off. */
-	if (clock == 0)
=+DO NOT APPLY+=	if (clock == 0) {
=+DO NOT APPLY+=		sdhci_set_clock(host, clock);
 		return;
=+DO NOT APPLY+=	}
 
 	for (src = 0; src < MAX_BUS_CLK; src++) {
 		delta = sdhci_s3c_consider_clock(ourhost, src, clock);
@@ -242,6 +247,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	if (clock < 25 * 1000000)
 		ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
 	writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_set_clock(host, clock);
 }
 
 /**
@@ -617,8 +624,10 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	/* Setup quirks for the controller */
 	host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
-	if (drv_data)
=+DO NOT APPLY+=	if (drv_data) {
 		host->quirks |= drv_data->sdhci_quirks;
=+DO NOT APPLY+=		sc->no_divider = drv_data->no_divider;
=+DO NOT APPLY+=	}
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -667,7 +676,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	 * If controller does not have internal clock divider,
 	 * we can use overriding functions instead of default.
 	 */
-	if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (sc->no_divider) {
 		sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
 		sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
 		sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -813,7 +822,7 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 
 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
 static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
-	.sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=	.no_divider = true,
 };
 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
 #else
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 5d79e10e1ba2..3b775348b470 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -28,6 +28,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_sirf_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index ef990974a522..f365a3fc7612 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,6 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 7754c0319fda..a0a8b5cc3b0c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -153,6 +153,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
=+DO NOT APPLY+=	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c370e6bd7ecd..ddd57bc235ab 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1112,19 +1112,13 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
 	return preset;
 }
 
-static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	int div = 0; /* Initialized for compiler warning */
 	int real_div = div, clk_mul = 1;
 	u16 clk = 0;
 	unsigned long timeout;
 
-	if (host->ops->set_clock) {
-		host->ops->set_clock(host, clock);
-		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
-			return;
-	}
-
 	host->mmc->actual_clock = 0;
 
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1221,6 +1215,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
@@ -1439,7 +1434,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		sdhci_enable_preset_value(host, false);
 
 	if (!ios->clock || ios->clock != host->clock) {
-		sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, ios->clock);
 		host->clock = ios->clock;
 	}
 
@@ -1509,7 +1504,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 		}
 
 
@@ -1553,7 +1548,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		/* Re-enable SD Clock */
-		sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2125,7 +2120,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 		/* Some controllers need this kick or reset won't work here */
 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7d84cb3b0e00..ac20195f667b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -400,6 +400,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 801579313789..20daa39e3a68 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -57,8 +57,6 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_CARD_DETECTION		(1<<15)
 /* Controller reports inverted write-protect state */
 #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT		(1<<16)
-/* Controller has nonstandard clock management */
-#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
 /* Controller has to be forced to use block size of 2048 bytes */
-- 
1.8.3.1


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

* [PATCH RFC 19/31] mmc: sdhci: convert sdhci_set_clock() into a library function
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Barry Song, spear-devel, Stephen Warren, Anton Vorontsov,
	Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra, linuxppc-dev

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  3 +--
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc.h     |  1 -
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       | 19 ++++++++++++++-----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 17 ++++++-----------
 drivers/mmc/host/sdhci.h           |  1 +
 include/linux/mmc/sdhci.h          |  2 --
 19 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 1ded6690be43..c20964e577e9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -101,12 +101,14 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 4c82ecb7a71e..77b14b1a24bc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -205,6 +205,7 @@ static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
 }
 
 static struct sdhci_ops sdhci_bcm_kona_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 289b1c80d5fc..74906d6008e1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -131,6 +131,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_l = bcm2835_sdhci_readl,
 	.read_w = bcm2835_sdhci_readw,
 	.read_b = bcm2835_sdhci_readb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 416f4a4c2e35..587d73ef33ff 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -89,8 +89,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
-		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
-		  SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4c0191bff85d..4f4216115aed 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index de69bddc3afc..3497cfaf683c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc.h
@@ -20,7 +20,6 @@
 
 #define ESDHC_DEFAULT_QUIRKS	(SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
 				SDHCI_QUIRK_NO_BUSY_IRQ | \
-				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
 				SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index faef21740584..f0ee594f25d1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -52,6 +52,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_arasan_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index fb01958cb18e..a4a1f0f2c0a0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 88a6c6b87d70..01ee60d17b04 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1058,6 +1058,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_pci_ops = {
=+DO NOT APPLY+=	.set_clock	= sdhci_set_clock,
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bfbf467b61c7..1fb89f44bd58 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 2eee0c8b88eb..db5257bf032e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -112,6 +112,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock     = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e6ea46c4d233..3d6b574528ea 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -170,6 +170,7 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 18579555a5f7..63496bd62196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -57,6 +57,8 @@ struct sdhci_s3c {
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
=+DO NOT APPLY+=
=+DO NOT APPLY+=	bool			no_divider;
 };
 
 /**
@@ -69,6 +71,7 @@ struct sdhci_s3c {
  */
 struct sdhci_s3c_drv_data {
 	unsigned int	sdhci_quirks;
=+DO NOT APPLY+=	bool		no_divider;
 };
 
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
@@ -153,7 +156,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
 	 * If controller uses a non-standard clock division, find the best clock
 	 * speed possible with selected clock source and skip the division.
 	 */
-	if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (ourhost->no_divider) {
 		rate = clk_round_rate(clksrc, wanted);
 		return wanted - rate;
 	}
@@ -191,8 +194,10 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	host->mmc->actual_clock = 0;
 
 	/* don't bother if the clock is going off. */
-	if (clock == 0)
=+DO NOT APPLY+=	if (clock == 0) {
=+DO NOT APPLY+=		sdhci_set_clock(host, clock);
 		return;
=+DO NOT APPLY+=	}
 
 	for (src = 0; src < MAX_BUS_CLK; src++) {
 		delta = sdhci_s3c_consider_clock(ourhost, src, clock);
@@ -242,6 +247,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	if (clock < 25 * 1000000)
 		ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
 	writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_set_clock(host, clock);
 }
 
 /**
@@ -617,8 +624,10 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	/* Setup quirks for the controller */
 	host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
-	if (drv_data)
=+DO NOT APPLY+=	if (drv_data) {
 		host->quirks |= drv_data->sdhci_quirks;
=+DO NOT APPLY+=		sc->no_divider = drv_data->no_divider;
=+DO NOT APPLY+=	}
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -667,7 +676,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	 * If controller does not have internal clock divider,
 	 * we can use overriding functions instead of default.
 	 */
-	if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (sc->no_divider) {
 		sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
 		sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
 		sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -813,7 +822,7 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 
 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
 static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
-	.sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=	.no_divider = true,
 };
 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
 #else
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 5d79e10e1ba2..3b775348b470 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -28,6 +28,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_sirf_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index ef990974a522..f365a3fc7612 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,6 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 7754c0319fda..a0a8b5cc3b0c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -153,6 +153,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
=+DO NOT APPLY+=	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c370e6bd7ecd..ddd57bc235ab 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1112,19 +1112,13 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
 	return preset;
 }
 
-static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	int div = 0; /* Initialized for compiler warning */
 	int real_div = div, clk_mul = 1;
 	u16 clk = 0;
 	unsigned long timeout;
 
-	if (host->ops->set_clock) {
-		host->ops->set_clock(host, clock);
-		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
-			return;
-	}
-
 	host->mmc->actual_clock = 0;
 
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1221,6 +1215,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
@@ -1439,7 +1434,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		sdhci_enable_preset_value(host, false);
 
 	if (!ios->clock || ios->clock != host->clock) {
-		sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, ios->clock);
 		host->clock = ios->clock;
 	}
 
@@ -1509,7 +1504,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 		}
 
 
@@ -1553,7 +1548,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		/* Re-enable SD Clock */
-		sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2125,7 +2120,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 		/* Some controllers need this kick or reset won't work here */
 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7d84cb3b0e00..ac20195f667b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -400,6 +400,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 801579313789..20daa39e3a68 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -57,8 +57,6 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_CARD_DETECTION		(1<<15)
 /* Controller reports inverted write-protect state */
 #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT		(1<<16)
-/* Controller has nonstandard clock management */
-#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
 /* Controller has to be forced to use block size of 2048 bytes */
-- 
1.8.3.1

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

* [PATCH RFC 19/31] mmc: sdhci: convert sdhci_set_clock() into a library function
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  3 +--
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-esdhc.h     |  1 -
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       | 19 ++++++++++++++-----
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 17 ++++++-----------
 drivers/mmc/host/sdhci.h           |  1 +
 include/linux/mmc/sdhci.h          |  2 --
 19 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index 1ded6690be43..c20964e577e9 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -101,12 +101,14 @@ static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 4c82ecb7a71e..77b14b1a24bc 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -205,6 +205,7 @@ static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
 }
 
 static struct sdhci_ops sdhci_bcm_kona_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_bcm_kona_get_max_clk,
 	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 289b1c80d5fc..74906d6008e1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -131,6 +131,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.read_l = bcm2835_sdhci_readl,
 	.read_w = bcm2835_sdhci_readw,
 	.read_b = bcm2835_sdhci_readb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 416f4a4c2e35..587d73ef33ff 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -89,8 +89,7 @@ static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
-		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
-		  SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=		  SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
 };
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4c0191bff85d..4f4216115aed 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -86,6 +86,7 @@ static u32 sdhci_dove_readl(struct sdhci_host *host, int reg)
 static const struct sdhci_ops sdhci_dove_ops = {
 	.read_w	= sdhci_dove_readw,
 	.read_l	= sdhci_dove_readl,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index de69bddc3afc..3497cfaf683c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc.h
@@ -20,7 +20,6 @@
 
 #define ESDHC_DEFAULT_QUIRKS	(SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
 				SDHCI_QUIRK_NO_BUSY_IRQ | \
-				SDHCI_QUIRK_NONSTANDARD_CLOCK | \
 				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
 				SDHCI_QUIRK_PIO_NEEDS_DELAY)
 
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index faef21740584..f0ee594f25d1 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -52,6 +52,7 @@ static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_arasan_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index fb01958cb18e..a4a1f0f2c0a0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -58,6 +58,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.write_l = sdhci_hlwd_writel,
 	.write_w = sdhci_hlwd_writew,
 	.write_b = sdhci_hlwd_writeb,
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 88a6c6b87d70..01ee60d17b04 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1058,6 +1058,7 @@ static void sdhci_pci_hw_reset(struct sdhci_host *host)
 }
 
 static const struct sdhci_ops sdhci_pci_ops = {
=+DO NOT APPLY+=	.set_clock	= sdhci_set_clock,
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index bfbf467b61c7..1fb89f44bd58 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -45,6 +45,7 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
 EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
 
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 2eee0c8b88eb..db5257bf032e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -112,6 +112,7 @@ static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
 }
 
 static const struct sdhci_ops pxav2_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock     = sdhci_set_clock,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index e6ea46c4d233..3d6b574528ea 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -170,6 +170,7 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_uhs_signaling = pxav3_set_uhs_signaling,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 18579555a5f7..63496bd62196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -57,6 +57,8 @@ struct sdhci_s3c {
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
=+DO NOT APPLY+=
=+DO NOT APPLY+=	bool			no_divider;
 };
 
 /**
@@ -69,6 +71,7 @@ struct sdhci_s3c {
  */
 struct sdhci_s3c_drv_data {
 	unsigned int	sdhci_quirks;
=+DO NOT APPLY+=	bool		no_divider;
 };
 
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
@@ -153,7 +156,7 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
 	 * If controller uses a non-standard clock division, find the best clock
 	 * speed possible with selected clock source and skip the division.
 	 */
-	if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (ourhost->no_divider) {
 		rate = clk_round_rate(clksrc, wanted);
 		return wanted - rate;
 	}
@@ -191,8 +194,10 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	host->mmc->actual_clock = 0;
 
 	/* don't bother if the clock is going off. */
-	if (clock == 0)
=+DO NOT APPLY+=	if (clock == 0) {
=+DO NOT APPLY+=		sdhci_set_clock(host, clock);
 		return;
=+DO NOT APPLY+=	}
 
 	for (src = 0; src < MAX_BUS_CLK; src++) {
 		delta = sdhci_s3c_consider_clock(ourhost, src, clock);
@@ -242,6 +247,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
 	if (clock < 25 * 1000000)
 		ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
 	writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sdhci_set_clock(host, clock);
 }
 
 /**
@@ -617,8 +624,10 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	/* Setup quirks for the controller */
 	host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
-	if (drv_data)
=+DO NOT APPLY+=	if (drv_data) {
 		host->quirks |= drv_data->sdhci_quirks;
=+DO NOT APPLY+=		sc->no_divider = drv_data->no_divider;
=+DO NOT APPLY+=	}
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -667,7 +676,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
 	 * If controller does not have internal clock divider,
 	 * we can use overriding functions instead of default.
 	 */
-	if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
=+DO NOT APPLY+=	if (sc->no_divider) {
 		sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
 		sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
 		sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -813,7 +822,7 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 
 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
 static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
-	.sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
=+DO NOT APPLY+=	.no_divider = true,
 };
 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
 #else
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 5d79e10e1ba2..3b775348b470 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -28,6 +28,7 @@ static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 }
 
 static struct sdhci_ops sdhci_sirf_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index ef990974a522..f365a3fc7612 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -37,6 +37,7 @@ struct spear_sdhci {
 
 /* sdhci ops */
 static const struct sdhci_ops sdhci_pltfm_ops = {
=+DO NOT APPLY+=	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 7754c0319fda..a0a8b5cc3b0c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -153,6 +153,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
=+DO NOT APPLY+=	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
 };
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c370e6bd7ecd..ddd57bc235ab 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1112,19 +1112,13 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
 	return preset;
 }
 
-static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	int div = 0; /* Initialized for compiler warning */
 	int real_div = div, clk_mul = 1;
 	u16 clk = 0;
 	unsigned long timeout;
 
-	if (host->ops->set_clock) {
-		host->ops->set_clock(host, clock);
-		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
-			return;
-	}
-
 	host->mmc->actual_clock = 0;
 
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -1221,6 +1215,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	clk |= SDHCI_CLOCK_CARD_EN;
 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
 static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
 {
@@ -1439,7 +1434,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		sdhci_enable_preset_value(host, false);
 
 	if (!ios->clock || ios->clock != host->clock) {
-		sdhci_set_clock(host, ios->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, ios->clock);
 		host->clock = ios->clock;
 	}
 
@@ -1509,7 +1504,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 			/* Re-enable SD Clock */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 		}
 
 
@@ -1553,7 +1548,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		/* Re-enable SD Clock */
-		sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=		host->ops->set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -2125,7 +2120,7 @@ static void sdhci_tasklet_finish(unsigned long param)
 		/* Some controllers need this kick or reset won't work here */
 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
 			/* This is to force an update */
-			sdhci_set_clock(host, host->clock);
=+DO NOT APPLY+=			host->ops->set_clock(host, host->clock);
 
 		/* Spec says we should do both at the same time, but Ricoh
 		   controllers do not like that. */
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7d84cb3b0e00..ac20195f667b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -400,6 +400,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 	return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
 }
 
=+DO NOT APPLY+=void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 801579313789..20daa39e3a68 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -57,8 +57,6 @@ struct sdhci_host {
 #define SDHCI_QUIRK_BROKEN_CARD_DETECTION		(1<<15)
 /* Controller reports inverted write-protect state */
 #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT		(1<<16)
-/* Controller has nonstandard clock management */
-#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
 /* Controller does not like fast PIO transfers */
 #define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
 /* Controller has to be forced to use block size of 2048 bytes */
-- 
1.8.3.1

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

* [PATCH RFC 20/31] mmc: sdhci-esdhc-imx: avoid DMA to kernel stack
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

sdhci-esdhc-imx tries to DMA to the kernel stack when tuning the
interface, which causes dma-debug to complain.  Fix this by kmallocing
a buffer to hold the received tuning pattern.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ce8939ff97a4..5acfe2fc4fe0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -711,13 +711,12 @@ static void esdhc_request_done(struct mmc_request *mrq)
 	complete(&mrq->completion);
 }
 
-static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
=+DO NOT APPLY+=static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
=+DO NOT APPLY+=				 struct scatterlist *sg)
 {
 	struct mmc_command cmd = {0};
 	struct mmc_request mrq = {NULL};
 	struct mmc_data data = {0};
-	struct scatterlist sg;
-	char tuning_pattern[ESDHC_TUNING_BLOCK_PATTERN_LEN];
 
 	cmd.opcode = opcode;
 	cmd.arg = 0;
@@ -726,11 +725,9 @@ static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
 	data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
-	data.sg = &sg;
=+DO NOT APPLY+=	data.sg = sg;
 	data.sg_len = 1;
 
-	sg_init_one(&sg, tuning_pattern, sizeof(tuning_pattern));
-
 	mrq.cmd = &cmd;
 	mrq.cmd->mrq = &mrq;
 	mrq.data = &data;
@@ -770,13 +767,21 @@ static void esdhc_post_tuning(struct sdhci_host *host)
 
 static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 {
=+DO NOT APPLY+=	struct scatterlist sg;
=+DO NOT APPLY+=	char *tuning_pattern;
 	int min, max, avg, ret;
 
=+DO NOT APPLY+=	tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
=+DO NOT APPLY+=	if (!tuning_pattern)
=+DO NOT APPLY+=		return -ENOMEM;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
=+DO NOT APPLY+=
 	/* find the mininum delay first which can pass tuning */
 	min = ESDHC_TUNE_CTRL_MIN;
 	while (min < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, min);
-		if (!esdhc_send_tuning_cmd(host, opcode))
=+DO NOT APPLY+=		if (!esdhc_send_tuning_cmd(host, opcode, &sg))
 			break;
 		min += ESDHC_TUNE_CTRL_STEP;
 	}
@@ -785,7 +790,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	max = min + ESDHC_TUNE_CTRL_STEP;
 	while (max < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, max);
-		if (esdhc_send_tuning_cmd(host, opcode)) {
=+DO NOT APPLY+=		if (esdhc_send_tuning_cmd(host, opcode, &sg)) {
 			max -= ESDHC_TUNE_CTRL_STEP;
 			break;
 		}
@@ -795,9 +800,11 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	/* use average delay to get the best timing */
 	avg = (min + max) / 2;
 	esdhc_prepare_tuning(host, avg);
-	ret = esdhc_send_tuning_cmd(host, opcode);
=+DO NOT APPLY+=	ret = esdhc_send_tuning_cmd(host, opcode, &sg);
 	esdhc_post_tuning(host);
 
=+DO NOT APPLY+=	kfree(tuning_pattern);
=+DO NOT APPLY+=
 	dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
 		ret ? "failed" : "passed", avg, ret);
 
-- 
1.8.3.1


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

* [PATCH RFC 20/31] mmc: sdhci-esdhc-imx: avoid DMA to kernel stack
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

sdhci-esdhc-imx tries to DMA to the kernel stack when tuning the
interface, which causes dma-debug to complain.  Fix this by kmallocing
a buffer to hold the received tuning pattern.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ce8939ff97a4..5acfe2fc4fe0 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -711,13 +711,12 @@ static void esdhc_request_done(struct mmc_request *mrq)
 	complete(&mrq->completion);
 }
 
-static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
=+DO NOT APPLY+=static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
=+DO NOT APPLY+=				 struct scatterlist *sg)
 {
 	struct mmc_command cmd = {0};
 	struct mmc_request mrq = {NULL};
 	struct mmc_data data = {0};
-	struct scatterlist sg;
-	char tuning_pattern[ESDHC_TUNING_BLOCK_PATTERN_LEN];
 
 	cmd.opcode = opcode;
 	cmd.arg = 0;
@@ -726,11 +725,9 @@ static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
 	data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
-	data.sg = &sg;
=+DO NOT APPLY+=	data.sg = sg;
 	data.sg_len = 1;
 
-	sg_init_one(&sg, tuning_pattern, sizeof(tuning_pattern));
-
 	mrq.cmd = &cmd;
 	mrq.cmd->mrq = &mrq;
 	mrq.data = &data;
@@ -770,13 +767,21 @@ static void esdhc_post_tuning(struct sdhci_host *host)
 
 static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 {
=+DO NOT APPLY+=	struct scatterlist sg;
=+DO NOT APPLY+=	char *tuning_pattern;
 	int min, max, avg, ret;
 
=+DO NOT APPLY+=	tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
=+DO NOT APPLY+=	if (!tuning_pattern)
=+DO NOT APPLY+=		return -ENOMEM;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
=+DO NOT APPLY+=
 	/* find the mininum delay first which can pass tuning */
 	min = ESDHC_TUNE_CTRL_MIN;
 	while (min < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, min);
-		if (!esdhc_send_tuning_cmd(host, opcode))
=+DO NOT APPLY+=		if (!esdhc_send_tuning_cmd(host, opcode, &sg))
 			break;
 		min += ESDHC_TUNE_CTRL_STEP;
 	}
@@ -785,7 +790,7 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	max = min + ESDHC_TUNE_CTRL_STEP;
 	while (max < ESDHC_TUNE_CTRL_MAX) {
 		esdhc_prepare_tuning(host, max);
-		if (esdhc_send_tuning_cmd(host, opcode)) {
=+DO NOT APPLY+=		if (esdhc_send_tuning_cmd(host, opcode, &sg)) {
 			max -= ESDHC_TUNE_CTRL_STEP;
 			break;
 		}
@@ -795,9 +800,11 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
 	/* use average delay to get the best timing */
 	avg = (min + max) / 2;
 	esdhc_prepare_tuning(host, avg);
-	ret = esdhc_send_tuning_cmd(host, opcode);
=+DO NOT APPLY+=	ret = esdhc_send_tuning_cmd(host, opcode, &sg);
 	esdhc_post_tuning(host);
 
=+DO NOT APPLY+=	kfree(tuning_pattern);
=+DO NOT APPLY+=
 	dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
 		ret ? "failed" : "passed", avg, ret);
 
-- 
1.8.3.1

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

* [PATCH RFC 21/31] mmc: sdhci-esdhc-imx: avoid runtime_pm_get_sync() in esdhc_prepare_tuning()
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

The caller will already have dealt with runtime PM, so there's no need
to get it here as well - moreover, this results in the runtime PM use
count becoming unbalanced, and preventing runtime PM from operating.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5acfe2fc4fe0..a9a20c856b0b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -695,7 +695,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
 	/* FIXME: delay a bit for card to be ready for next tuning due to errors */
 	mdelay(1);
 
-	pm_runtime_get_sync(host->mmc->parent);
 	reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
 	reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
 			ESDHC_MIX_CTRL_FBCLK_SEL;
-- 
1.8.3.1


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

* [PATCH RFC 21/31] mmc: sdhci-esdhc-imx: avoid runtime_pm_get_sync() in esdhc_prepare_tuning()
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

The caller will already have dealt with runtime PM, so there's no need
to get it here as well - moreover, this results in the runtime PM use
count becoming unbalanced, and preventing runtime PM from operating.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5acfe2fc4fe0..a9a20c856b0b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -695,7 +695,6 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
 	/* FIXME: delay a bit for card to be ready for next tuning due to errors */
 	mdelay(1);
 
-	pm_runtime_get_sync(host->mmc->parent);
 	reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
 	reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
 			ESDHC_MIX_CTRL_FBCLK_SEL;
-- 
1.8.3.1

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

* [PATCH RFC 22/31] mmc: sdhci-esdhc-imx: fix lockdep splat upon tuning
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:10   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

=================================
[ INFO: inconsistent lock state ]
3.14.0-rc1+ #490 Not tainted
=-DO NOT APPLY-=------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
kworker/u8:0/6 [HC0[0]:SC0[0]:HE1:SE1] takes:
 (&(&host->lock)->rlock#2){?.-...}, at: [<c04b57a4>] esdhc_send_tuning_cmd+0x104/0x14c
{IN-HARDIRQ-W} state was registered at:
  [<c00652fc>] mark_lock+0x15c/0x6f8
  [<c0066354>] __lock_acquire+0xabc/0x1ca0
  [<c0067ad8>] lock_acquire+0xa0/0x130
  [<c0697a44>] _raw_spin_lock+0x34/0x44
  [<c04b0dbc>] sdhci_irq+0x20/0xa40
  [<c0071b1c>] handle_irq_event_percpu+0x74/0x284
  [<c0071d70>] handle_irq_event+0x44/0x64
  [<c0074db8>] handle_fasteoi_irq+0xac/0x140
  [<c007147c>] generic_handle_irq+0x28/0x38
  [<c000efd4>] handle_IRQ+0x40/0x98
  [<c0008584>] gic_handle_irq+0x30/0x64
  [<c0013144>] __irq_svc+0x44/0x58
  [<c0028fc8>] irq_exit+0xc0/0x120
  [<c000efd8>] handle_IRQ+0x44/0x98
  [<c0008584>] gic_handle_irq+0x30/0x64
  [<c0013144>] __irq_svc+0x44/0x58
  [<c068f398>] printk+0x3c/0x44
  [<c03191d0>] _regulator_get+0x1b4/0x1e0
  [<c031924c>] regulator_get+0x18/0x1c
  [<c049fbc4>] mmc_add_host+0x30/0x1c0
  [<c04b2e10>] sdhci_add_host+0x804/0xbbc
  [<c04b5318>] sdhci_esdhc_imx_probe+0x380/0x674
  [<c036d530>] platform_drv_probe+0x20/0x50
  [<c036b948>] driver_probe_device+0x120/0x234
  [<c036baf8>] __driver_attach+0x9c/0xa0
  [<c036a04c>] bus_for_each_dev+0x5c/0x90
  [<c036b418>] driver_attach+0x24/0x28
  [<c036b018>] bus_add_driver+0xe4/0x1d8
  [<c036c1b0>] driver_register+0x80/0xfc
  [<c036ce28>] __platform_driver_register+0x50/0x64
  [<c093706c>] sdhci_esdhc_imx_driver_init+0x18/0x20
  [<c0008834>] do_one_initcall+0x3c/0x164
  [<c0901c94>] kernel_init_freeable+0x104/0x1d0
  [<c068c45c>] kernel_init+0x10/0x118
  [<c000e768>] ret_from_fork+0x14/0x2c
irq event stamp: 5933
hardirqs last  enabled at (5933): [<c069813c>] _raw_spin_unlock_irqrestore+0x38/0x4c
hardirqs last disabled at (5932): [<c0697b04>] _raw_spin_lock_irqsave+0x24/0x60
softirqs last  enabled at (5914): [<c0028ba0>] __do_softirq+0x260/0x360
softirqs last disabled at (5909): [<c0028fc8>] irq_exit+0xc0/0x120

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&(&host->lock)->rlock#2);
  <Interrupt>
    lock(&(&host->lock)->rlock#2);

 *** DEADLOCK ***

2 locks held by kworker/u8:0/6:
 #0:  (kmmcd){.+.+.+}, at: [<c003d890>] process_one_work+0x134/0x4e8
 #1:  ((&(&host->detect)->work)){+.+.+.}, at: [<c003d890>] process_one_work+0x134/0x4e8

stack backtrace:
CPU: 2 PID: 6 Comm: kworker/u8:0 Not tainted 3.14.0-rc1+ #490
Workqueue: kmmcd mmc_rescan
Backtrace:
[<c00124a0>] (dump_backtrace) from [<c0012640>] (show_stack+0x18/0x1c)
[<c0012628>] (show_stack) from [<c069164c>] (dump_stack+0x70/0x8c)
[<c06915dc>] (dump_stack) from [<c068f080>] (print_usage_bug+0x274/0x2e4)
[<c068ee0c>] (print_usage_bug) from [<c0065774>] (mark_lock+0x5d4/0x6f8)
[<c00651a0>] (mark_lock) from [<c0065e6c>] (__lock_acquire+0x5d4/0x1ca0)
[<c0065898>] (__lock_acquire) from [<c0067ad8>] (lock_acquire+0xa0/0x130)
[<c0067a38>] (lock_acquire) from [<c0697a44>] (_raw_spin_lock+0x34/0x44)
[<c0697a10>] (_raw_spin_lock) from [<c04b57a4>] (esdhc_send_tuning_cmd+0x104/0x14c)
[<c04b56a0>] (esdhc_send_tuning_cmd) from [<c04b582c>] (esdhc_executing_tuning+0x40/0x100)
[<c04b57ec>] (esdhc_executing_tuning) from [<c04afa54>] (sdhci_execute_tuning+0xcc/0x754)
[<c04af988>] (sdhci_execute_tuning) from [<c04a4684>] (mmc_sd_init_card+0x65c/0x694)
[<c04a4028>] (mmc_sd_init_card) from [<c04a48f0>] (mmc_attach_sd+0xb0/0x184)
[<c04a4840>] (mmc_attach_sd) from [<c049eb28>] (mmc_rescan+0x26c/0x2e8)
[<c049e8bc>] (mmc_rescan) from [<c003d914>] (process_one_work+0x1b8/0x4e8)
[<c003d75c>] (process_one_work) from [<c003e090>] (worker_thread+0x13c/0x3f8)
[<c003df54>] (worker_thread) from [<c00449bc>] (kthread+0xcc/0xe8)
[<c00448f0>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a9a20c856b0b..5ad4883155a5 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -736,14 +736,12 @@ static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
 	mrq.done = esdhc_request_done;
 	init_completion(&(mrq.completion));
 
-	disable_irq(host->irq);
-	spin_lock(&host->lock);
=+DO NOT APPLY+=	spin_lock_irq(&host->lock);
 	host->mrq = &mrq;
 
 	sdhci_send_command(host, mrq.cmd);
 
-	spin_unlock(&host->lock);
-	enable_irq(host->irq);
=+DO NOT APPLY+=	spin_unlock_irq(&host->lock);
 
 	wait_for_completion(&mrq.completion);
 
-- 
1.8.3.1


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

* [PATCH RFC 22/31] mmc: sdhci-esdhc-imx: fix lockdep splat upon tuning
@ 2014-02-18 15:10   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

=================================
[ INFO: inconsistent lock state ]
3.14.0-rc1+ #490 Not tainted
=-DO NOT APPLY-=------------------------------
inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
kworker/u8:0/6 [HC0[0]:SC0[0]:HE1:SE1] takes:
 (&(&host->lock)->rlock#2){?.-...}, at: [<c04b57a4>] esdhc_send_tuning_cmd+0x104/0x14c
{IN-HARDIRQ-W} state was registered at:
  [<c00652fc>] mark_lock+0x15c/0x6f8
  [<c0066354>] __lock_acquire+0xabc/0x1ca0
  [<c0067ad8>] lock_acquire+0xa0/0x130
  [<c0697a44>] _raw_spin_lock+0x34/0x44
  [<c04b0dbc>] sdhci_irq+0x20/0xa40
  [<c0071b1c>] handle_irq_event_percpu+0x74/0x284
  [<c0071d70>] handle_irq_event+0x44/0x64
  [<c0074db8>] handle_fasteoi_irq+0xac/0x140
  [<c007147c>] generic_handle_irq+0x28/0x38
  [<c000efd4>] handle_IRQ+0x40/0x98
  [<c0008584>] gic_handle_irq+0x30/0x64
  [<c0013144>] __irq_svc+0x44/0x58
  [<c0028fc8>] irq_exit+0xc0/0x120
  [<c000efd8>] handle_IRQ+0x44/0x98
  [<c0008584>] gic_handle_irq+0x30/0x64
  [<c0013144>] __irq_svc+0x44/0x58
  [<c068f398>] printk+0x3c/0x44
  [<c03191d0>] _regulator_get+0x1b4/0x1e0
  [<c031924c>] regulator_get+0x18/0x1c
  [<c049fbc4>] mmc_add_host+0x30/0x1c0
  [<c04b2e10>] sdhci_add_host+0x804/0xbbc
  [<c04b5318>] sdhci_esdhc_imx_probe+0x380/0x674
  [<c036d530>] platform_drv_probe+0x20/0x50
  [<c036b948>] driver_probe_device+0x120/0x234
  [<c036baf8>] __driver_attach+0x9c/0xa0
  [<c036a04c>] bus_for_each_dev+0x5c/0x90
  [<c036b418>] driver_attach+0x24/0x28
  [<c036b018>] bus_add_driver+0xe4/0x1d8
  [<c036c1b0>] driver_register+0x80/0xfc
  [<c036ce28>] __platform_driver_register+0x50/0x64
  [<c093706c>] sdhci_esdhc_imx_driver_init+0x18/0x20
  [<c0008834>] do_one_initcall+0x3c/0x164
  [<c0901c94>] kernel_init_freeable+0x104/0x1d0
  [<c068c45c>] kernel_init+0x10/0x118
  [<c000e768>] ret_from_fork+0x14/0x2c
irq event stamp: 5933
hardirqs last  enabled at (5933): [<c069813c>] _raw_spin_unlock_irqrestore+0x38/0x4c
hardirqs last disabled at (5932): [<c0697b04>] _raw_spin_lock_irqsave+0x24/0x60
softirqs last  enabled at (5914): [<c0028ba0>] __do_softirq+0x260/0x360
softirqs last disabled at (5909): [<c0028fc8>] irq_exit+0xc0/0x120

other info that might help us debug this:
 Possible unsafe locking scenario:

       CPU0
       ----
  lock(&(&host->lock)->rlock#2);
  <Interrupt>
    lock(&(&host->lock)->rlock#2);

 *** DEADLOCK ***

2 locks held by kworker/u8:0/6:
 #0:  (kmmcd){.+.+.+}, at: [<c003d890>] process_one_work+0x134/0x4e8
 #1:  ((&(&host->detect)->work)){+.+.+.}, at: [<c003d890>] process_one_work+0x134/0x4e8

stack backtrace:
CPU: 2 PID: 6 Comm: kworker/u8:0 Not tainted 3.14.0-rc1+ #490
Workqueue: kmmcd mmc_rescan
Backtrace:
[<c00124a0>] (dump_backtrace) from [<c0012640>] (show_stack+0x18/0x1c)
[<c0012628>] (show_stack) from [<c069164c>] (dump_stack+0x70/0x8c)
[<c06915dc>] (dump_stack) from [<c068f080>] (print_usage_bug+0x274/0x2e4)
[<c068ee0c>] (print_usage_bug) from [<c0065774>] (mark_lock+0x5d4/0x6f8)
[<c00651a0>] (mark_lock) from [<c0065e6c>] (__lock_acquire+0x5d4/0x1ca0)
[<c0065898>] (__lock_acquire) from [<c0067ad8>] (lock_acquire+0xa0/0x130)
[<c0067a38>] (lock_acquire) from [<c0697a44>] (_raw_spin_lock+0x34/0x44)
[<c0697a10>] (_raw_spin_lock) from [<c04b57a4>] (esdhc_send_tuning_cmd+0x104/0x14c)
[<c04b56a0>] (esdhc_send_tuning_cmd) from [<c04b582c>] (esdhc_executing_tuning+0x40/0x100)
[<c04b57ec>] (esdhc_executing_tuning) from [<c04afa54>] (sdhci_execute_tuning+0xcc/0x754)
[<c04af988>] (sdhci_execute_tuning) from [<c04a4684>] (mmc_sd_init_card+0x65c/0x694)
[<c04a4028>] (mmc_sd_init_card) from [<c04a48f0>] (mmc_attach_sd+0xb0/0x184)
[<c04a4840>] (mmc_attach_sd) from [<c049eb28>] (mmc_rescan+0x26c/0x2e8)
[<c049e8bc>] (mmc_rescan) from [<c003d914>] (process_one_work+0x1b8/0x4e8)
[<c003d75c>] (process_one_work) from [<c003e090>] (worker_thread+0x13c/0x3f8)
[<c003df54>] (worker_thread) from [<c00449bc>] (kthread+0xcc/0xe8)
[<c00448f0>] (kthread) from [<c000e768>] (ret_from_fork+0x14/0x2c)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a9a20c856b0b..5ad4883155a5 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -736,14 +736,12 @@ static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
 	mrq.done = esdhc_request_done;
 	init_completion(&(mrq.completion));
 
-	disable_irq(host->irq);
-	spin_lock(&host->lock);
=+DO NOT APPLY+=	spin_lock_irq(&host->lock);
 	host->mrq = &mrq;
 
 	sdhci_send_command(host, mrq.cmd);
 
-	spin_unlock(&host->lock);
-	enable_irq(host->irq);
=+DO NOT APPLY+=	spin_unlock_irq(&host->lock);
 
 	wait_for_completion(&mrq.completion);
 
-- 
1.8.3.1

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

* [PATCH RFC 23/31] mmc: sdhci: hack up driver to make it more compliant with UHS-1
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Patch suggested by Dong Aisheng <dongas86@gmail.com>, this avoids
additional clock start/stop cycles during the transition to 1.8V
signalling mode.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ddd57bc235ab..4b6ee2029604 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1507,12 +1507,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			host->ops->set_clock(host, host->clock);
 		}
 
-
-		/* Reset SD Clock Enable */
-		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-		clk &= ~SDHCI_CLOCK_CARD_EN;
-		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
 		if (host->ops->set_uhs_signaling)
 			host->ops->set_uhs_signaling(host, ios->timing);
 		else {
@@ -1546,9 +1540,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK)
 				>> SDHCI_PRESET_DRV_SHIFT;
 		}
-
-		/* Re-enable SD Clock */
-		host->ops->set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -1757,9 +1748,6 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
 		ctrl |= SDHCI_CTRL_VDD_180;
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-		/* Wait for 5ms */
-		usleep_range(5000, 5500);
-
 		/* 1.8V regulator output should be stable within 5 ms */
 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (ctrl & SDHCI_CTRL_VDD_180)
-- 
1.8.3.1


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

* [PATCH RFC 23/31] mmc: sdhci: hack up driver to make it more compliant with UHS-1
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Patch suggested by Dong Aisheng <dongas86@gmail.com>, this avoids
additional clock start/stop cycles during the transition to 1.8V
signalling mode.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ddd57bc235ab..4b6ee2029604 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1507,12 +1507,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			host->ops->set_clock(host, host->clock);
 		}
 
-
-		/* Reset SD Clock Enable */
-		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-		clk &= ~SDHCI_CLOCK_CARD_EN;
-		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
-
 		if (host->ops->set_uhs_signaling)
 			host->ops->set_uhs_signaling(host, ios->timing);
 		else {
@@ -1546,9 +1540,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK)
 				>> SDHCI_PRESET_DRV_SHIFT;
 		}
-
-		/* Re-enable SD Clock */
-		host->ops->set_clock(host, host->clock);
 	} else
 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
@@ -1757,9 +1748,6 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
 		ctrl |= SDHCI_CTRL_VDD_180;
 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-		/* Wait for 5ms */
-		usleep_range(5000, 5500);
-
 		/* 1.8V regulator output should be stable within 5 ms */
 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (ctrl & SDHCI_CTRL_VDD_180)
-- 
1.8.3.1

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

* [PATCH RFC 24/31] mmc: sdhci: set_uhs_signaling() need not return a value
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

The set_uhs_signaling() method gives the impression that it can fail,
but anything returned from the method is entirely ignored by the sdhci
driver.  So returning failure has no effect.

So, kill the idea that it's possible for this to return an error by
removing the returned value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 4 ++--
 drivers/mmc/host/sdhci-pxav3.c     | 4 +---
 drivers/mmc/host/sdhci.h           | 2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5ad4883155a5..ae346d60adb7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -839,7 +839,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
-static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
@@ -877,7 +877,7 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 		break;
 	}
 
-	return esdhc_change_pinstate(host, uhs);
=+DO NOT APPLY+=	esdhc_change_pinstate(host, uhs);
 }
 
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 3d6b574528ea..13f8552ed0b3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -131,7 +131,7 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode)
 	pxa->power_mode = power_mode;
 }
 
-static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
 	u16 ctrl_2;
 
@@ -165,8 +165,6 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 	dev_dbg(mmc_dev(host->mmc),
 		"%s uhs = %d, ctrl_2 = %04X\n",
 		__func__, uhs, ctrl_2);
-
-	return 0;
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index ac20195f667b..3179a8053019 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -287,7 +287,7 @@ struct sdhci_ops {
 	unsigned int    (*get_ro)(struct sdhci_host *host);
 	void		(*reset)(struct sdhci_host *host, u8 mask);
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
-	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
=+DO NOT APPLY+=	void	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
 	void	(*platform_suspend)(struct sdhci_host *host);
 	void	(*platform_resume)(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 24/31] mmc: sdhci: set_uhs_signaling() need not return a value
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

The set_uhs_signaling() method gives the impression that it can fail,
but anything returned from the method is entirely ignored by the sdhci
driver.  So returning failure has no effect.

So, kill the idea that it's possible for this to return an error by
removing the returned value.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 4 ++--
 drivers/mmc/host/sdhci-pxav3.c     | 4 +---
 drivers/mmc/host/sdhci.h           | 2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5ad4883155a5..ae346d60adb7 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -839,7 +839,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
-static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
@@ -877,7 +877,7 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 		break;
 	}
 
-	return esdhc_change_pinstate(host, uhs);
=+DO NOT APPLY+=	esdhc_change_pinstate(host, uhs);
 }
 
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 3d6b574528ea..13f8552ed0b3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -131,7 +131,7 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode)
 	pxa->power_mode = power_mode;
 }
 
-static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
 	u16 ctrl_2;
 
@@ -165,8 +165,6 @@ static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 	dev_dbg(mmc_dev(host->mmc),
 		"%s uhs = %d, ctrl_2 = %04X\n",
 		__func__, uhs, ctrl_2);
-
-	return 0;
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index ac20195f667b..3179a8053019 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -287,7 +287,7 @@ struct sdhci_ops {
 	unsigned int    (*get_ro)(struct sdhci_host *host);
 	void		(*reset)(struct sdhci_host *host, u8 mask);
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
-	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
=+DO NOT APPLY+=	void	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
 	void	(*platform_suspend)(struct sdhci_host *host);
 	void	(*platform_resume)(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 25/31] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
  2014-02-18 15:08 ` Russell King - ARM Linux
  (?)
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Michal Simek, Anton Vorontsov, Ben Dooks, Barry Song,
	Viresh Kumar, Stephen Warren, Thierry Reding, linuxppc-dev,
	spear-devel, linux-tegra

Add sdhci_set_uhs_signaling() and always call the set_uhs_signaling
method.  This avoids quirks being added into sdhci_set_uhs_signaling().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 42 +++++++++++++++++++++-----------------
 drivers/mmc/host/sdhci.h           |  1 +
 18 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index c20964e577e9..2ece31d88196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -105,6 +105,7 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
@@ -112,6 +113,7 @@ static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 77b14b1a24bc..20096aaf14b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -211,6 +211,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 74906d6008e1..46af9a439d7b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -136,6 +136,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 587d73ef33ff..14b74075589a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -81,6 +81,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
 	.reset          = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4f4216115aed..8d6d0a293f17 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -89,6 +89,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f0ee594f25d1..5bd1092310f2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -57,6 +57,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index c4f8cd3f83c8..fcaeae5f55b8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index a4a1f0f2c0a0..b341661369a2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -61,6 +61,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 01ee60d17b04..ba4eaf03200d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1062,6 +1062,7 @@ static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 1fb89f44bd58..7e834fb78f42 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -48,6 +48,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index db5257bf032e..3c0f3c0a1cc8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -116,6 +116,7 @@ static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 13f8552ed0b3..4c5e52fbc6ee 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -174,6 +174,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = pxav3_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 63496bd62196..a633418ddcfa 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -375,6 +375,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
 	.reset			= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling	= sdhci_set_uhs_signaling,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 3b775348b470..17004531d089 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -32,6 +32,7 @@ static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index f365a3fc7612..94ae64d23ef3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -40,6 +40,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a0a8b5cc3b0c..d06b6ff60432 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -156,6 +156,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4b6ee2029604..d7e142ea55ef 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1404,6 +1404,28 @@ void sdhci_set_bus_width(struct sdhci_host *host, int width)
 }
 EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
 
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u16 ctrl_2;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=	/* Select Bus Speed Mode for host */
=+DO NOT APPLY+=	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
=+DO NOT APPLY+=	if ((timing == MMC_TIMING_MMC_HS200) ||
=+DO NOT APPLY+=	    (timing == MMC_TIMING_UHS_SDR104))
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR12)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR25)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_DDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
=+DO NOT APPLY+=	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			host->ops->set_clock(host, host->clock);
 		}
 
-		if (host->ops->set_uhs_signaling)
-			host->ops->set_uhs_signaling(host, ios->timing);
-		else {
-			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-			/* Select Bus Speed Mode for host */
-			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
-			if ((ios->timing == MMC_TIMING_MMC_HS200) ||
-			    (ios->timing == MMC_TIMING_UHS_SDR104))
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
-			else if (ios->timing == MMC_TIMING_UHS_SDR12)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
-			else if (ios->timing == MMC_TIMING_UHS_SDR25)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
-			else if (ios->timing == MMC_TIMING_UHS_SDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
-			else if (ios->timing == MMC_TIMING_UHS_DDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
-			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
-		}
=+DO NOT APPLY+=		host->ops->set_uhs_signaling(host, ios->timing);
 
 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3179a8053019..7a35395e5f56 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -403,6 +403,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 25/31] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Barry Song, spear-devel, Stephen Warren, Anton Vorontsov,
	Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra, linuxppc-dev

Add sdhci_set_uhs_signaling() and always call the set_uhs_signaling
method.  This avoids quirks being added into sdhci_set_uhs_signaling().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 42 +++++++++++++++++++++-----------------
 drivers/mmc/host/sdhci.h           |  1 +
 18 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index c20964e577e9..2ece31d88196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -105,6 +105,7 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
@@ -112,6 +113,7 @@ static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 77b14b1a24bc..20096aaf14b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -211,6 +211,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 74906d6008e1..46af9a439d7b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -136,6 +136,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 587d73ef33ff..14b74075589a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -81,6 +81,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
 	.reset          = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4f4216115aed..8d6d0a293f17 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -89,6 +89,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f0ee594f25d1..5bd1092310f2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -57,6 +57,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index c4f8cd3f83c8..fcaeae5f55b8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index a4a1f0f2c0a0..b341661369a2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -61,6 +61,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 01ee60d17b04..ba4eaf03200d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1062,6 +1062,7 @@ static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 1fb89f44bd58..7e834fb78f42 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -48,6 +48,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index db5257bf032e..3c0f3c0a1cc8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -116,6 +116,7 @@ static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 13f8552ed0b3..4c5e52fbc6ee 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -174,6 +174,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = pxav3_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 63496bd62196..a633418ddcfa 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -375,6 +375,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
 	.reset			= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling	= sdhci_set_uhs_signaling,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 3b775348b470..17004531d089 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -32,6 +32,7 @@ static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index f365a3fc7612..94ae64d23ef3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -40,6 +40,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a0a8b5cc3b0c..d06b6ff60432 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -156,6 +156,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4b6ee2029604..d7e142ea55ef 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1404,6 +1404,28 @@ void sdhci_set_bus_width(struct sdhci_host *host, int width)
 }
 EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
 
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u16 ctrl_2;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=	/* Select Bus Speed Mode for host */
=+DO NOT APPLY+=	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
=+DO NOT APPLY+=	if ((timing == MMC_TIMING_MMC_HS200) ||
=+DO NOT APPLY+=	    (timing == MMC_TIMING_UHS_SDR104))
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR12)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR25)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_DDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
=+DO NOT APPLY+=	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			host->ops->set_clock(host, host->clock);
 		}
 
-		if (host->ops->set_uhs_signaling)
-			host->ops->set_uhs_signaling(host, ios->timing);
-		else {
-			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-			/* Select Bus Speed Mode for host */
-			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
-			if ((ios->timing == MMC_TIMING_MMC_HS200) ||
-			    (ios->timing == MMC_TIMING_UHS_SDR104))
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
-			else if (ios->timing == MMC_TIMING_UHS_SDR12)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
-			else if (ios->timing == MMC_TIMING_UHS_SDR25)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
-			else if (ios->timing == MMC_TIMING_UHS_SDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
-			else if (ios->timing == MMC_TIMING_UHS_DDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
-			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
-		}
=+DO NOT APPLY+=		host->ops->set_uhs_signaling(host, ios->timing);
 
 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3179a8053019..7a35395e5f56 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -403,6 +403,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 25/31] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Add sdhci_set_uhs_signaling() and always call the set_uhs_signaling
method.  This avoids quirks being added into sdhci_set_uhs_signaling().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-acpi.c      |  2 ++
 drivers/mmc/host/sdhci-bcm-kona.c  |  1 +
 drivers/mmc/host/sdhci-bcm2835.c   |  1 +
 drivers/mmc/host/sdhci-cns3xxx.c   |  1 +
 drivers/mmc/host/sdhci-dove.c      |  1 +
 drivers/mmc/host/sdhci-of-arasan.c |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c  |  1 +
 drivers/mmc/host/sdhci-of-hlwd.c   |  1 +
 drivers/mmc/host/sdhci-pci.c       |  1 +
 drivers/mmc/host/sdhci-pltfm.c     |  1 +
 drivers/mmc/host/sdhci-pxav2.c     |  1 +
 drivers/mmc/host/sdhci-pxav3.c     |  1 +
 drivers/mmc/host/sdhci-s3c.c       |  1 +
 drivers/mmc/host/sdhci-sirf.c      |  1 +
 drivers/mmc/host/sdhci-spear.c     |  1 +
 drivers/mmc/host/sdhci-tegra.c     |  1 +
 drivers/mmc/host/sdhci.c           | 42 +++++++++++++++++++++-----------------
 drivers/mmc/host/sdhci.h           |  1 +
 18 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
index c20964e577e9..2ece31d88196 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-acpi.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-acpi.c
@@ -105,6 +105,7 @@ static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_ops sdhci_acpi_ops_int = {
@@ -112,6 +113,7 @@ static const struct sdhci_ops sdhci_acpi_ops_int = {
 	.enable_dma = sdhci_acpi_enable_dma,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset   = sdhci_acpi_int_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c
index 77b14b1a24bc..20096aaf14b4 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm-kona.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm-kona.c
@@ -211,6 +211,7 @@ static struct sdhci_ops sdhci_bcm_kona_ops = {
 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.card_event = sdhci_bcm_kona_card_event,
 };
 
diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c
index 74906d6008e1..46af9a439d7b 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-bcm2835.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-bcm2835.c
@@ -136,6 +136,7 @@ static const struct sdhci_ops bcm2835_sdhci_ops = {
 	.get_min_clock = bcm2835_sdhci_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index 587d73ef33ff..14b74075589a 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-cns3xxx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -81,6 +81,7 @@ static const struct sdhci_ops sdhci_cns3xxx_ops = {
 	.set_clock	= sdhci_cns3xxx_set_clock,
 	.set_bus_width	= sdhci_set_bus_width,
 	.reset          = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index 4f4216115aed..8d6d0a293f17 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-dove.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-dove.c
@@ -89,6 +89,7 @@ static const struct sdhci_ops sdhci_dove_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_dove_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index f0ee594f25d1..5bd1092310f2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-arasan.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-arasan.c
@@ -57,6 +57,7 @@ static struct sdhci_ops sdhci_arasan_ops = {
 	.get_timeout_clock = sdhci_arasan_get_timeout_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_arasan_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index c4f8cd3f83c8..fcaeae5f55b8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -309,6 +309,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index a4a1f0f2c0a0..b341661369a2 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-hlwd.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -61,6 +61,7 @@ static const struct sdhci_ops sdhci_hlwd_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 01ee60d17b04..ba4eaf03200d 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pci.c
@@ -1062,6 +1062,7 @@ static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.set_bus_width	= sdhci_pci_set_bus_width,
 	.reset		= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 	.hw_reset		= sdhci_pci_hw_reset,
 };
 
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 1fb89f44bd58..7e834fb78f42 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pltfm.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pltfm.c
@@ -48,6 +48,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index db5257bf032e..3c0f3c0a1cc8 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav2.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav2.c
@@ -116,6 +116,7 @@ static const struct sdhci_ops pxav2_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = pxav2_mmc_set_bus_width,
 	.reset         = pxav2_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 13f8552ed0b3..4c5e52fbc6ee 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-pxav3.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-pxav3.c
@@ -174,6 +174,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = pxav3_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 63496bd62196..a633418ddcfa 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-s3c.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-s3c.c
@@ -375,6 +375,7 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.get_min_clock		= sdhci_s3c_get_min_clock,
 	.set_bus_width		= sdhci_s3c_set_bus_width,
 	.reset			= sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling	= sdhci_set_uhs_signaling,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 3b775348b470..17004531d089 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-sirf.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-sirf.c
@@ -32,6 +32,7 @@ static struct sdhci_ops sdhci_sirf_ops = {
 	.get_max_clock	= sdhci_sirf_get_max_clk,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index f365a3fc7612..94ae64d23ef3 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-spear.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-spear.c
@@ -40,6 +40,7 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 /* gpio card detection interrupt handler */
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a0a8b5cc3b0c..d06b6ff60432 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -156,6 +156,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.set_clock  = sdhci_set_clock,
 	.set_bus_width = tegra_sdhci_set_bus_width,
 	.reset      = tegra_sdhci_reset,
=+DO NOT APPLY+=	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4b6ee2029604..d7e142ea55ef 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1404,6 +1404,28 @@ void sdhci_set_bus_width(struct sdhci_host *host, int width)
 }
 EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
 
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	u16 ctrl_2;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=	/* Select Bus Speed Mode for host */
=+DO NOT APPLY+=	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
=+DO NOT APPLY+=	if ((timing == MMC_TIMING_MMC_HS200) ||
=+DO NOT APPLY+=	    (timing == MMC_TIMING_UHS_SDR104))
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR12)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR25)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_SDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
=+DO NOT APPLY+=	else if (timing == MMC_TIMING_UHS_DDR50)
=+DO NOT APPLY+=		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
=+DO NOT APPLY+=	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
=+DO NOT APPLY+=
 static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 {
 	unsigned long flags;
@@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 			host->ops->set_clock(host, host->clock);
 		}
 
-		if (host->ops->set_uhs_signaling)
-			host->ops->set_uhs_signaling(host, ios->timing);
-		else {
-			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-			/* Select Bus Speed Mode for host */
-			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
-			if ((ios->timing == MMC_TIMING_MMC_HS200) ||
-			    (ios->timing == MMC_TIMING_UHS_SDR104))
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
-			else if (ios->timing == MMC_TIMING_UHS_SDR12)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
-			else if (ios->timing == MMC_TIMING_UHS_SDR25)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
-			else if (ios->timing == MMC_TIMING_UHS_SDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
-			else if (ios->timing == MMC_TIMING_UHS_DDR50)
-				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
-			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
-		}
=+DO NOT APPLY+=		host->ops->set_uhs_signaling(host, ios->timing);
 
 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3179a8053019..7a35395e5f56 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -403,6 +403,7 @@ static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
 void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
=+DO NOT APPLY+=void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
 
 #ifdef CONFIG_PM
 extern int sdhci_suspend_host(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 26/31] mmc: sdhci: cache timing information locally
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Rather than reading back the timing information from the registers,
cache it locally.  This allows implementations to translate the UHS
timing by overriding the set_uhs_signaling() method as required
without also having to emulate the SDHCI_HOST_CONTROL2 register.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 23 ++++++++++++-----------
 include/linux/mmc/sdhci.h |  2 ++
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d7e142ea55ef..01eed75d9404 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1083,24 +1083,23 @@ static void sdhci_finish_command(struct sdhci_host *host)
 
 static u16 sdhci_get_preset_value(struct sdhci_host *host)
 {
-	u16 ctrl, preset = 0;
=+DO NOT APPLY+=	u16 preset = 0;
 
-	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
-	switch (ctrl & SDHCI_CTRL_UHS_MASK) {
-	case SDHCI_CTRL_UHS_SDR12:
=+DO NOT APPLY+=	switch (host->timing) {
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR12:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
 		break;
-	case SDHCI_CTRL_UHS_SDR25:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR25:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
 		break;
-	case SDHCI_CTRL_UHS_SDR50:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR50:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
 		break;
-	case SDHCI_CTRL_UHS_SDR104:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR104:
=+DO NOT APPLY+=	case MMC_TIMING_MMC_HS200:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
 		break;
-	case SDHCI_CTRL_UHS_DDR50:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_DDR50:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
 		break;
 	default:
@@ -1530,6 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		host->ops->set_uhs_signaling(host, ios->timing);
=+DO NOT APPLY+=		host->timing = ios->timing;
 
 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
@@ -1828,12 +1828,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * If the Host Controller supports the HS200 mode then the
 	 * tuning function has to be executed.
 	 */
-	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
=+DO NOT APPLY+=	if (host->timing == MMC_TIMING_UHS_SDR50 &&
 	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
 	     host->flags & SDHCI_SDR104_NEEDS_TUNING))
 		requires_tuning_nonuhs = true;
 
-	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
=+DO NOT APPLY+=	if (host->timing == MMC_TIMING_MMC_HS200 ||
=+DO NOT APPLY+=	    host->timing == MMC_TIMING_UHS_SDR104 ||
 	    requires_tuning_nonuhs)
 		ctrl |= SDHCI_CTRL_EXEC_TUNING;
 	else {
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 20daa39e3a68..54fff6156d1b 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -170,6 +170,8 @@ struct sdhci_host {
 	unsigned int            ocr_avail_mmc;
 	u32 ocr_mask;		/* available voltages */
 
=+DO NOT APPLY+=	unsigned		timing;		/* Current timing */
=+DO NOT APPLY+=
 	u32			thread_isr;
 
 	/* cached registers */
-- 
1.8.3.1


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

* [PATCH RFC 26/31] mmc: sdhci: cache timing information locally
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than reading back the timing information from the registers,
cache it locally.  This allows implementations to translate the UHS
timing by overriding the set_uhs_signaling() method as required
without also having to emulate the SDHCI_HOST_CONTROL2 register.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c  | 23 ++++++++++++-----------
 include/linux/mmc/sdhci.h |  2 ++
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d7e142ea55ef..01eed75d9404 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1083,24 +1083,23 @@ static void sdhci_finish_command(struct sdhci_host *host)
 
 static u16 sdhci_get_preset_value(struct sdhci_host *host)
 {
-	u16 ctrl, preset = 0;
=+DO NOT APPLY+=	u16 preset = 0;
 
-	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
-	switch (ctrl & SDHCI_CTRL_UHS_MASK) {
-	case SDHCI_CTRL_UHS_SDR12:
=+DO NOT APPLY+=	switch (host->timing) {
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR12:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
 		break;
-	case SDHCI_CTRL_UHS_SDR25:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR25:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
 		break;
-	case SDHCI_CTRL_UHS_SDR50:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR50:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
 		break;
-	case SDHCI_CTRL_UHS_SDR104:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR104:
=+DO NOT APPLY+=	case MMC_TIMING_MMC_HS200:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
 		break;
-	case SDHCI_CTRL_UHS_DDR50:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_DDR50:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
 		break;
 	default:
@@ -1530,6 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 		}
 
 		host->ops->set_uhs_signaling(host, ios->timing);
=+DO NOT APPLY+=		host->timing = ios->timing;
 
 		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
 				((ios->timing == MMC_TIMING_UHS_SDR12) ||
@@ -1828,12 +1828,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * If the Host Controller supports the HS200 mode then the
 	 * tuning function has to be executed.
 	 */
-	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
=+DO NOT APPLY+=	if (host->timing == MMC_TIMING_UHS_SDR50 &&
 	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
 	     host->flags & SDHCI_SDR104_NEEDS_TUNING))
 		requires_tuning_nonuhs = true;
 
-	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
=+DO NOT APPLY+=	if (host->timing == MMC_TIMING_MMC_HS200 ||
=+DO NOT APPLY+=	    host->timing == MMC_TIMING_UHS_SDR104 ||
 	    requires_tuning_nonuhs)
 		ctrl |= SDHCI_CTRL_EXEC_TUNING;
 	else {
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 20daa39e3a68..54fff6156d1b 100644
=-DO NOT APPLY-= a/include/linux/mmc/sdhci.h
=+DO NOT APPLY+= b/include/linux/mmc/sdhci.h
@@ -170,6 +170,8 @@ struct sdhci_host {
 	unsigned int            ocr_avail_mmc;
 	u32 ocr_mask;		/* available voltages */
 
=+DO NOT APPLY+=	unsigned		timing;		/* Current timing */
=+DO NOT APPLY+=
 	u32			thread_isr;
 
 	/* cached registers */
-- 
1.8.3.1

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

* [PATCH RFC 27/31] mmc: sdhci: clean up sdhci_execute_tuning() decision
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

Clean up the code in sdhci_execute_tuning() so the decision whether
to execute tuning is clearer - and despite this reflecting what the
original code was doing, it shows that it may not be what the author
actually intended.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 01eed75d9404..224ca833410c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1806,21 +1806,16 @@ static int sdhci_card_busy(struct mmc_host *mmc)
 
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
-	struct sdhci_host *host;
=+DO NOT APPLY+=	struct sdhci_host *host = mmc_priv(mmc);
 	u16 ctrl;
 	int tuning_loop_counter = MAX_TUNING_LOOP;
 	unsigned long timeout;
 	int err = 0;
-	bool requires_tuning_nonuhs = false;
 	unsigned long flags;
 
-	host = mmc_priv(mmc);
-
 	sdhci_runtime_pm_get(host);
 	spin_lock_irqsave(&host->lock, flags);
 
-	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
 	/*
 	 * The Host Controller needs tuning only in case of SDR104 mode
 	 * and for SDR50 mode when Use Tuning for SDR50 is set in the
@@ -1828,16 +1823,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * If the Host Controller supports the HS200 mode then the
 	 * tuning function has to be executed.
 	 */
-	if (host->timing == MMC_TIMING_UHS_SDR50 &&
-	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
-	     host->flags & SDHCI_SDR104_NEEDS_TUNING))
-		requires_tuning_nonuhs = true;
-
-	if (host->timing == MMC_TIMING_MMC_HS200 ||
-	    host->timing == MMC_TIMING_UHS_SDR104 ||
-	    requires_tuning_nonuhs)
-		ctrl |= SDHCI_CTRL_EXEC_TUNING;
-	else {
=+DO NOT APPLY+=	switch (host->timing) {
=+DO NOT APPLY+=	case MMC_TIMING_MMC_HS200:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR104:
=+DO NOT APPLY+=		break;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR50:
=+DO NOT APPLY+=		if (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
=+DO NOT APPLY+=		    host->flags & SDHCI_SDR104_NEEDS_TUNING)
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		/* FALLTHROUGH */
=+DO NOT APPLY+=
=+DO NOT APPLY+=	default:
 		spin_unlock_irqrestore(&host->lock, flags);
 		sdhci_runtime_pm_put(host);
 		return 0;
@@ -1850,6 +1847,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 		return err;
 	}
 
=+DO NOT APPLY+=	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=	ctrl |= SDHCI_CTRL_EXEC_TUNING;
 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
 	/*
-- 
1.8.3.1


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

* [PATCH RFC 27/31] mmc: sdhci: clean up sdhci_execute_tuning() decision
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Clean up the code in sdhci_execute_tuning() so the decision whether
to execute tuning is clearer - and despite this reflecting what the
original code was doing, it shows that it may not be what the author
actually intended.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 01eed75d9404..224ca833410c 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -1806,21 +1806,16 @@ static int sdhci_card_busy(struct mmc_host *mmc)
 
 static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
-	struct sdhci_host *host;
=+DO NOT APPLY+=	struct sdhci_host *host = mmc_priv(mmc);
 	u16 ctrl;
 	int tuning_loop_counter = MAX_TUNING_LOOP;
 	unsigned long timeout;
 	int err = 0;
-	bool requires_tuning_nonuhs = false;
 	unsigned long flags;
 
-	host = mmc_priv(mmc);
-
 	sdhci_runtime_pm_get(host);
 	spin_lock_irqsave(&host->lock, flags);
 
-	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
 	/*
 	 * The Host Controller needs tuning only in case of SDR104 mode
 	 * and for SDR50 mode when Use Tuning for SDR50 is set in the
@@ -1828,16 +1823,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	 * If the Host Controller supports the HS200 mode then the
 	 * tuning function has to be executed.
 	 */
-	if (host->timing == MMC_TIMING_UHS_SDR50 &&
-	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
-	     host->flags & SDHCI_SDR104_NEEDS_TUNING))
-		requires_tuning_nonuhs = true;
-
-	if (host->timing == MMC_TIMING_MMC_HS200 ||
-	    host->timing == MMC_TIMING_UHS_SDR104 ||
-	    requires_tuning_nonuhs)
-		ctrl |= SDHCI_CTRL_EXEC_TUNING;
-	else {
=+DO NOT APPLY+=	switch (host->timing) {
=+DO NOT APPLY+=	case MMC_TIMING_MMC_HS200:
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR104:
=+DO NOT APPLY+=		break;
=+DO NOT APPLY+=
=+DO NOT APPLY+=	case MMC_TIMING_UHS_SDR50:
=+DO NOT APPLY+=		if (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
=+DO NOT APPLY+=		    host->flags & SDHCI_SDR104_NEEDS_TUNING)
=+DO NOT APPLY+=			break;
=+DO NOT APPLY+=		/* FALLTHROUGH */
=+DO NOT APPLY+=
=+DO NOT APPLY+=	default:
 		spin_unlock_irqrestore(&host->lock, flags);
 		sdhci_runtime_pm_put(host);
 		return 0;
@@ -1850,6 +1847,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 		return err;
 	}
 
=+DO NOT APPLY+=	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
=+DO NOT APPLY+=	ctrl |= SDHCI_CTRL_EXEC_TUNING;
 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
 	/*
-- 
1.8.3.1

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

* [PATCH RFC 28/31] mmc: sdhci-esdhc-imx: remove emulation of uhs_mode
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

We no longer need to emulate the uhs_mode field of the host control2
register - the main sdhci driver never reads this back to evaluate
the current mode as it caches the current mode instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ae346d60adb7..dbb7d91a1c49 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -160,7 +160,6 @@ struct pltfm_imx_data {
 		MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
 		WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
 	} multiblock_status;
-	u32 uhs_mode;
 	u32 is_ddr;
 };
 
@@ -382,7 +381,6 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
 		if (val & ESDHC_MIX_CTRL_SMPCLK_SEL)
 			ret |= SDHCI_CTRL_TUNED_CLK;
 
-		ret |= (imx_data->uhs_mode & SDHCI_CTRL_UHS_MASK);
 		ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
 
 		return ret;
@@ -429,7 +427,6 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		else
 			new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
 		writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
-		imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
 		if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
 			new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
 			if (val & SDHCI_CTRL_TUNED_CLK)
@@ -839,28 +836,20 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
-static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
-	switch (uhs) {
=+DO NOT APPLY+=	switch (timing) {
 	case MMC_TIMING_UHS_SDR12:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR12;
-		break;
 	case MMC_TIMING_UHS_SDR25:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR25;
-		break;
 	case MMC_TIMING_UHS_SDR50:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR50;
-		break;
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR104;
 		break;
 	case MMC_TIMING_UHS_DDR50:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_DDR50;
 		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
 				ESDHC_MIX_CTRL_DDREN,
 				host->ioaddr + ESDHC_MIX_CTRL);
@@ -877,7 +866,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 		break;
 	}
 
-	esdhc_change_pinstate(host, uhs);
=+DO NOT APPLY+=	esdhc_change_pinstate(host, timing);
 }
 
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
-- 
1.8.3.1


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

* [PATCH RFC 28/31] mmc: sdhci-esdhc-imx: remove emulation of uhs_mode
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

We no longer need to emulate the uhs_mode field of the host control2
register - the main sdhci driver never reads this back to evaluate
the current mode as it caches the current mode instead.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-esdhc-imx.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ae346d60adb7..dbb7d91a1c49 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-esdhc-imx.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -160,7 +160,6 @@ struct pltfm_imx_data {
 		MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
 		WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
 	} multiblock_status;
-	u32 uhs_mode;
 	u32 is_ddr;
 };
 
@@ -382,7 +381,6 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
 		if (val & ESDHC_MIX_CTRL_SMPCLK_SEL)
 			ret |= SDHCI_CTRL_TUNED_CLK;
 
-		ret |= (imx_data->uhs_mode & SDHCI_CTRL_UHS_MASK);
 		ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
 
 		return ret;
@@ -429,7 +427,6 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		else
 			new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
 		writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
-		imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
 		if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
 			new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
 			if (val & SDHCI_CTRL_TUNED_CLK)
@@ -839,28 +836,20 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
-static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
=+DO NOT APPLY+=static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
-	switch (uhs) {
=+DO NOT APPLY+=	switch (timing) {
 	case MMC_TIMING_UHS_SDR12:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR12;
-		break;
 	case MMC_TIMING_UHS_SDR25:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR25;
-		break;
 	case MMC_TIMING_UHS_SDR50:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR50;
-		break;
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR104;
 		break;
 	case MMC_TIMING_UHS_DDR50:
-		imx_data->uhs_mode = SDHCI_CTRL_UHS_DDR50;
 		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
 				ESDHC_MIX_CTRL_DDREN,
 				host->ioaddr + ESDHC_MIX_CTRL);
@@ -877,7 +866,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 		break;
 	}
 
-	esdhc_change_pinstate(host, uhs);
=+DO NOT APPLY+=	esdhc_change_pinstate(host, timing);
 }
 
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
-- 
1.8.3.1

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

* [PATCH RFC 29/31] mmc: sdhci-of-esdhc: remove platform_suspend/platform_resume callbacks
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

We don't need these hooks in order to insert code in these paths, we
can just provide our own handlers and call the main sdhci handlers as
appropriate.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-of-esdhc.c | 55 +++++++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fcaeae5f55b8..605815e52f5f 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -241,20 +241,6 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	mdelay(1);
 }
 
-#ifdef CONFIG_PM
-static u32 esdhc_proctl;
-static void esdhc_of_suspend(struct sdhci_host *host)
-{
-	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
-}
-
-static void esdhc_of_resume(struct sdhci_host *host)
-{
-	esdhc_of_enable_dma(host);
-	sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
-}
-#endif
-
 static void esdhc_of_platform_init(struct sdhci_host *host)
 {
 	u32 vvn;
@@ -302,16 +288,47 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.get_max_clock = esdhc_of_get_max_clock,
 	.get_min_clock = esdhc_of_get_min_clock,
 	.platform_init = esdhc_of_platform_init,
-#ifdef CONFIG_PM
-	.platform_suspend = esdhc_of_suspend,
-	.platform_resume = esdhc_of_resume,
-#endif
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.reset = sdhci_reset,
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
=+DO NOT APPLY+=#ifdef CONFIG_PM
=+DO NOT APPLY+=
=+DO NOT APPLY+=static u32 esdhc_proctl;
=+DO NOT APPLY+=static int esdhc_of_suspend(struct device *dev)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_get_drvdata(dev);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return sdhci_suspend_host(host);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
=+DO NOT APPLY+=static void esdhc_of_resume(device *dev)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_get_drvdata(dev);
=+DO NOT APPLY+=	int ret = sdhci_resume_host(host);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (ret == 0) {
=+DO NOT APPLY+=		/* Isn't this already done by sdhci_resume_host() ? --rmk */
=+DO NOT APPLY+=		esdhc_of_enable_dma(host);
=+DO NOT APPLY+=		sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return ret;
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
=+DO NOT APPLY+=static const struct dev_pm_ops esdhc_pmops = {
=+DO NOT APPLY+=	.suspend	= esdhci_of_suspend,
=+DO NOT APPLY+=	.resume		= esdhci_of_resume,
=+DO NOT APPLY+=};
=+DO NOT APPLY+=#define ESDHC_PMOPS (&esdhc_pmops)
=+DO NOT APPLY+=#else
=+DO NOT APPLY+=#define ESDHC_PMOPS NULL
=+DO NOT APPLY+=#endif
=+DO NOT APPLY+=
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 	/*
 	 * card detection could be handled via GPIO
@@ -373,7 +390,7 @@ static struct platform_driver sdhci_esdhc_driver = {
 		.name = "sdhci-esdhc",
 		.owner = THIS_MODULE,
 		.of_match_table = sdhci_esdhc_of_match,
-		.pm = SDHCI_PLTFM_PMOPS,
=+DO NOT APPLY+=		.pm = ESDHC_PMOPS,
 	},
 	.probe = sdhci_esdhc_probe,
 	.remove = sdhci_esdhc_remove,
-- 
1.8.3.1


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

* [PATCH RFC 29/31] mmc: sdhci-of-esdhc: remove platform_suspend/platform_resume callbacks
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need these hooks in order to insert code in these paths, we
can just provide our own handlers and call the main sdhci handlers as
appropriate.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-of-esdhc.c | 55 +++++++++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fcaeae5f55b8..605815e52f5f 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-of-esdhc.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -241,20 +241,6 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	mdelay(1);
 }
 
-#ifdef CONFIG_PM
-static u32 esdhc_proctl;
-static void esdhc_of_suspend(struct sdhci_host *host)
-{
-	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
-}
-
-static void esdhc_of_resume(struct sdhci_host *host)
-{
-	esdhc_of_enable_dma(host);
-	sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
-}
-#endif
-
 static void esdhc_of_platform_init(struct sdhci_host *host)
 {
 	u32 vvn;
@@ -302,16 +288,47 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
 	.get_max_clock = esdhc_of_get_max_clock,
 	.get_min_clock = esdhc_of_get_min_clock,
 	.platform_init = esdhc_of_platform_init,
-#ifdef CONFIG_PM
-	.platform_suspend = esdhc_of_suspend,
-	.platform_resume = esdhc_of_resume,
-#endif
 	.adma_workaround = esdhci_of_adma_workaround,
 	.set_bus_width = esdhc_pltfm_set_bus_width,
 	.reset = sdhci_reset,
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
=+DO NOT APPLY+=#ifdef CONFIG_PM
=+DO NOT APPLY+=
=+DO NOT APPLY+=static u32 esdhc_proctl;
=+DO NOT APPLY+=static int esdhc_of_suspend(struct device *dev)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_get_drvdata(dev);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return sdhci_suspend_host(host);
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
=+DO NOT APPLY+=static void esdhc_of_resume(device *dev)
=+DO NOT APPLY+={
=+DO NOT APPLY+=	struct sdhci_host *host = dev_get_drvdata(dev);
=+DO NOT APPLY+=	int ret = sdhci_resume_host(host);
=+DO NOT APPLY+=
=+DO NOT APPLY+=	if (ret == 0) {
=+DO NOT APPLY+=		/* Isn't this already done by sdhci_resume_host() ? --rmk */
=+DO NOT APPLY+=		esdhc_of_enable_dma(host);
=+DO NOT APPLY+=		sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
=+DO NOT APPLY+=	}
=+DO NOT APPLY+=
=+DO NOT APPLY+=	return ret;
=+DO NOT APPLY+=}
=+DO NOT APPLY+=
=+DO NOT APPLY+=static const struct dev_pm_ops esdhc_pmops = {
=+DO NOT APPLY+=	.suspend	= esdhci_of_suspend,
=+DO NOT APPLY+=	.resume		= esdhci_of_resume,
=+DO NOT APPLY+=};
=+DO NOT APPLY+=#define ESDHC_PMOPS (&esdhc_pmops)
=+DO NOT APPLY+=#else
=+DO NOT APPLY+=#define ESDHC_PMOPS NULL
=+DO NOT APPLY+=#endif
=+DO NOT APPLY+=
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
 	/*
 	 * card detection could be handled via GPIO
@@ -373,7 +390,7 @@ static struct platform_driver sdhci_esdhc_driver = {
 		.name = "sdhci-esdhc",
 		.owner = THIS_MODULE,
 		.of_match_table = sdhci_esdhc_of_match,
-		.pm = SDHCI_PLTFM_PMOPS,
=+DO NOT APPLY+=		.pm = ESDHC_PMOPS,
 	},
 	.probe = sdhci_esdhc_probe,
 	.remove = sdhci_esdhc_remove,
-- 
1.8.3.1

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

* [PATCH RFC 30/31] mmc: sdhci: remove platform_suspend/platform_resume callbacks
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc; +Cc: Chris Ball

The only user (sdhci-of-esdhc) no longer uses these callbacks, so lets
remove them to discourage any further use.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 6 ------
 drivers/mmc/host/sdhci.h | 2 --
 2 files changed, 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 224ca833410c..2ed89c4aa176 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2533,9 +2533,6 @@ EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);
 
 int sdhci_suspend_host(struct sdhci_host *host)
 {
-	if (host->ops->platform_suspend)
-		host->ops->platform_suspend(host);
-
 	sdhci_disable_card_detection(host);
 
 	/* Disable tuning since we are suspending */
@@ -2592,9 +2589,6 @@ int sdhci_resume_host(struct sdhci_host *host)
 
 	sdhci_enable_card_detection(host);
 
-	if (host->ops->platform_resume)
-		host->ops->platform_resume(host);
-
 	/* Set the re-tuning expiration flag */
 	if (host->flags & SDHCI_USING_RETUNING_TIMER)
 		host->flags |= SDHCI_NEEDS_RETUNING;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7a35395e5f56..4a5cd5e3fa3e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -289,8 +289,6 @@ struct sdhci_ops {
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
 	void	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
-	void	(*platform_suspend)(struct sdhci_host *host);
-	void	(*platform_resume)(struct sdhci_host *host);
 	void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
 	void	(*platform_init)(struct sdhci_host *host);
 	void    (*card_event)(struct sdhci_host *host);
-- 
1.8.3.1


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

* [PATCH RFC 30/31] mmc: sdhci: remove platform_suspend/platform_resume callbacks
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

The only user (sdhci-of-esdhc) no longer uses these callbacks, so lets
remove them to discourage any further use.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci.c | 6 ------
 drivers/mmc/host/sdhci.h | 2 --
 2 files changed, 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 224ca833410c..2ed89c4aa176 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.c
@@ -2533,9 +2533,6 @@ EXPORT_SYMBOL_GPL(sdhci_disable_irq_wakeups);
 
 int sdhci_suspend_host(struct sdhci_host *host)
 {
-	if (host->ops->platform_suspend)
-		host->ops->platform_suspend(host);
-
 	sdhci_disable_card_detection(host);
 
 	/* Disable tuning since we are suspending */
@@ -2592,9 +2589,6 @@ int sdhci_resume_host(struct sdhci_host *host)
 
 	sdhci_enable_card_detection(host);
 
-	if (host->ops->platform_resume)
-		host->ops->platform_resume(host);
-
 	/* Set the re-tuning expiration flag */
 	if (host->flags & SDHCI_USING_RETUNING_TIMER)
 		host->flags |= SDHCI_NEEDS_RETUNING;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 7a35395e5f56..4a5cd5e3fa3e 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci.h
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci.h
@@ -289,8 +289,6 @@ struct sdhci_ops {
 	int	(*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
 	void	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
-	void	(*platform_suspend)(struct sdhci_host *host);
-	void	(*platform_resume)(struct sdhci_host *host);
 	void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
 	void	(*platform_init)(struct sdhci_host *host);
 	void    (*card_event)(struct sdhci_host *host);
-- 
1.8.3.1

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

* [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
  2014-02-18 15:08 ` Russell King - ARM Linux
@ 2014-02-18 15:11   ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Stephen Warren, Thierry Reding, linux-tegra

sdhci-tegra provides a get_ro method, which overrides the checking
of the write protect bit in the PRESENT_STATE register in sdhci.c:

        if (host->flags & SDHCI_DEVICE_DEAD)
                is_readonly = 0;
        else if (host->ops->get_ro)
                is_readonly = host->ops->get_ro(host);
        else
                is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
                                & SDHCI_WRITE_PROTECT);

This means it's pointless detecting accesses to this register and
manually setting the SDHCI_WRITE_PROTECT as it has no effect.

This means that the whole of tegra_sdhci_readl() can be removed and
we can use the builtin sdhci readl functionality here.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-tegra.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index d06b6ff60432..985247649f46 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -48,19 +48,6 @@ struct sdhci_tegra {
 	int power_gpio;
 };
 
-static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
-{
-	u32 val;
-
-	if (unlikely(reg == SDHCI_PRESENT_STATE)) {
-		/* Use wp_gpio here instead? */
-		val = readl(host->ioaddr + reg);
-		return val | SDHCI_WRITE_PROTECT;
-	}
-
-	return readl(host->ioaddr + reg);
-}
-
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -150,7 +137,6 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 
 static const struct sdhci_ops tegra_sdhci_ops = {
 	.get_ro     = tegra_sdhci_get_ro,
-	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
 	.set_clock  = sdhci_set_clock,
-- 
1.8.3.1


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

* [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
@ 2014-02-18 15:11   ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-18 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

sdhci-tegra provides a get_ro method, which overrides the checking
of the write protect bit in the PRESENT_STATE register in sdhci.c:

        if (host->flags & SDHCI_DEVICE_DEAD)
                is_readonly = 0;
        else if (host->ops->get_ro)
                is_readonly = host->ops->get_ro(host);
        else
                is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
                                & SDHCI_WRITE_PROTECT);

This means it's pointless detecting accesses to this register and
manually setting the SDHCI_WRITE_PROTECT as it has no effect.

This means that the whole of tegra_sdhci_readl() can be removed and
we can use the builtin sdhci readl functionality here.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
=-DO NOT APPLY-=
 drivers/mmc/host/sdhci-tegra.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index d06b6ff60432..985247649f46 100644
=-DO NOT APPLY-= a/drivers/mmc/host/sdhci-tegra.c
=+DO NOT APPLY+= b/drivers/mmc/host/sdhci-tegra.c
@@ -48,19 +48,6 @@ struct sdhci_tegra {
 	int power_gpio;
 };
 
-static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
-{
-	u32 val;
-
-	if (unlikely(reg == SDHCI_PRESENT_STATE)) {
-		/* Use wp_gpio here instead? */
-		val = readl(host->ioaddr + reg);
-		return val | SDHCI_WRITE_PROTECT;
-	}
-
-	return readl(host->ioaddr + reg);
-}
-
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -150,7 +137,6 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 
 static const struct sdhci_ops tegra_sdhci_ops = {
 	.get_ro     = tegra_sdhci_get_ro,
-	.read_l     = tegra_sdhci_readl,
 	.read_w     = tegra_sdhci_readw,
 	.write_l    = tegra_sdhci_writel,
 	.set_clock  = sdhci_set_clock,
-- 
1.8.3.1

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-18 15:09   ` Russell King
@ 2014-02-18 17:57     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-18 17:57 UTC (permalink / raw)
  To: linux-arm-kernel, linux-mmc, Viresh Kumar; +Cc: Chris Ball

On Tue, Feb 18, 2014 at 03:09:38PM +0000, Russell King wrote:
> There's no requirement to have the card tasklet separate now that we
> have a threaded interrupt handler, so kill this and move the called
> code into the threaded part of the handler.

This patch breaks sdhci-spear's build due to this:

/* gpio card detection interrupt handler */
static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
{
        struct platform_device *pdev = dev_id;
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
        unsigned long gpio_irq_type;
        int val;
        
        val = gpio_get_value(sdhci->data->card_int_gpio);
        
        /* val == 1 -> card removed, val == 0 -> card inserted */
        /* if card removed - set irq for low level, else vice versa */
        gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
        irq_set_irq_type(irq, gpio_irq_type);
 
        if (sdhci->data->card_power_gpio >= 0) {   
                if (!sdhci->data->power_always_enb) {
                        /* if card inserted, give power, otherwise remove it */
                        val = sdhci->data->power_active_high ? !val : val ;
                        gpio_set_value(sdhci->data->card_power_gpio, val);
                }
        }
  
        /* inform sdhci driver about card insertion/removal */
        tasklet_schedule(&host->card_tasklet);
                
        return IRQ_HANDLED;  
}

which is really nice code.  WTF is this doing?

1) You're controlling the card power GPIO via the insertion/removal
   interrupt handler?  What's wrong with using a vmmc regulator for
   that, which will be controlled via the MMC subsystem as required?

2) card detection GPIO is handled natively by sdhci.c, there's really
   no need for sdhci users to implement this themselves.

Viresh, can this custom code be killed?

Lastly, you do realise that using sdhci-spear with DT results in it
always claiming GPIO 0 for power control, since you use devm_kzalloc()
to allocate the private data and never set card_power_gpio to a
negative number.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-18 17:57     ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-18 17:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 18, 2014 at 03:09:38PM +0000, Russell King wrote:
> There's no requirement to have the card tasklet separate now that we
> have a threaded interrupt handler, so kill this and move the called
> code into the threaded part of the handler.

This patch breaks sdhci-spear's build due to this:

/* gpio card detection interrupt handler */
static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
{
        struct platform_device *pdev = dev_id;
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
        unsigned long gpio_irq_type;
        int val;
        
        val = gpio_get_value(sdhci->data->card_int_gpio);
        
        /* val == 1 -> card removed, val == 0 -> card inserted */
        /* if card removed - set irq for low level, else vice versa */
        gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
        irq_set_irq_type(irq, gpio_irq_type);
 
        if (sdhci->data->card_power_gpio >= 0) {   
                if (!sdhci->data->power_always_enb) {
                        /* if card inserted, give power, otherwise remove it */
                        val = sdhci->data->power_active_high ? !val : val ;
                        gpio_set_value(sdhci->data->card_power_gpio, val);
                }
        }
  
        /* inform sdhci driver about card insertion/removal */
        tasklet_schedule(&host->card_tasklet);
                
        return IRQ_HANDLED;  
}

which is really nice code.  WTF is this doing?

1) You're controlling the card power GPIO via the insertion/removal
   interrupt handler?  What's wrong with using a vmmc regulator for
   that, which will be controlled via the MMC subsystem as required?

2) card detection GPIO is handled natively by sdhci.c, there's really
   no need for sdhci users to implement this themselves.

Viresh, can this custom code be killed?

Lastly, you do realise that using sdhci-spear with DT results in it
always claiming GPIO 0 for power control, since you use devm_kzalloc()
to allocate the private data and never set card_power_gpio to a
negative number.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
  2014-02-18 15:09   ` Russell King
@ 2014-02-19  3:40     ` Nicolas Pitre
  -1 siblings, 0 replies; 121+ messages in thread
From: Nicolas Pitre @ 2014-02-19  3:40 UTC (permalink / raw)
  To: Russell King; +Cc: linux-arm-kernel, linux-mmc, Chris Ball

On Tue, 18 Feb 2014, Russell King wrote:

> Rather than the SDIO support spawning it's own thread for handling card
> interrupts, use the generic IRQ infrastructure for this, triggering it
> from the host interface's interrupt handling directly.
> 
> This avoids a race between the parent thread waiting to receive an
> interrupt response from the card, and the slow startup from the sdio
> irq thread, which can occur as a result of high system load (eg, while
> udev is running.)
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> =-DO NOT APPLY-=
>  drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
>  include/linux/mmc/host.h    |  3 +++
>  2 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> index aaa90460ed23..f23d73993dc6 100644
> =-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
> =+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
> @@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
>  	return ret;
>  }
>  
> =+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
> =+DO NOT APPLY+={
> =+DO NOT APPLY+=	mmc_claim_host(host);
> =+DO NOT APPLY+=	host->sdio_irq_pending = true;
> =+DO NOT APPLY+=	process_sdio_pending_irqs(host);
> =+DO NOT APPLY+=	mmc_release_host(host);
> =+DO NOT APPLY+=}
> =+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
> =+DO NOT APPLY+=

Could you please dispense with those obnoxious "DO NOT APPLY" strings 
all over the place?  That makes patch review very annoying.


Nicolas

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

* [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
@ 2014-02-19  3:40     ` Nicolas Pitre
  0 siblings, 0 replies; 121+ messages in thread
From: Nicolas Pitre @ 2014-02-19  3:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 18 Feb 2014, Russell King wrote:

> Rather than the SDIO support spawning it's own thread for handling card
> interrupts, use the generic IRQ infrastructure for this, triggering it
> from the host interface's interrupt handling directly.
> 
> This avoids a race between the parent thread waiting to receive an
> interrupt response from the card, and the slow startup from the sdio
> irq thread, which can occur as a result of high system load (eg, while
> udev is running.)
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> =-DO NOT APPLY-=
>  drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
>  include/linux/mmc/host.h    |  3 +++
>  2 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> index aaa90460ed23..f23d73993dc6 100644
> =-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
> =+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
> @@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
>  	return ret;
>  }
>  
> =+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
> =+DO NOT APPLY+={
> =+DO NOT APPLY+=	mmc_claim_host(host);
> =+DO NOT APPLY+=	host->sdio_irq_pending = true;
> =+DO NOT APPLY+=	process_sdio_pending_irqs(host);
> =+DO NOT APPLY+=	mmc_release_host(host);
> =+DO NOT APPLY+=}
> =+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
> =+DO NOT APPLY+=

Could you please dispense with those obnoxious "DO NOT APPLY" strings 
all over the place?  That makes patch review very annoying.


Nicolas

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-18 17:57     ` Russell King - ARM Linux
@ 2014-02-19  6:13       ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19  6:13 UTC (permalink / raw)
  To: Russell King - ARM Linux, Pratyush Anand, spear-devel, Mohit KUMAR
  Cc: linux-arm-kernel, linux-mmc, Viresh Kumar, Chris Ball

Adding ST people as well who have access to boards and are working on SPEAr.

On 18 February 2014 23:27, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 18, 2014 at 03:09:38PM +0000, Russell King wrote:
>> There's no requirement to have the card tasklet separate now that we
>> have a threaded interrupt handler, so kill this and move the called
>> code into the threaded part of the handler.
>
> This patch breaks sdhci-spear's build due to this:
>
> /* gpio card detection interrupt handler */
> static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
> {
>         struct platform_device *pdev = dev_id;
>         struct sdhci_host *host = platform_get_drvdata(pdev);
>         struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
>         unsigned long gpio_irq_type;
>         int val;
>
>         val = gpio_get_value(sdhci->data->card_int_gpio);
>
>         /* val == 1 -> card removed, val == 0 -> card inserted */
>         /* if card removed - set irq for low level, else vice versa */
>         gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
>         irq_set_irq_type(irq, gpio_irq_type);
>
>         if (sdhci->data->card_power_gpio >= 0) {
>                 if (!sdhci->data->power_always_enb) {
>                         /* if card inserted, give power, otherwise remove it */
>                         val = sdhci->data->power_active_high ? !val : val ;
>                         gpio_set_value(sdhci->data->card_power_gpio, val);
>                 }
>         }
>
>         /* inform sdhci driver about card insertion/removal */
>         tasklet_schedule(&host->card_tasklet);
>
>         return IRQ_HANDLED;
> }
>
> which is really nice code.  WTF is this doing?

:)

> 1) You're controlling the card power GPIO via the insertion/removal
>    interrupt handler?  What's wrong with using a vmmc regulator for
>    that, which will be controlled via the MMC subsystem as required?

Haven't explored that earlier.. Maybe its possible but no idea.
The requirements were like this:
- We may or maynot need a GPIO for controlling power
- If we need it, we may need to disable/enable power with card removal/
insertion Or we may need to keep it enabled for ever..

Don't know if this can be done with existing stuff..

> 2) card detection GPIO is handled natively by sdhci.c, there's really
>    no need for sdhci users to implement this themselves.

Probably it was done to take care of power stuff, so that we know
when card is inserted/removed..

> Viresh, can this custom code be killed?

Not sure. Somebody from inside ST has to work on this, use already
present common stuff from sdhci/regulator/etc..

> Lastly, you do realise that using sdhci-spear with DT results in it
> always claiming GPIO 0 for power control, since you use devm_kzalloc()
> to allocate the private data and never set card_power_gpio to a
> negative number.

Hmm.. No I didn't at that time. Its a bug then.. Actually while leaving ST
I pushed the DT patch upstream and it had power binding there but was
then asked to use regulators etc for it and so dropped it at last time. Never
had bandwidth and hardware after that to do it..

http://www.spinics.net/lists/linux-mmc/msg16685.html

@Pratyush/Mohit: Can you guys help Russell here?

--
viresh

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19  6:13       ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

Adding ST people as well who have access to boards and are working on SPEAr.

On 18 February 2014 23:27, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 18, 2014 at 03:09:38PM +0000, Russell King wrote:
>> There's no requirement to have the card tasklet separate now that we
>> have a threaded interrupt handler, so kill this and move the called
>> code into the threaded part of the handler.
>
> This patch breaks sdhci-spear's build due to this:
>
> /* gpio card detection interrupt handler */
> static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
> {
>         struct platform_device *pdev = dev_id;
>         struct sdhci_host *host = platform_get_drvdata(pdev);
>         struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
>         unsigned long gpio_irq_type;
>         int val;
>
>         val = gpio_get_value(sdhci->data->card_int_gpio);
>
>         /* val == 1 -> card removed, val == 0 -> card inserted */
>         /* if card removed - set irq for low level, else vice versa */
>         gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
>         irq_set_irq_type(irq, gpio_irq_type);
>
>         if (sdhci->data->card_power_gpio >= 0) {
>                 if (!sdhci->data->power_always_enb) {
>                         /* if card inserted, give power, otherwise remove it */
>                         val = sdhci->data->power_active_high ? !val : val ;
>                         gpio_set_value(sdhci->data->card_power_gpio, val);
>                 }
>         }
>
>         /* inform sdhci driver about card insertion/removal */
>         tasklet_schedule(&host->card_tasklet);
>
>         return IRQ_HANDLED;
> }
>
> which is really nice code.  WTF is this doing?

:)

> 1) You're controlling the card power GPIO via the insertion/removal
>    interrupt handler?  What's wrong with using a vmmc regulator for
>    that, which will be controlled via the MMC subsystem as required?

Haven't explored that earlier.. Maybe its possible but no idea.
The requirements were like this:
- We may or maynot need a GPIO for controlling power
- If we need it, we may need to disable/enable power with card removal/
insertion Or we may need to keep it enabled for ever..

Don't know if this can be done with existing stuff..

> 2) card detection GPIO is handled natively by sdhci.c, there's really
>    no need for sdhci users to implement this themselves.

Probably it was done to take care of power stuff, so that we know
when card is inserted/removed..

> Viresh, can this custom code be killed?

Not sure. Somebody from inside ST has to work on this, use already
present common stuff from sdhci/regulator/etc..

> Lastly, you do realise that using sdhci-spear with DT results in it
> always claiming GPIO 0 for power control, since you use devm_kzalloc()
> to allocate the private data and never set card_power_gpio to a
> negative number.

Hmm.. No I didn't at that time. Its a bug then.. Actually while leaving ST
I pushed the DT patch upstream and it had power binding there but was
then asked to use regulators etc for it and so dropped it at last time. Never
had bandwidth and hardware after that to do it..

http://www.spinics.net/lists/linux-mmc/msg16685.html

@Pratyush/Mohit: Can you guys help Russell here?

--
viresh

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19  6:13       ` Viresh Kumar
@ 2014-02-19  9:43         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:43 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Pratyush Anand, Viresh Kumar, Mohit KUMAR, spear-devel,
	linux-mmc, Chris Ball, linux-arm-kernel

On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
> Adding ST people as well who have access to boards and are working on SPEAr.
> 
> On 18 February 2014 23:27, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > 1) You're controlling the card power GPIO via the insertion/removal
> >    interrupt handler?  What's wrong with using a vmmc regulator for
> >    that, which will be controlled via the MMC subsystem as required?
> 
> Haven't explored that earlier.. Maybe its possible but no idea.
> The requirements were like this:
> - We may or maynot need a GPIO for controlling power
> - If we need it, we may need to disable/enable power with card removal/
> insertion Or we may need to keep it enabled for ever..

So how is this any different from any other system which controls power to
the MMC/SD socket?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19  9:43         ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
> Adding ST people as well who have access to boards and are working on SPEAr.
> 
> On 18 February 2014 23:27, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > 1) You're controlling the card power GPIO via the insertion/removal
> >    interrupt handler?  What's wrong with using a vmmc regulator for
> >    that, which will be controlled via the MMC subsystem as required?
> 
> Haven't explored that earlier.. Maybe its possible but no idea.
> The requirements were like this:
> - We may or maynot need a GPIO for controlling power
> - If we need it, we may need to disable/enable power with card removal/
> insertion Or we may need to keep it enabled for ever..

So how is this any different from any other system which controls power to
the MMC/SD socket?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
  2014-02-19  3:40     ` Nicolas Pitre
@ 2014-02-19  9:44       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:44 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: linux-arm-kernel, linux-mmc, Chris Ball

On Tue, Feb 18, 2014 at 10:40:33PM -0500, Nicolas Pitre wrote:
> On Tue, 18 Feb 2014, Russell King wrote:
> 
> > Rather than the SDIO support spawning it's own thread for handling card
> > interrupts, use the generic IRQ infrastructure for this, triggering it
> > from the host interface's interrupt handling directly.
> > 
> > This avoids a race between the parent thread waiting to receive an
> > interrupt response from the card, and the slow startup from the sdio
> > irq thread, which can occur as a result of high system load (eg, while
> > udev is running.)
> > 
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > =-DO NOT APPLY-=
> >  drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
> >  include/linux/mmc/host.h    |  3 +++
> >  2 files changed, 34 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> > index aaa90460ed23..f23d73993dc6 100644
> > =-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
> > =+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
> > @@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
> >  	return ret;
> >  }
> >  
> > =+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
> > =+DO NOT APPLY+={
> > =+DO NOT APPLY+=	mmc_claim_host(host);
> > =+DO NOT APPLY+=	host->sdio_irq_pending = true;
> > =+DO NOT APPLY+=	process_sdio_pending_irqs(host);
> > =+DO NOT APPLY+=	mmc_release_host(host);
> > =+DO NOT APPLY+=}
> > =+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
> > =+DO NOT APPLY+=
> 
> Could you please dispense with those obnoxious "DO NOT APPLY" strings 
> all over the place?  That makes patch review very annoying.

Calm down.  That was a bug in the script, which has since been fixed.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling
@ 2014-02-19  9:44       ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 18, 2014 at 10:40:33PM -0500, Nicolas Pitre wrote:
> On Tue, 18 Feb 2014, Russell King wrote:
> 
> > Rather than the SDIO support spawning it's own thread for handling card
> > interrupts, use the generic IRQ infrastructure for this, triggering it
> > from the host interface's interrupt handling directly.
> > 
> > This avoids a race between the parent thread waiting to receive an
> > interrupt response from the card, and the slow startup from the sdio
> > irq thread, which can occur as a result of high system load (eg, while
> > udev is running.)
> > 
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > =-DO NOT APPLY-=
> >  drivers/mmc/core/sdio_irq.c | 41 +++++++++++++++++++++++++++++++----------
> >  include/linux/mmc/host.h    |  3 +++
> >  2 files changed, 34 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
> > index aaa90460ed23..f23d73993dc6 100644
> > =-DO NOT APPLY-= a/drivers/mmc/core/sdio_irq.c
> > =+DO NOT APPLY+= b/drivers/mmc/core/sdio_irq.c
> > @@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
> >  	return ret;
> >  }
> >  
> > =+DO NOT APPLY+=void sdio_run_irqs(struct mmc_host *host)
> > =+DO NOT APPLY+={
> > =+DO NOT APPLY+=	mmc_claim_host(host);
> > =+DO NOT APPLY+=	host->sdio_irq_pending = true;
> > =+DO NOT APPLY+=	process_sdio_pending_irqs(host);
> > =+DO NOT APPLY+=	mmc_release_host(host);
> > =+DO NOT APPLY+=}
> > =+DO NOT APPLY+=EXPORT_SYMBOL_GPL(sdio_run_irqs);
> > =+DO NOT APPLY+=
> 
> Could you please dispense with those obnoxious "DO NOT APPLY" strings 
> all over the place?  That makes patch review very annoying.

Calm down.  That was a bug in the script, which has since been fixed.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19  9:43         ` Russell King - ARM Linux
@ 2014-02-19  9:48           ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19  9:48 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Viresh Kumar, Chris Ball

On 19 February 2014 15:13, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
>> Adding ST people as well who have access to boards and are working on SPEAr.
>>
>> On 18 February 2014 23:27, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > 1) You're controlling the card power GPIO via the insertion/removal
>> >    interrupt handler?  What's wrong with using a vmmc regulator for
>> >    that, which will be controlled via the MMC subsystem as required?
>>
>> Haven't explored that earlier.. Maybe its possible but no idea.
>> The requirements were like this:
>> - We may or maynot need a GPIO for controlling power
>> - If we need it, we may need to disable/enable power with card removal/
>> insertion Or we may need to keep it enabled for ever..
>
> So how is this any different from any other system which controls power to
> the MMC/SD socket?

I am not claiming it to be different. I am just saying these were the
requirements
and I am not sure if they were satisfied with vmmc regulator. It might
be exactly
same in all other platforms.

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19  9:48           ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 February 2014 15:13, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
>> Adding ST people as well who have access to boards and are working on SPEAr.
>>
>> On 18 February 2014 23:27, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > 1) You're controlling the card power GPIO via the insertion/removal
>> >    interrupt handler?  What's wrong with using a vmmc regulator for
>> >    that, which will be controlled via the MMC subsystem as required?
>>
>> Haven't explored that earlier.. Maybe its possible but no idea.
>> The requirements were like this:
>> - We may or maynot need a GPIO for controlling power
>> - If we need it, we may need to disable/enable power with card removal/
>> insertion Or we may need to keep it enabled for ever..
>
> So how is this any different from any other system which controls power to
> the MMC/SD socket?

I am not claiming it to be different. I am just saying these were the
requirements
and I am not sure if they were satisfied with vmmc regulator. It might
be exactly
same in all other platforms.

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19  9:48           ` Viresh Kumar
@ 2014-02-19  9:52             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:52 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Viresh Kumar, Chris Ball

On Wed, Feb 19, 2014 at 03:18:08PM +0530, Viresh Kumar wrote:
> On 19 February 2014 15:13, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
> >> Adding ST people as well who have access to boards and are working on SPEAr.
> >>
> >> On 18 February 2014 23:27, Russell King - ARM Linux
> >> <linux@arm.linux.org.uk> wrote:
> >> > 1) You're controlling the card power GPIO via the insertion/removal
> >> >    interrupt handler?  What's wrong with using a vmmc regulator for
> >> >    that, which will be controlled via the MMC subsystem as required?
> >>
> >> Haven't explored that earlier.. Maybe its possible but no idea.
> >> The requirements were like this:
> >> - We may or maynot need a GPIO for controlling power
> >> - If we need it, we may need to disable/enable power with card removal/
> >> insertion Or we may need to keep it enabled for ever..
> >
> > So how is this any different from any other system which controls power to
> > the MMC/SD socket?
> 
> I am not claiming it to be different. I am just saying these were the
> requirements
> and I am not sure if they were satisfied with vmmc regulator. It might
> be exactly
> same in all other platforms.

Are you aware that power control to the card is part of the MMC/SD/SDIO
spec - and part of the protocol talking to the card?  Hence why the
mmc layer has support for its control built-in.

If you don't want to use a regulator, then the right way to do this is to
use the set_ios callback and check the power field - anything which is not
MMC_POWER_OFF should result in power to the card being turned on.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19  9:52             ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19  9:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 03:18:08PM +0530, Viresh Kumar wrote:
> On 19 February 2014 15:13, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Wed, Feb 19, 2014 at 11:43:19AM +0530, Viresh Kumar wrote:
> >> Adding ST people as well who have access to boards and are working on SPEAr.
> >>
> >> On 18 February 2014 23:27, Russell King - ARM Linux
> >> <linux@arm.linux.org.uk> wrote:
> >> > 1) You're controlling the card power GPIO via the insertion/removal
> >> >    interrupt handler?  What's wrong with using a vmmc regulator for
> >> >    that, which will be controlled via the MMC subsystem as required?
> >>
> >> Haven't explored that earlier.. Maybe its possible but no idea.
> >> The requirements were like this:
> >> - We may or maynot need a GPIO for controlling power
> >> - If we need it, we may need to disable/enable power with card removal/
> >> insertion Or we may need to keep it enabled for ever..
> >
> > So how is this any different from any other system which controls power to
> > the MMC/SD socket?
> 
> I am not claiming it to be different. I am just saying these were the
> requirements
> and I am not sure if they were satisfied with vmmc regulator. It might
> be exactly
> same in all other platforms.

Are you aware that power control to the card is part of the MMC/SD/SDIO
spec - and part of the protocol talking to the card?  Hence why the
mmc layer has support for its control built-in.

If you don't want to use a regulator, then the right way to do this is to
use the set_ios callback and check the power field - anything which is not
MMC_POWER_OFF should result in power to the card being turned on.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19  9:52             ` Russell King - ARM Linux
@ 2014-02-19 10:09               ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19 10:09 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Viresh Kumar, Chris Ball

On 19 February 2014 15:22, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Are you aware that power control to the card is part of the MMC/SD/SDIO
> spec - and part of the protocol talking to the card?  Hence why the
> mmc layer has support for its control built-in.

Yeah, almost everything is part of the protocol and hence handled by core
sdhci.c layer.. We were handling some board specific issues here, that's it.

> If you don't want to use a regulator, then the right way to do this is to
> use the set_ios callback and check the power field - anything which is not
> MMC_POWER_OFF should result in power to the card being turned on.

I didn't get that completely here.. sorry completely out of touch on
this driver.
The power GPIO here is controlling the power to card socket. Once the card
is inserted, we need to enable power to the socket so that controller can
read back information from card.

And this set_ios callback is not available to drivers above sdhci.c, i.e. glues
like sdhci-pltfm or spear.. so, how we can we get that back in sdhci-spear.c?

Again, I can't test any modifications to this code and we need help from
Pratyush/Mohit on this..

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19 10:09               ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 19 February 2014 15:22, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Are you aware that power control to the card is part of the MMC/SD/SDIO
> spec - and part of the protocol talking to the card?  Hence why the
> mmc layer has support for its control built-in.

Yeah, almost everything is part of the protocol and hence handled by core
sdhci.c layer.. We were handling some board specific issues here, that's it.

> If you don't want to use a regulator, then the right way to do this is to
> use the set_ios callback and check the power field - anything which is not
> MMC_POWER_OFF should result in power to the card being turned on.

I didn't get that completely here.. sorry completely out of touch on
this driver.
The power GPIO here is controlling the power to card socket. Once the card
is inserted, we need to enable power to the socket so that controller can
read back information from card.

And this set_ios callback is not available to drivers above sdhci.c, i.e. glues
like sdhci-pltfm or spear.. so, how we can we get that back in sdhci-spear.c?

Again, I can't test any modifications to this code and we need help from
Pratyush/Mohit on this..

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19 10:09               ` Viresh Kumar
@ 2014-02-19 10:50                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 10:50 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Chris Ball

On Wed, Feb 19, 2014 at 03:39:35PM +0530, Viresh Kumar wrote:
> On 19 February 2014 15:22, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > If you don't want to use a regulator, then the right way to do this is to
> > use the set_ios callback and check the power field - anything which is not
> > MMC_POWER_OFF should result in power to the card being turned on.
> 
> I didn't get that completely here.. sorry completely out of touch on
> this driver.
> The power GPIO here is controlling the power to card socket. Once the card
> is inserted, we need to enable power to the socket so that controller can
> read back information from card.

Yes, and how is this different from any other implementation where power
to the socket is controlled?

This is what happens:
- You detect a card insertion/removal event
- You tell the mmc core about it via mmc_detect_change()
- The mmc core looks at the current state, and if the socket is powered down,
  it first goes through the power up sequence:
  - Apply power to the socket
    (a call to set_ios with MMC_POWER_UP and zero clock)
  - Apply clock to the socket
    (a call to set_ios with MMC_POWER_ON and non-zero clock)
  - Wait 74 clock cycles (as required by the spec)
- Start the detection by sending commands to the cards
- If no cards are detected, power down the socket

> And this set_ios callback is not available to drivers above sdhci.c, i.e.
> glues like sdhci-pltfm or spear.. so, how we can we get that back in
> sdhci-spear.c?

This is the crux of the issue which this patch set tries to address.  sdhci
has become - as I've now described it several times - "a patchwork quilt of
hacks all cooperating to give the impression of a working driver".

This is just another such hack, because rather than fixing sdhci.c properly,
you've hacked around it, thereby making sdhci.c worse.

What you could have done is turned the power control code in sdhci.c into
a library function, and sdhci_do_set_ios() calls a method in the sdhci_ops
to control the power.  What this means is that:

- if you use the standard sdhci power control support, then you can just
  hook the standard function in there.
- if you need to do something extra, you can place your function there
  to do your own stuff, and call the standard function to do the standard
  bits.
- if you don't need the standard functionality, then you can handle the
  power control entirely within your driver.

Not only does this result in a much cleaner implementation, it means that
going forward, any other such quirky stuff can be handled in the same way
by the "glues" rather than having to augment the horrid quirk/quirk2 stuff,
or coming up with hacks like sdhci-spear.c

If you have a look through this patch set, I've already done that with a
number of these methods - set_clock, set_uhs_signaling and reset.

Moreover, you don't end up fiddling with sdhci internals (such as the
card_tasklet) which then impact on attempts to clean that code up, which
is exactly why we're discussing this. :)

> Again, I can't test any modifications to this code and we need help from
> Pratyush/Mohit on this..

The important thing is we understand why the code is the way it is today,
and work out some way of cleaning this up.  Do you think the above will
work?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19 10:50                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 10:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 03:39:35PM +0530, Viresh Kumar wrote:
> On 19 February 2014 15:22, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > If you don't want to use a regulator, then the right way to do this is to
> > use the set_ios callback and check the power field - anything which is not
> > MMC_POWER_OFF should result in power to the card being turned on.
> 
> I didn't get that completely here.. sorry completely out of touch on
> this driver.
> The power GPIO here is controlling the power to card socket. Once the card
> is inserted, we need to enable power to the socket so that controller can
> read back information from card.

Yes, and how is this different from any other implementation where power
to the socket is controlled?

This is what happens:
- You detect a card insertion/removal event
- You tell the mmc core about it via mmc_detect_change()
- The mmc core looks at the current state, and if the socket is powered down,
  it first goes through the power up sequence:
  - Apply power to the socket
    (a call to set_ios with MMC_POWER_UP and zero clock)
  - Apply clock to the socket
    (a call to set_ios with MMC_POWER_ON and non-zero clock)
  - Wait 74 clock cycles (as required by the spec)
- Start the detection by sending commands to the cards
- If no cards are detected, power down the socket

> And this set_ios callback is not available to drivers above sdhci.c, i.e.
> glues like sdhci-pltfm or spear.. so, how we can we get that back in
> sdhci-spear.c?

This is the crux of the issue which this patch set tries to address.  sdhci
has become - as I've now described it several times - "a patchwork quilt of
hacks all cooperating to give the impression of a working driver".

This is just another such hack, because rather than fixing sdhci.c properly,
you've hacked around it, thereby making sdhci.c worse.

What you could have done is turned the power control code in sdhci.c into
a library function, and sdhci_do_set_ios() calls a method in the sdhci_ops
to control the power.  What this means is that:

- if you use the standard sdhci power control support, then you can just
  hook the standard function in there.
- if you need to do something extra, you can place your function there
  to do your own stuff, and call the standard function to do the standard
  bits.
- if you don't need the standard functionality, then you can handle the
  power control entirely within your driver.

Not only does this result in a much cleaner implementation, it means that
going forward, any other such quirky stuff can be handled in the same way
by the "glues" rather than having to augment the horrid quirk/quirk2 stuff,
or coming up with hacks like sdhci-spear.c

If you have a look through this patch set, I've already done that with a
number of these methods - set_clock, set_uhs_signaling and reset.

Moreover, you don't end up fiddling with sdhci internals (such as the
card_tasklet) which then impact on attempts to clean that code up, which
is exactly why we're discussing this. :)

> Again, I can't test any modifications to this code and we need help from
> Pratyush/Mohit on this..

The important thing is we understand why the code is the way it is today,
and work out some way of cleaning this up.  Do you think the above will
work?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19 10:50                 ` Russell King - ARM Linux
@ 2014-02-19 10:55                   ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19 10:55 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Chris Ball

Thanks for removing my ST email id from this mail, I was about to do that
this time :)

On 19 February 2014 16:20, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 19, 2014 at 03:39:35PM +0530, Viresh Kumar wrote:

>> I didn't get that completely here.. sorry completely out of touch on
>> this driver.
>> The power GPIO here is controlling the power to card socket. Once the card
>> is inserted, we need to enable power to the socket so that controller can
>> read back information from card.
>
> Yes, and how is this different from any other implementation where power
> to the socket is controlled?
>
> This is what happens:
> - You detect a card insertion/removal event
> - You tell the mmc core about it via mmc_detect_change()
> - The mmc core looks at the current state, and if the socket is powered down,
>   it first goes through the power up sequence:
>   - Apply power to the socket
>     (a call to set_ios with MMC_POWER_UP and zero clock)
>   - Apply clock to the socket
>     (a call to set_ios with MMC_POWER_ON and non-zero clock)
>   - Wait 74 clock cycles (as required by the spec)
> - Start the detection by sending commands to the cards
> - If no cards are detected, power down the socket

Okay, that's all we need then..

>> And this set_ios callback is not available to drivers above sdhci.c, i.e.
>> glues like sdhci-pltfm or spear.. so, how we can we get that back in
>> sdhci-spear.c?
>
> This is the crux of the issue which this patch set tries to address.  sdhci
> has become - as I've now described it several times - "a patchwork quilt of
> hacks all cooperating to give the impression of a working driver".

Being honest, I haven't had a in depth look of your patchset. Was really busy
with some other stuff..

> This is just another such hack, because rather than fixing sdhci.c properly,
> you've hacked around it, thereby making sdhci.c worse.
>
> What you could have done is turned the power control code in sdhci.c into
> a library function, and sdhci_do_set_ios() calls a method in the sdhci_ops
> to control the power.  What this means is that:
>
> - if you use the standard sdhci power control support, then you can just
>   hook the standard function in there.
> - if you need to do something extra, you can place your function there
>   to do your own stuff, and call the standard function to do the standard
>   bits.
> - if you don't need the standard functionality, then you can handle the
>   power control entirely within your driver.
>
> Not only does this result in a much cleaner implementation, it means that
> going forward, any other such quirky stuff can be handled in the same way
> by the "glues" rather than having to augment the horrid quirk/quirk2 stuff,
> or coming up with hacks like sdhci-spear.c
>
> If you have a look through this patch set, I've already done that with a
> number of these methods - set_clock, set_uhs_signaling and reset.
>
> Moreover, you don't end up fiddling with sdhci internals (such as the
> card_tasklet) which then impact on attempts to clean that code up, which
> is exactly why we're discussing this. :)

I agree to all above stuff..

>> Again, I can't test any modifications to this code and we need help from
>> Pratyush/Mohit on this..
>
> The important thing is we understand why the code is the way it is today,
> and work out some way of cleaning this up.  Do you think the above will
> work?

Absolutely, it will work.

Thanks for your efforts in cleaning up this stuff..

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-19 10:55                   ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-19 10:55 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for removing my ST email id from this mail, I was about to do that
this time :)

On 19 February 2014 16:20, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 19, 2014 at 03:39:35PM +0530, Viresh Kumar wrote:

>> I didn't get that completely here.. sorry completely out of touch on
>> this driver.
>> The power GPIO here is controlling the power to card socket. Once the card
>> is inserted, we need to enable power to the socket so that controller can
>> read back information from card.
>
> Yes, and how is this different from any other implementation where power
> to the socket is controlled?
>
> This is what happens:
> - You detect a card insertion/removal event
> - You tell the mmc core about it via mmc_detect_change()
> - The mmc core looks at the current state, and if the socket is powered down,
>   it first goes through the power up sequence:
>   - Apply power to the socket
>     (a call to set_ios with MMC_POWER_UP and zero clock)
>   - Apply clock to the socket
>     (a call to set_ios with MMC_POWER_ON and non-zero clock)
>   - Wait 74 clock cycles (as required by the spec)
> - Start the detection by sending commands to the cards
> - If no cards are detected, power down the socket

Okay, that's all we need then..

>> And this set_ios callback is not available to drivers above sdhci.c, i.e.
>> glues like sdhci-pltfm or spear.. so, how we can we get that back in
>> sdhci-spear.c?
>
> This is the crux of the issue which this patch set tries to address.  sdhci
> has become - as I've now described it several times - "a patchwork quilt of
> hacks all cooperating to give the impression of a working driver".

Being honest, I haven't had a in depth look of your patchset. Was really busy
with some other stuff..

> This is just another such hack, because rather than fixing sdhci.c properly,
> you've hacked around it, thereby making sdhci.c worse.
>
> What you could have done is turned the power control code in sdhci.c into
> a library function, and sdhci_do_set_ios() calls a method in the sdhci_ops
> to control the power.  What this means is that:
>
> - if you use the standard sdhci power control support, then you can just
>   hook the standard function in there.
> - if you need to do something extra, you can place your function there
>   to do your own stuff, and call the standard function to do the standard
>   bits.
> - if you don't need the standard functionality, then you can handle the
>   power control entirely within your driver.
>
> Not only does this result in a much cleaner implementation, it means that
> going forward, any other such quirky stuff can be handled in the same way
> by the "glues" rather than having to augment the horrid quirk/quirk2 stuff,
> or coming up with hacks like sdhci-spear.c
>
> If you have a look through this patch set, I've already done that with a
> number of these methods - set_clock, set_uhs_signaling and reset.
>
> Moreover, you don't end up fiddling with sdhci internals (such as the
> card_tasklet) which then impact on attempts to clean that code up, which
> is exactly why we're discussing this. :)

I agree to all above stuff..

>> Again, I can't test any modifications to this code and we need help from
>> Pratyush/Mohit on this..
>
> The important thing is we understand why the code is the way it is today,
> and work out some way of cleaning this up.  Do you think the above will
> work?

Absolutely, it will work.

Thanks for your efforts in cleaning up this stuff..

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

* Re: [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
  2014-02-18 15:11   ` Russell King
@ 2014-02-19 20:04     ` Stephen Warren
  -1 siblings, 0 replies; 121+ messages in thread
From: Stephen Warren @ 2014-02-19 20:04 UTC (permalink / raw)
  To: Russell King, linux-arm-kernel, linux-mmc
  Cc: Chris Ball, Thierry Reding, linux-tegra

On 02/18/2014 08:11 AM, Russell King wrote:
> sdhci-tegra provides a get_ro method, which overrides the checking
> of the write protect bit in the PRESENT_STATE register in sdhci.c:
> 
>         if (host->flags & SDHCI_DEVICE_DEAD)
>                 is_readonly = 0;
>         else if (host->ops->get_ro)
>                 is_readonly = host->ops->get_ro(host);
>         else
>                 is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
>                                 & SDHCI_WRITE_PROTECT);
> 
> This means it's pointless detecting accesses to this register and
> manually setting the SDHCI_WRITE_PROTECT as it has no effect.
> 
> This means that the whole of tegra_sdhci_readl() can be removed and
> we can use the builtin sdhci readl functionality here.

Acked-by: Stephen Warren <swarren@nvidia.com>

> =-DO NOT APPLY-=

Is that just because it's an RFC and you want to make sure it doesn't
get accepted early, or are you explicitly trying to stop people applying
this, testing it, and giving Tested-by?

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

* [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
@ 2014-02-19 20:04     ` Stephen Warren
  0 siblings, 0 replies; 121+ messages in thread
From: Stephen Warren @ 2014-02-19 20:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/18/2014 08:11 AM, Russell King wrote:
> sdhci-tegra provides a get_ro method, which overrides the checking
> of the write protect bit in the PRESENT_STATE register in sdhci.c:
> 
>         if (host->flags & SDHCI_DEVICE_DEAD)
>                 is_readonly = 0;
>         else if (host->ops->get_ro)
>                 is_readonly = host->ops->get_ro(host);
>         else
>                 is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
>                                 & SDHCI_WRITE_PROTECT);
> 
> This means it's pointless detecting accesses to this register and
> manually setting the SDHCI_WRITE_PROTECT as it has no effect.
> 
> This means that the whole of tegra_sdhci_readl() can be removed and
> we can use the builtin sdhci readl functionality here.

Acked-by: Stephen Warren <swarren@nvidia.com>

> =-DO NOT APPLY-=

Is that just because it's an RFC and you want to make sure it doesn't
get accepted early, or are you explicitly trying to stop people applying
this, testing it, and giving Tested-by?

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

* Re: [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
  2014-02-19 20:04     ` Stephen Warren
@ 2014-02-19 23:22       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 23:22 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-arm-kernel, linux-mmc, Chris Ball, Thierry Reding, linux-tegra

On Wed, Feb 19, 2014 at 01:04:19PM -0700, Stephen Warren wrote:
> On 02/18/2014 08:11 AM, Russell King wrote:
> > sdhci-tegra provides a get_ro method, which overrides the checking
> > of the write protect bit in the PRESENT_STATE register in sdhci.c:
> > 
> >         if (host->flags & SDHCI_DEVICE_DEAD)
> >                 is_readonly = 0;
> >         else if (host->ops->get_ro)
> >                 is_readonly = host->ops->get_ro(host);
> >         else
> >                 is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
> >                                 & SDHCI_WRITE_PROTECT);
> > 
> > This means it's pointless detecting accesses to this register and
> > manually setting the SDHCI_WRITE_PROTECT as it has no effect.
> > 
> > This means that the whole of tegra_sdhci_readl() can be removed and
> > we can use the builtin sdhci readl functionality here.
> 
> Acked-by: Stephen Warren <swarren@nvidia.com>

Thanks.

> > =-DO NOT APPLY-=
> 
> Is that just because it's an RFC and you want to make sure it doesn't
> get accepted early, or are you explicitly trying to stop people applying
> this, testing it, and giving Tested-by?

The script was a little too over-zealous.  It was just supposed to do
the following transformation:

--- => =-DO NOT APPLY-=
+++ => =+DO NOT APPLY+=

which would've made it reversible with a trivial sed expression - but I
cocked up because of the utterly random nature of regexp flavours, and
instead gave sed this:

	sed -i 's/^---/=-DO NOT APPLY-=/;s/^\+\+\+/=+DO NOT APPLY+=/'

The escaped '+' ends up causing sed to match a single + at the beginning
of a line.  (Other regexp flavours require you to escape the '+' otherwise
it's interpreted as "one or more".)

I had added that mode to my script a few months ago, and I just assumed
I'd fully tested it when I used it yesterday... clearly not so.

So... yes it was designed to stop it being _accepted_ but it should have
also been completely reversible for those who wished to apply it via
the obvious reversed sed expression.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
@ 2014-02-19 23:22       ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 23:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 01:04:19PM -0700, Stephen Warren wrote:
> On 02/18/2014 08:11 AM, Russell King wrote:
> > sdhci-tegra provides a get_ro method, which overrides the checking
> > of the write protect bit in the PRESENT_STATE register in sdhci.c:
> > 
> >         if (host->flags & SDHCI_DEVICE_DEAD)
> >                 is_readonly = 0;
> >         else if (host->ops->get_ro)
> >                 is_readonly = host->ops->get_ro(host);
> >         else
> >                 is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
> >                                 & SDHCI_WRITE_PROTECT);
> > 
> > This means it's pointless detecting accesses to this register and
> > manually setting the SDHCI_WRITE_PROTECT as it has no effect.
> > 
> > This means that the whole of tegra_sdhci_readl() can be removed and
> > we can use the builtin sdhci readl functionality here.
> 
> Acked-by: Stephen Warren <swarren@nvidia.com>

Thanks.

> > =-DO NOT APPLY-=
> 
> Is that just because it's an RFC and you want to make sure it doesn't
> get accepted early, or are you explicitly trying to stop people applying
> this, testing it, and giving Tested-by?

The script was a little too over-zealous.  It was just supposed to do
the following transformation:

--- => =-DO NOT APPLY-=
+++ => =+DO NOT APPLY+=

which would've made it reversible with a trivial sed expression - but I
cocked up because of the utterly random nature of regexp flavours, and
instead gave sed this:

	sed -i 's/^---/=-DO NOT APPLY-=/;s/^\+\+\+/=+DO NOT APPLY+=/'

The escaped '+' ends up causing sed to match a single + at the beginning
of a line.  (Other regexp flavours require you to escape the '+' otherwise
it's interpreted as "one or more".)

I had added that mode to my script a few months ago, and I just assumed
I'd fully tested it when I used it yesterday... clearly not so.

So... yes it was designed to stop it being _accepted_ but it should have
also been completely reversible for those who wished to apply it via
the obvious reversed sed expression.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
  2014-02-19 23:22       ` Russell King - ARM Linux
@ 2014-02-19 23:28           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 23:28 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Thierry Reding,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Feb 19, 2014 at 11:22:53PM +0000, Russell King - ARM Linux wrote:
> The script was a little too over-zealous.  It was just supposed to do
> the following transformation:
> 
> --- => =-DO NOT APPLY-=
> +++ => =+DO NOT APPLY+=
> 
> which would've made it reversible with a trivial sed expression - but I
> cocked up because of the utterly random nature of regexp flavours, and
> instead gave sed this:
> 
> 	sed -i 's/^---/=-DO NOT APPLY-=/;s/^\+\+\+/=+DO NOT APPLY+=/'
> 
> The escaped '+' ends up causing sed to match a single + at the beginning
> of a line.  (Other regexp flavours require you to escape the '+' otherwise
> it's interpreted as "one or more".)
> 
> I had added that mode to my script a few months ago, and I just assumed
> I'd fully tested it when I used it yesterday... clearly not so.
> 
> So... yes it was designed to stop it being _accepted_ but it should have
> also been completely reversible for those who wished to apply it via
> the obvious reversed sed expression.

Oh, and before you ask why I'm now doing it, it's through necessity.  I've
had too many instances where some maintainers will take patches sent out
as part of a RFC without being asked to do so - and I've then had to email
the maintainers asking them to drop such patches from their trees.

I wish this kind of buggeration of patches wasn't necessary, but
unfortunately - as seems to always be the case - people just can't be
trusted to pay due care and attention, and do the right thing.

That's why the intention is to (a) prevent the patch being applied without
thought while (b) allowing it to be applied with a trivial transformation.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling
@ 2014-02-19 23:28           ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-19 23:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 11:22:53PM +0000, Russell King - ARM Linux wrote:
> The script was a little too over-zealous.  It was just supposed to do
> the following transformation:
> 
> --- => =-DO NOT APPLY-=
> +++ => =+DO NOT APPLY+=
> 
> which would've made it reversible with a trivial sed expression - but I
> cocked up because of the utterly random nature of regexp flavours, and
> instead gave sed this:
> 
> 	sed -i 's/^---/=-DO NOT APPLY-=/;s/^\+\+\+/=+DO NOT APPLY+=/'
> 
> The escaped '+' ends up causing sed to match a single + at the beginning
> of a line.  (Other regexp flavours require you to escape the '+' otherwise
> it's interpreted as "one or more".)
> 
> I had added that mode to my script a few months ago, and I just assumed
> I'd fully tested it when I used it yesterday... clearly not so.
> 
> So... yes it was designed to stop it being _accepted_ but it should have
> also been completely reversible for those who wished to apply it via
> the obvious reversed sed expression.

Oh, and before you ask why I'm now doing it, it's through necessity.  I've
had too many instances where some maintainers will take patches sent out
as part of a RFC without being asked to do so - and I've then had to email
the maintainers asking them to drop such patches from their trees.

I wish this kind of buggeration of patches wasn't necessary, but
unfortunately - as seems to always be the case - people just can't be
trusted to pay due care and attention, and do the right thing.

That's why the intention is to (a) prevent the patch being applied without
thought while (b) allowing it to be applied with a trivial transformation.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-19 10:55                   ` Viresh Kumar
@ 2014-02-20 10:59                     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-20 10:59 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Chris Ball

On Wed, Feb 19, 2014 at 04:25:12PM +0530, Viresh Kumar wrote:
> Absolutely, it will work.
> 
> Thanks for your efforts in cleaning up this stuff..

I'll send a few patches in a moment.  First through, I've just found this
gem:

static int sdhci_probe(struct platform_device *pdev)
{
...
        sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
...
        if (np) {
...
        } else {
                sdhci->data = dev_get_platdata(&pdev->dev);
        }

        pdev->dev.platform_data = sdhci;
...
	... some paths which can cause probe to return an error code ...
...
static int sdhci_remove(struct platform_device *pdev)
{
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
...
        clk_disable_unprepare(sdhci->clk);
        clk_put(sdhci->clk);

So, what happens if we hit an error such as -EPROBEDEFER after that
assignment to pdev->dev.platform_data, and then re-probe the driver
later?

This is just horribly broken.

What's wrong with using the facilities in sdhci to allow you to have
your own private data after the sdhci_host structure?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-20 10:59                     ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-20 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 19, 2014 at 04:25:12PM +0530, Viresh Kumar wrote:
> Absolutely, it will work.
> 
> Thanks for your efforts in cleaning up this stuff..

I'll send a few patches in a moment.  First through, I've just found this
gem:

static int sdhci_probe(struct platform_device *pdev)
{
...
        sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
...
        if (np) {
...
        } else {
                sdhci->data = dev_get_platdata(&pdev->dev);
        }

        pdev->dev.platform_data = sdhci;
...
	... some paths which can cause probe to return an error code ...
...
static int sdhci_remove(struct platform_device *pdev)
{
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
...
        clk_disable_unprepare(sdhci->clk);
        clk_put(sdhci->clk);

So, what happens if we hit an error such as -EPROBEDEFER after that
assignment to pdev->dev.platform_data, and then re-probe the driver
later?

This is just horribly broken.

What's wrong with using the facilities in sdhci to allow you to have
your own private data after the sdhci_host structure?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-20 10:59                     ` Russell King - ARM Linux
@ 2014-02-20 11:18                       ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-20 11:18 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Chris Ball

On 20 February 2014 16:29, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> I'll send a few patches in a moment.  First through, I've just found this
> gem:

Yeah, 'gem' is the real word for this precious code :)

> static int sdhci_probe(struct platform_device *pdev)
> {
> ...
>         sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
> ...
>         if (np) {
> ...
>         } else {
>                 sdhci->data = dev_get_platdata(&pdev->dev);
>         }
>
>         pdev->dev.platform_data = sdhci;
> ...
>         ... some paths which can cause probe to return an error code ...
> ...
> static int sdhci_remove(struct platform_device *pdev)
> {
>         struct sdhci_host *host = platform_get_drvdata(pdev);
>         struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
> ...
>         clk_disable_unprepare(sdhci->clk);
>         clk_put(sdhci->clk);
>
> So, what happens if we hit an error such as -EPROBEDEFER after that
> assignment to pdev->dev.platform_data, and then re-probe the driver
> later?

BANG BANG!! :)

> This is just horribly broken.
>
> What's wrong with using the facilities in sdhci to allow you to have
> your own private data after the sdhci_host structure?

Nothing wrong in that, only right.. Do you want me to float a patch for
this or you can get that done along with your series?

Thanks again..

--
viresh

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-20 11:18                       ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-20 11:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 20 February 2014 16:29, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> I'll send a few patches in a moment.  First through, I've just found this
> gem:

Yeah, 'gem' is the real word for this precious code :)

> static int sdhci_probe(struct platform_device *pdev)
> {
> ...
>         sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
> ...
>         if (np) {
> ...
>         } else {
>                 sdhci->data = dev_get_platdata(&pdev->dev);
>         }
>
>         pdev->dev.platform_data = sdhci;
> ...
>         ... some paths which can cause probe to return an error code ...
> ...
> static int sdhci_remove(struct platform_device *pdev)
> {
>         struct sdhci_host *host = platform_get_drvdata(pdev);
>         struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
> ...
>         clk_disable_unprepare(sdhci->clk);
>         clk_put(sdhci->clk);
>
> So, what happens if we hit an error such as -EPROBEDEFER after that
> assignment to pdev->dev.platform_data, and then re-probe the driver
> later?

BANG BANG!! :)

> This is just horribly broken.
>
> What's wrong with using the facilities in sdhci to allow you to have
> your own private data after the sdhci_host structure?

Nothing wrong in that, only right.. Do you want me to float a patch for
this or you can get that done along with your series?

Thanks again..

--
viresh

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-20 11:18                       ` Viresh Kumar
@ 2014-02-21 10:37                         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-21 10:37 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Pratyush Anand, spear-devel, Mohit KUMAR, linux-arm-kernel,
	linux-mmc, Chris Ball

On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
> Nothing wrong in that, only right.. Do you want me to float a patch for
> this or you can get that done along with your series?

I'll send a follow-up mini-series of five patches for it.  It shouldn't
depend all that much on the bigger series - and I think the first two
patches could well do with going into -rc.

 drivers/mmc/host/sdhci-spear.c  | 190 +++++++++-------------------------------
 include/linux/mmc/sdhci-spear.h |   8 --
 2 files changed, 43 insertions(+), 155 deletions(-)

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-21 10:37                         ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-21 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
> Nothing wrong in that, only right.. Do you want me to float a patch for
> this or you can get that done along with your series?

I'll send a follow-up mini-series of five patches for it.  It shouldn't
depend all that much on the bigger series - and I think the first two
patches could well do with going into -rc.

 drivers/mmc/host/sdhci-spear.c  | 190 +++++++++-------------------------------
 include/linux/mmc/sdhci-spear.h |   8 --
 2 files changed, 43 insertions(+), 155 deletions(-)

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH 1/5] mmc: sdhci-spear: fix error handling paths for DT
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-21 10:41                           ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: Viresh Kumar, Pratyush Anand, Mohit KUMAR
  Cc: linux-arm-kernel, Viresh Kumar, Chris Ball, spear-devel, linux-mmc

Fix the error handling paths for DT and simplify using the devm_* API
for clk_get().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 94ae64d23ef3..d4621eb59527 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -134,7 +134,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	}
 
 	/* clk enable */
-	sdhci->clk = clk_get(&pdev->dev, NULL);
+	sdhci->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(sdhci->clk)) {
 		ret = PTR_ERR(sdhci->clk);
 		dev_dbg(&pdev->dev, "Error getting clock\n");
@@ -144,7 +144,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
-		goto put_clk;
+		goto err;
 	}
 
 	ret = clk_set_rate(sdhci->clk, 50000000);
@@ -156,7 +156,7 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = sdhci_probe_config_dt(pdev);
 		if (IS_ERR(sdhci->data)) {
 			dev_err(&pdev->dev, "DT: Failed to get pdata\n");
-			return -ENODEV;
+			goto disable_clk;
 		}
 	} else {
 		sdhci->data = dev_get_platdata(&pdev->dev);
@@ -266,8 +266,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	sdhci_free_host(host);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
-put_clk:
-	clk_put(sdhci->clk);
 err:
 	dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
 	return ret;
@@ -287,7 +285,6 @@ static int sdhci_remove(struct platform_device *pdev)
 	sdhci_remove_host(host, dead);
 	sdhci_free_host(host);
 	clk_disable_unprepare(sdhci->clk);
-	clk_put(sdhci->clk);
 
 	return 0;
 }
-- 
1.8.3.1


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

* [PATCH 1/5] mmc: sdhci-spear: fix error handling paths for DT
@ 2014-02-21 10:41                           ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Fix the error handling paths for DT and simplify using the devm_* API
for clk_get().

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 94ae64d23ef3..d4621eb59527 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -134,7 +134,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	}
 
 	/* clk enable */
-	sdhci->clk = clk_get(&pdev->dev, NULL);
+	sdhci->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(sdhci->clk)) {
 		ret = PTR_ERR(sdhci->clk);
 		dev_dbg(&pdev->dev, "Error getting clock\n");
@@ -144,7 +144,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
-		goto put_clk;
+		goto err;
 	}
 
 	ret = clk_set_rate(sdhci->clk, 50000000);
@@ -156,7 +156,7 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = sdhci_probe_config_dt(pdev);
 		if (IS_ERR(sdhci->data)) {
 			dev_err(&pdev->dev, "DT: Failed to get pdata\n");
-			return -ENODEV;
+			goto disable_clk;
 		}
 	} else {
 		sdhci->data = dev_get_platdata(&pdev->dev);
@@ -266,8 +266,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	sdhci_free_host(host);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
-put_clk:
-	clk_put(sdhci->clk);
 err:
 	dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
 	return ret;
@@ -287,7 +285,6 @@ static int sdhci_remove(struct platform_device *pdev)
 	sdhci_remove_host(host, dead);
 	sdhci_free_host(host);
 	clk_disable_unprepare(sdhci->clk);
-	clk_put(sdhci->clk);
 
 	return 0;
 }
-- 
1.8.3.1

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

* [PATCH 2/5] mmc: sdhci-spear: fix platform_data usage
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-21 10:41                           ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: Viresh Kumar, Pratyush Anand, Mohit KUMAR
  Cc: linux-arm-kernel, Viresh Kumar, Chris Ball, spear-devel, linux-mmc

sdhci-spear is unsafe should a probe fail or defer, since it overwrites
the platform_data with its own driver-private data.  It's trivial to
fix as SDHCI allows for driver-private data to be appended to its own
structure - we just need to arrange the code to allow this.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 43 +++++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index d4621eb59527..ca1cb9776ea2 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -110,6 +110,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	struct sdhci_host *host;
 	struct resource *iomem;
 	struct spear_sdhci *sdhci;
+	struct device *dev;
 	int ret;
 
 	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -126,25 +127,28 @@ static int sdhci_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
-	if (!sdhci) {
-		ret = -ENOMEM;
+	dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
+	host = sdhci_alloc_host(dev, sizeof(*sdhci));
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
 		dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n");
 		goto err;
 	}
 
+	sdhci = sdhci_priv(host);
+
 	/* clk enable */
 	sdhci->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(sdhci->clk)) {
 		ret = PTR_ERR(sdhci->clk);
 		dev_dbg(&pdev->dev, "Error getting clock\n");
-		goto err;
+		goto err_host;
 	}
 
 	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
-		goto err;
+		goto err_host;
 	}
 
 	ret = clk_set_rate(sdhci->clk, 50000000);
@@ -162,19 +166,6 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
-	pdev->dev.platform_data = sdhci;
-
-	if (pdev->dev.parent)
-		host = sdhci_alloc_host(pdev->dev.parent, 0);
-	else
-		host = sdhci_alloc_host(&pdev->dev, 0);
-
-	if (IS_ERR(host)) {
-		ret = PTR_ERR(host);
-		dev_dbg(&pdev->dev, "error allocating host\n");
-		goto disable_clk;
-	}
-
 	host->hw_name = "sdhci";
 	host->ops = &sdhci_pltfm_ops;
 	host->irq = platform_get_irq(pdev, 0);
@@ -185,13 +176,13 @@ static int sdhci_probe(struct platform_device *pdev)
 	if (!host->ioaddr) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "failed to remap registers\n");
-		goto free_host;
+		goto disable_clk;
 	}
 
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
-		goto free_host;
+		goto disable_clk;
 	}
 
 	platform_set_drvdata(pdev, host);
@@ -262,10 +253,10 @@ static int sdhci_probe(struct platform_device *pdev)
 
 set_drvdata:
 	sdhci_remove_host(host, 1);
-free_host:
-	sdhci_free_host(host);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
+err_host:
+	sdhci_free_host(host);
 err:
 	dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
 	return ret;
@@ -274,7 +265,7 @@ static int sdhci_probe(struct platform_device *pdev)
 static int sdhci_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int dead = 0;
 	u32 scratch;
 
@@ -283,8 +274,8 @@ static int sdhci_remove(struct platform_device *pdev)
 		dead = 1;
 
 	sdhci_remove_host(host, dead);
-	sdhci_free_host(host);
 	clk_disable_unprepare(sdhci->clk);
+	sdhci_free_host(host);
 
 	return 0;
 }
@@ -293,7 +284,7 @@ static int sdhci_remove(struct platform_device *pdev)
 static int sdhci_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
-	struct spear_sdhci *sdhci = dev_get_platdata(dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int ret;
 
 	ret = sdhci_suspend_host(host);
@@ -306,7 +297,7 @@ static int sdhci_suspend(struct device *dev)
 static int sdhci_resume(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
-	struct spear_sdhci *sdhci = dev_get_platdata(dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int ret;
 
 	ret = clk_enable(sdhci->clk);
-- 
1.8.3.1


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

* [PATCH 2/5] mmc: sdhci-spear: fix platform_data usage
@ 2014-02-21 10:41                           ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

sdhci-spear is unsafe should a probe fail or defer, since it overwrites
the platform_data with its own driver-private data.  It's trivial to
fix as SDHCI allows for driver-private data to be appended to its own
structure - we just need to arrange the code to allow this.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 43 +++++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index d4621eb59527..ca1cb9776ea2 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -110,6 +110,7 @@ static int sdhci_probe(struct platform_device *pdev)
 	struct sdhci_host *host;
 	struct resource *iomem;
 	struct spear_sdhci *sdhci;
+	struct device *dev;
 	int ret;
 
 	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -126,25 +127,28 @@ static int sdhci_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL);
-	if (!sdhci) {
-		ret = -ENOMEM;
+	dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
+	host = sdhci_alloc_host(dev, sizeof(*sdhci));
+	if (IS_ERR(host)) {
+		ret = PTR_ERR(host);
 		dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n");
 		goto err;
 	}
 
+	sdhci = sdhci_priv(host);
+
 	/* clk enable */
 	sdhci->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(sdhci->clk)) {
 		ret = PTR_ERR(sdhci->clk);
 		dev_dbg(&pdev->dev, "Error getting clock\n");
-		goto err;
+		goto err_host;
 	}
 
 	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
-		goto err;
+		goto err_host;
 	}
 
 	ret = clk_set_rate(sdhci->clk, 50000000);
@@ -162,19 +166,6 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
-	pdev->dev.platform_data = sdhci;
-
-	if (pdev->dev.parent)
-		host = sdhci_alloc_host(pdev->dev.parent, 0);
-	else
-		host = sdhci_alloc_host(&pdev->dev, 0);
-
-	if (IS_ERR(host)) {
-		ret = PTR_ERR(host);
-		dev_dbg(&pdev->dev, "error allocating host\n");
-		goto disable_clk;
-	}
-
 	host->hw_name = "sdhci";
 	host->ops = &sdhci_pltfm_ops;
 	host->irq = platform_get_irq(pdev, 0);
@@ -185,13 +176,13 @@ static int sdhci_probe(struct platform_device *pdev)
 	if (!host->ioaddr) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "failed to remap registers\n");
-		goto free_host;
+		goto disable_clk;
 	}
 
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
-		goto free_host;
+		goto disable_clk;
 	}
 
 	platform_set_drvdata(pdev, host);
@@ -262,10 +253,10 @@ static int sdhci_probe(struct platform_device *pdev)
 
 set_drvdata:
 	sdhci_remove_host(host, 1);
-free_host:
-	sdhci_free_host(host);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
+err_host:
+	sdhci_free_host(host);
 err:
 	dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
 	return ret;
@@ -274,7 +265,7 @@ static int sdhci_probe(struct platform_device *pdev)
 static int sdhci_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int dead = 0;
 	u32 scratch;
 
@@ -283,8 +274,8 @@ static int sdhci_remove(struct platform_device *pdev)
 		dead = 1;
 
 	sdhci_remove_host(host, dead);
-	sdhci_free_host(host);
 	clk_disable_unprepare(sdhci->clk);
+	sdhci_free_host(host);
 
 	return 0;
 }
@@ -293,7 +284,7 @@ static int sdhci_remove(struct platform_device *pdev)
 static int sdhci_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
-	struct spear_sdhci *sdhci = dev_get_platdata(dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int ret;
 
 	ret = sdhci_suspend_host(host);
@@ -306,7 +297,7 @@ static int sdhci_suspend(struct device *dev)
 static int sdhci_resume(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
-	struct spear_sdhci *sdhci = dev_get_platdata(dev);
+	struct spear_sdhci *sdhci = sdhci_priv(host);
 	int ret;
 
 	ret = clk_enable(sdhci->clk);
-- 
1.8.3.1

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

* [PATCH 3/5] mmc: sdhci-spear: simplify resource handling
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-21 10:41                           ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: Viresh Kumar, Pratyush Anand, Mohit KUMAR
  Cc: linux-arm-kernel, Viresh Kumar, Chris Ball, spear-devel, linux-mmc

Use devm_ioremap_resource() to simplify iomem resource handling in the
probe path.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 40 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index ca1cb9776ea2..f879b27e59b1 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -113,20 +113,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	struct device *dev;
 	int ret;
 
-	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iomem) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "memory resource not defined\n");
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev, iomem->start,
-				resource_size(iomem), "spear-sdhci")) {
-		ret = -EBUSY;
-		dev_dbg(&pdev->dev, "cannot request region\n");
-		goto err;
-	}
-
 	dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
 	host = sdhci_alloc_host(dev, sizeof(*sdhci));
 	if (IS_ERR(host)) {
@@ -135,6 +121,19 @@ static int sdhci_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
+	if (IS_ERR(host->ioaddr)) {
+		ret = PTR_ERR(host->ioaddr);
+		dev_dbg(&pdev->dev, "unable to map iomem: %d\n", ret);
+		goto err_host;
+	}
+
+	host->hw_name = "sdhci";
+	host->ops = &sdhci_pltfm_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
+
 	sdhci = sdhci_priv(host);
 
 	/* clk enable */
@@ -166,19 +165,6 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
-	host->hw_name = "sdhci";
-	host->ops = &sdhci_pltfm_ops;
-	host->irq = platform_get_irq(pdev, 0);
-	host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
-
-	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
-			resource_size(iomem));
-	if (!host->ioaddr) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "failed to remap registers\n");
-		goto disable_clk;
-	}
-
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
-- 
1.8.3.1


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

* [PATCH 3/5] mmc: sdhci-spear: simplify resource handling
@ 2014-02-21 10:41                           ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Use devm_ioremap_resource() to simplify iomem resource handling in the
probe path.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 40 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index ca1cb9776ea2..f879b27e59b1 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -113,20 +113,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	struct device *dev;
 	int ret;
 
-	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iomem) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "memory resource not defined\n");
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev, iomem->start,
-				resource_size(iomem), "spear-sdhci")) {
-		ret = -EBUSY;
-		dev_dbg(&pdev->dev, "cannot request region\n");
-		goto err;
-	}
-
 	dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
 	host = sdhci_alloc_host(dev, sizeof(*sdhci));
 	if (IS_ERR(host)) {
@@ -135,6 +121,19 @@ static int sdhci_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
+	if (IS_ERR(host->ioaddr)) {
+		ret = PTR_ERR(host->ioaddr);
+		dev_dbg(&pdev->dev, "unable to map iomem: %d\n", ret);
+		goto err_host;
+	}
+
+	host->hw_name = "sdhci";
+	host->ops = &sdhci_pltfm_ops;
+	host->irq = platform_get_irq(pdev, 0);
+	host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
+
 	sdhci = sdhci_priv(host);
 
 	/* clk enable */
@@ -166,19 +165,6 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
-	host->hw_name = "sdhci";
-	host->ops = &sdhci_pltfm_ops;
-	host->irq = platform_get_irq(pdev, 0);
-	host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
-
-	host->ioaddr = devm_ioremap(&pdev->dev, iomem->start,
-			resource_size(iomem));
-	if (!host->ioaddr) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "failed to remap registers\n");
-		goto disable_clk;
-	}
-
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
-- 
1.8.3.1

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

* [PATCH 4/5] mmc: sdhci-spear: remove support for power gpio
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-21 10:41                           ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: Viresh Kumar, Pratyush Anand, Mohit KUMAR
  Cc: linux-arm-kernel, Viresh Kumar, Chris Ball, spear-devel, linux-mmc

None of this code is currently used: there are no definitions of
struct sdhci_plat_data in arch/arm, neither are there any DT properties
which use card_power_gpio/power_active_high/power_always_enb.  In any
case, slot power control should be rigged up via vmmc and the regulator
subsystem in the DT case.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c  | 32 --------------------------------
 include/linux/mmc/sdhci-spear.h |  8 --------
 2 files changed, 40 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index f879b27e59b1..00a73b1a6444 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -59,14 +59,6 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
 	gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
 	irq_set_irq_type(irq, gpio_irq_type);
 
-	if (sdhci->data->card_power_gpio >= 0) {
-		if (!sdhci->data->power_always_enb) {
-			/* if card inserted, give power, otherwise remove it */
-			val = sdhci->data->power_active_high ? !val : val ;
-			gpio_set_value(sdhci->data->card_power_gpio, val);
-		}
-	}
-
 	/* inform sdhci driver about card insertion/removal */
 	tasklet_schedule(&host->card_tasklet);
 
@@ -184,30 +176,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	if (!sdhci->data)
 		return 0;
 
-	if (sdhci->data->card_power_gpio >= 0) {
-		int val = 0;
-
-		ret = devm_gpio_request(&pdev->dev,
-				sdhci->data->card_power_gpio, "sdhci");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
-					sdhci->data->card_power_gpio);
-			goto set_drvdata;
-		}
-
-		if (sdhci->data->power_always_enb)
-			val = sdhci->data->power_active_high;
-		else
-			val = !sdhci->data->power_active_high;
-
-		ret = gpio_direction_output(sdhci->data->card_power_gpio, val);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
-					sdhci->data->card_power_gpio);
-			goto set_drvdata;
-		}
-	}
-
 	if (sdhci->data->card_int_gpio >= 0) {
 		ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio,
 				"sdhci");
diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h
index e78c0e236e9d..8cc095a76cf8 100644
--- a/include/linux/mmc/sdhci-spear.h
+++ b/include/linux/mmc/sdhci-spear.h
@@ -18,17 +18,9 @@
 /*
  * struct sdhci_plat_data: spear sdhci platform data structure
  *
- * @card_power_gpio: gpio pin for enabling/disabling power to sdhci socket
- * @power_active_high: if set, enable power to sdhci socket by setting
- *			card_power_gpio
- * @power_always_enb: If set, then enable power on probe, otherwise enable only
- *			on card insertion and disable on card removal.
  * card_int_gpio: gpio pin used for card detection
  */
 struct sdhci_plat_data {
-	int card_power_gpio;
-	int power_active_high;
-	int power_always_enb;
 	int card_int_gpio;
 };
 
-- 
1.8.3.1


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

* [PATCH 4/5] mmc: sdhci-spear: remove support for power gpio
@ 2014-02-21 10:41                           ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

None of this code is currently used: there are no definitions of
struct sdhci_plat_data in arch/arm, neither are there any DT properties
which use card_power_gpio/power_active_high/power_always_enb.  In any
case, slot power control should be rigged up via vmmc and the regulator
subsystem in the DT case.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c  | 32 --------------------------------
 include/linux/mmc/sdhci-spear.h |  8 --------
 2 files changed, 40 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index f879b27e59b1..00a73b1a6444 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -59,14 +59,6 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
 	gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
 	irq_set_irq_type(irq, gpio_irq_type);
 
-	if (sdhci->data->card_power_gpio >= 0) {
-		if (!sdhci->data->power_always_enb) {
-			/* if card inserted, give power, otherwise remove it */
-			val = sdhci->data->power_active_high ? !val : val ;
-			gpio_set_value(sdhci->data->card_power_gpio, val);
-		}
-	}
-
 	/* inform sdhci driver about card insertion/removal */
 	tasklet_schedule(&host->card_tasklet);
 
@@ -184,30 +176,6 @@ static int sdhci_probe(struct platform_device *pdev)
 	if (!sdhci->data)
 		return 0;
 
-	if (sdhci->data->card_power_gpio >= 0) {
-		int val = 0;
-
-		ret = devm_gpio_request(&pdev->dev,
-				sdhci->data->card_power_gpio, "sdhci");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
-					sdhci->data->card_power_gpio);
-			goto set_drvdata;
-		}
-
-		if (sdhci->data->power_always_enb)
-			val = sdhci->data->power_active_high;
-		else
-			val = !sdhci->data->power_active_high;
-
-		ret = gpio_direction_output(sdhci->data->card_power_gpio, val);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
-					sdhci->data->card_power_gpio);
-			goto set_drvdata;
-		}
-	}
-
 	if (sdhci->data->card_int_gpio >= 0) {
 		ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio,
 				"sdhci");
diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h
index e78c0e236e9d..8cc095a76cf8 100644
--- a/include/linux/mmc/sdhci-spear.h
+++ b/include/linux/mmc/sdhci-spear.h
@@ -18,17 +18,9 @@
 /*
  * struct sdhci_plat_data: spear sdhci platform data structure
  *
- * @card_power_gpio: gpio pin for enabling/disabling power to sdhci socket
- * @power_active_high: if set, enable power to sdhci socket by setting
- *			card_power_gpio
- * @power_always_enb: If set, then enable power on probe, otherwise enable only
- *			on card insertion and disable on card removal.
  * card_int_gpio: gpio pin used for card detection
  */
 struct sdhci_plat_data {
-	int card_power_gpio;
-	int power_active_high;
-	int power_always_enb;
 	int card_int_gpio;
 };
 
-- 
1.8.3.1

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

* [PATCH 5/5] mmc: sdhci-spear: use generic card detection gpio support
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-21 10:41                           ` Russell King
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: Viresh Kumar, Pratyush Anand, Mohit KUMAR
  Cc: linux-arm-kernel, Viresh Kumar, Chris Ball, spear-devel, linux-mmc

sdhci has support for using GPIOs for card detection.  If we have a
GPIO specified, we can use that directly, without needing our own
interrupt handler.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 78 +++++++++---------------------------------
 1 file changed, 16 insertions(+), 62 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 00a73b1a6444..af3338fb0762 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -43,28 +43,6 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
-/* gpio card detection interrupt handler */
-static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
-{
-	struct platform_device *pdev = dev_id;
-	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
-	unsigned long gpio_irq_type;
-	int val;
-
-	val = gpio_get_value(sdhci->data->card_int_gpio);
-
-	/* val == 1 -> card removed, val == 0 -> card inserted */
-	/* if card removed - set irq for low level, else vice versa */
-	gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
-	irq_set_irq_type(irq, gpio_irq_type);
-
-	/* inform sdhci driver about card insertion/removal */
-	tasklet_schedule(&host->card_tasklet);
-
-	return IRQ_HANDLED;
-}
-
 #ifdef CONFIG_OF
 static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
 {
@@ -157,6 +135,22 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
+	/*
+	 * It is optional to use GPIOs for sdhci card detection. If
+	 * sdhci->data is NULL, then use original sdhci lines otherwise
+	 * GPIO lines. We use the built-in GPIO support for this.
+	 */
+	if (sdhci->data && sdhci->data->card_int_gpio >= 0) {
+		ret = mmc_gpio_request_cd(host->mmc,
+					  sdhci->data->card_int_gpio, 0);
+		if (ret < 0) {
+			dev_dbg(&pdev->dev,
+				"failed to request card-detect gpio%d\n",
+				sdhci->data->card_int_gpio);
+			goto disable_clk;
+		}
+	}
+
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
@@ -165,48 +159,8 @@ static int sdhci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, host);
 
-	/*
-	 * It is optional to use GPIOs for sdhci Power control & sdhci card
-	 * interrupt detection. If sdhci->data is NULL, then use original sdhci
-	 * lines otherwise GPIO lines.
-	 * If GPIO is selected for power control, then power should be disabled
-	 * after card removal and should be enabled when card insertion
-	 * interrupt occurs
-	 */
-	if (!sdhci->data)
-		return 0;
-
-	if (sdhci->data->card_int_gpio >= 0) {
-		ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio,
-				"sdhci");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-
-		ret = gpio_direction_input(sdhci->data->card_int_gpio);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-		ret = devm_request_irq(&pdev->dev,
-				gpio_to_irq(sdhci->data->card_int_gpio),
-				sdhci_gpio_irq, IRQF_TRIGGER_LOW,
-				mmc_hostname(host->mmc), pdev);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio request irq fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-
-	}
-
 	return 0;
 
-set_drvdata:
-	sdhci_remove_host(host, 1);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
 err_host:
-- 
1.8.3.1


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

* [PATCH 5/5] mmc: sdhci-spear: use generic card detection gpio support
@ 2014-02-21 10:41                           ` Russell King
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King @ 2014-02-21 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

sdhci has support for using GPIOs for card detection.  If we have a
GPIO specified, we can use that directly, without needing our own
interrupt handler.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/mmc/host/sdhci-spear.c | 78 +++++++++---------------------------------
 1 file changed, 16 insertions(+), 62 deletions(-)

diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 00a73b1a6444..af3338fb0762 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -43,28 +43,6 @@ static const struct sdhci_ops sdhci_pltfm_ops = {
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
 };
 
-/* gpio card detection interrupt handler */
-static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
-{
-	struct platform_device *pdev = dev_id;
-	struct sdhci_host *host = platform_get_drvdata(pdev);
-	struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev);
-	unsigned long gpio_irq_type;
-	int val;
-
-	val = gpio_get_value(sdhci->data->card_int_gpio);
-
-	/* val == 1 -> card removed, val == 0 -> card inserted */
-	/* if card removed - set irq for low level, else vice versa */
-	gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
-	irq_set_irq_type(irq, gpio_irq_type);
-
-	/* inform sdhci driver about card insertion/removal */
-	tasklet_schedule(&host->card_tasklet);
-
-	return IRQ_HANDLED;
-}
-
 #ifdef CONFIG_OF
 static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev)
 {
@@ -157,6 +135,22 @@ static int sdhci_probe(struct platform_device *pdev)
 		sdhci->data = dev_get_platdata(&pdev->dev);
 	}
 
+	/*
+	 * It is optional to use GPIOs for sdhci card detection. If
+	 * sdhci->data is NULL, then use original sdhci lines otherwise
+	 * GPIO lines. We use the built-in GPIO support for this.
+	 */
+	if (sdhci->data && sdhci->data->card_int_gpio >= 0) {
+		ret = mmc_gpio_request_cd(host->mmc,
+					  sdhci->data->card_int_gpio, 0);
+		if (ret < 0) {
+			dev_dbg(&pdev->dev,
+				"failed to request card-detect gpio%d\n",
+				sdhci->data->card_int_gpio);
+			goto disable_clk;
+		}
+	}
+
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_dbg(&pdev->dev, "error adding host\n");
@@ -165,48 +159,8 @@ static int sdhci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, host);
 
-	/*
-	 * It is optional to use GPIOs for sdhci Power control & sdhci card
-	 * interrupt detection. If sdhci->data is NULL, then use original sdhci
-	 * lines otherwise GPIO lines.
-	 * If GPIO is selected for power control, then power should be disabled
-	 * after card removal and should be enabled when card insertion
-	 * interrupt occurs
-	 */
-	if (!sdhci->data)
-		return 0;
-
-	if (sdhci->data->card_int_gpio >= 0) {
-		ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio,
-				"sdhci");
-		if (ret < 0) {
-			dev_dbg(&pdev->dev, "gpio request fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-
-		ret = gpio_direction_input(sdhci->data->card_int_gpio);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio set direction fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-		ret = devm_request_irq(&pdev->dev,
-				gpio_to_irq(sdhci->data->card_int_gpio),
-				sdhci_gpio_irq, IRQF_TRIGGER_LOW,
-				mmc_hostname(host->mmc), pdev);
-		if (ret) {
-			dev_dbg(&pdev->dev, "gpio request irq fail: %d\n",
-					sdhci->data->card_int_gpio);
-			goto set_drvdata;
-		}
-
-	}
-
 	return 0;
 
-set_drvdata:
-	sdhci_remove_host(host, 1);
 disable_clk:
 	clk_disable_unprepare(sdhci->clk);
 err_host:
-- 
1.8.3.1

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-21 10:37                         ` Russell King - ARM Linux
@ 2014-02-22 18:27                           ` Chris Ball
  -1 siblings, 0 replies; 121+ messages in thread
From: Chris Ball @ 2014-02-22 18:27 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Viresh Kumar, Pratyush Anand, spear-devel, Mohit KUMAR,
	linux-arm-kernel, linux-mmc

Hi,

On Fri, Feb 21 2014, Russell King - ARM Linux wrote:
> On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
>> Nothing wrong in that, only right.. Do you want me to float a patch for
>> this or you can get that done along with your series?
>
> I'll send a follow-up mini-series of five patches for it.  It shouldn't
> depend all that much on the bigger series - and I think the first two
> patches could well do with going into -rc.

Thanks.  Since testing resources might be scarce, and it looks like
Viresh is in favor of the series, any objections to putting these in
mmc-next straight away rather than waiting for test results to come in?

- Chris.
-- 
Chris Ball   <chris@printf.net>   <http://printf.net/>

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-22 18:27                           ` Chris Ball
  0 siblings, 0 replies; 121+ messages in thread
From: Chris Ball @ 2014-02-22 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Fri, Feb 21 2014, Russell King - ARM Linux wrote:
> On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
>> Nothing wrong in that, only right.. Do you want me to float a patch for
>> this or you can get that done along with your series?
>
> I'll send a follow-up mini-series of five patches for it.  It shouldn't
> depend all that much on the bigger series - and I think the first two
> patches could well do with going into -rc.

Thanks.  Since testing resources might be scarce, and it looks like
Viresh is in favor of the series, any objections to putting these in
mmc-next straight away rather than waiting for test results to come in?

- Chris.
-- 
Chris Ball   <chris@printf.net>   <http://printf.net/>

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-22 18:27                           ` Chris Ball
@ 2014-02-22 19:05                             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-22 19:05 UTC (permalink / raw)
  To: Chris Ball
  Cc: Viresh Kumar, Pratyush Anand, spear-devel, Mohit KUMAR,
	linux-arm-kernel, linux-mmc

On Sat, Feb 22, 2014 at 06:27:06PM +0000, Chris Ball wrote:
> Hi,
> 
> On Fri, Feb 21 2014, Russell King - ARM Linux wrote:
> > On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
> >> Nothing wrong in that, only right.. Do you want me to float a patch for
> >> this or you can get that done along with your series?
> >
> > I'll send a follow-up mini-series of five patches for it.  It shouldn't
> > depend all that much on the bigger series - and I think the first two
> > patches could well do with going into -rc.
> 
> Thanks.  Since testing resources might be scarce, and it looks like
> Viresh is in favor of the series, any objections to putting these in
> mmc-next straight away rather than waiting for test results to come in?

The series needs to be re-ordered to avoid patch 7 breaking sdhci-spear.
I'll send out a new series appropriately ordered.  I'm continuing to do
more to this driver as time permits.

One thing which I've toyed with is passing a "changes" field in struct
mmc_ios, so that host drivers can know what's changed and avoid resetting
the power, clocks, etc on every set_ios call.  Another thing I've toyed
with is the idea of splitting set_ios up into several sub-calls which
the core only calls with the various changes.

One of my reasonings for the second idea is that with the variability
in hosts, particularly with how they deal with the application of power,
it would be a good idea to allow hosts which do the "turn power on,
send 74 clocks" automonously avoid having to deal with the power_up
transition.

It also means that hosts aren't having to work out if the timings have
changed, or the clocks, or anything else.

What are your thoughts on that?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-22 19:05                             ` Russell King - ARM Linux
  0 siblings, 0 replies; 121+ messages in thread
From: Russell King - ARM Linux @ 2014-02-22 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Feb 22, 2014 at 06:27:06PM +0000, Chris Ball wrote:
> Hi,
> 
> On Fri, Feb 21 2014, Russell King - ARM Linux wrote:
> > On Thu, Feb 20, 2014 at 04:48:58PM +0530, Viresh Kumar wrote:
> >> Nothing wrong in that, only right.. Do you want me to float a patch for
> >> this or you can get that done along with your series?
> >
> > I'll send a follow-up mini-series of five patches for it.  It shouldn't
> > depend all that much on the bigger series - and I think the first two
> > patches could well do with going into -rc.
> 
> Thanks.  Since testing resources might be scarce, and it looks like
> Viresh is in favor of the series, any objections to putting these in
> mmc-next straight away rather than waiting for test results to come in?

The series needs to be re-ordered to avoid patch 7 breaking sdhci-spear.
I'll send out a new series appropriately ordered.  I'm continuing to do
more to this driver as time permits.

One thing which I've toyed with is passing a "changes" field in struct
mmc_ios, so that host drivers can know what's changed and avoid resetting
the power, clocks, etc on every set_ios call.  Another thing I've toyed
with is the idea of splitting set_ios up into several sub-calls which
the core only calls with the various changes.

One of my reasonings for the second idea is that with the variability
in hosts, particularly with how they deal with the application of power,
it would be a good idea to allow hosts which do the "turn power on,
send 74 clocks" automonously avoid having to deal with the power_up
transition.

It also means that hosts aren't having to work out if the timings have
changed, or the clocks, or anything else.

What are your thoughts on that?

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

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

* Re: [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
  2014-02-22 19:05                             ` Russell King - ARM Linux
@ 2014-02-22 19:11                               ` Chris Ball
  -1 siblings, 0 replies; 121+ messages in thread
From: Chris Ball @ 2014-02-22 19:11 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Viresh Kumar, Pratyush Anand, spear-devel, Mohit KUMAR,
	linux-arm-kernel, linux-mmc

Hi Russell,

On Sat, Feb 22 2014, Russell King - ARM Linux wrote:
>> > I'll send a follow-up mini-series of five patches for it.  It shouldn't
>> > depend all that much on the bigger series - and I think the first two
>> > patches could well do with going into -rc.
>> 
>> Thanks.  Since testing resources might be scarce, and it looks like
>> Viresh is in favor of the series, any objections to putting these in
>> mmc-next straight away rather than waiting for test results to come in?
>
> The series needs to be re-ordered to avoid patch 7 breaking sdhci-spear.
> I'll send out a new series appropriately ordered.  I'm continuing to do
> more to this driver as time permits.

Ah, I guess I chose the wrong mail to reply to -- I'm talking about
merging the five patch mini-series that descends from this mail
straight away, not the 31 patch RFC.

> One thing which I've toyed with is passing a "changes" field in struct
> mmc_ios, so that host drivers can know what's changed and avoid resetting
> the power, clocks, etc on every set_ios call.  Another thing I've toyed
> with is the idea of splitting set_ios up into several sub-calls which
> the core only calls with the various changes.
>
> One of my reasonings for the second idea is that with the variability
> in hosts, particularly with how they deal with the application of power,
> it would be a good idea to allow hosts which do the "turn power on,
> send 74 clocks" automonously avoid having to deal with the power_up
> transition.
>
> It also means that hosts aren't having to work out if the timings have
> changed, or the clocks, or anything else.
>
> What are your thoughts on that?

Sounds like an improvement.  Splitting up set_ios sounds cleaner than
using a "changes" field to me.  Thanks,

- Chris.
-- 
Chris Ball   <chris@printf.net>   <http://printf.net/>

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

* [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler
@ 2014-02-22 19:11                               ` Chris Ball
  0 siblings, 0 replies; 121+ messages in thread
From: Chris Ball @ 2014-02-22 19:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Sat, Feb 22 2014, Russell King - ARM Linux wrote:
>> > I'll send a follow-up mini-series of five patches for it.  It shouldn't
>> > depend all that much on the bigger series - and I think the first two
>> > patches could well do with going into -rc.
>> 
>> Thanks.  Since testing resources might be scarce, and it looks like
>> Viresh is in favor of the series, any objections to putting these in
>> mmc-next straight away rather than waiting for test results to come in?
>
> The series needs to be re-ordered to avoid patch 7 breaking sdhci-spear.
> I'll send out a new series appropriately ordered.  I'm continuing to do
> more to this driver as time permits.

Ah, I guess I chose the wrong mail to reply to -- I'm talking about
merging the five patch mini-series that descends from this mail
straight away, not the 31 patch RFC.

> One thing which I've toyed with is passing a "changes" field in struct
> mmc_ios, so that host drivers can know what's changed and avoid resetting
> the power, clocks, etc on every set_ios call.  Another thing I've toyed
> with is the idea of splitting set_ios up into several sub-calls which
> the core only calls with the various changes.
>
> One of my reasonings for the second idea is that with the variability
> in hosts, particularly with how they deal with the application of power,
> it would be a good idea to allow hosts which do the "turn power on,
> send 74 clocks" automonously avoid having to deal with the power_up
> transition.
>
> It also means that hosts aren't having to work out if the timings have
> changed, or the clocks, or anything else.
>
> What are your thoughts on that?

Sounds like an improvement.  Splitting up set_ios sounds cleaner than
using a "changes" field to me.  Thanks,

- Chris.
-- 
Chris Ball   <chris@printf.net>   <http://printf.net/>

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

* Re: [PATCH 1/5] mmc: sdhci-spear: fix error handling paths for DT
  2014-02-21 10:41                           ` Russell King
@ 2014-02-24  5:59                             ` Viresh Kumar
  -1 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-24  5:59 UTC (permalink / raw)
  To: Russell King
  Cc: Pratyush Anand, Mohit KUMAR, linux-arm-kernel, Viresh Kumar,
	Chris Ball, spear-devel, linux-mmc

On 21 February 2014 16:11, Russell King <rmk+kernel@arm.linux.org.uk> wrote:
> Fix the error handling paths for DT and simplify using the devm_* API
> for clk_get().
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/mmc/host/sdhci-spear.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

For all patches:

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

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

* [PATCH 1/5] mmc: sdhci-spear: fix error handling paths for DT
@ 2014-02-24  5:59                             ` Viresh Kumar
  0 siblings, 0 replies; 121+ messages in thread
From: Viresh Kumar @ 2014-02-24  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 February 2014 16:11, Russell King <rmk+kernel@arm.linux.org.uk> wrote:
> Fix the error handling paths for DT and simplify using the devm_* API
> for clk_get().
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/mmc/host/sdhci-spear.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

For all patches:

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

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

* Re: [PATCH 5/5] mmc: sdhci-spear: use generic card detection gpio support
  2014-02-21 10:41                           ` Russell King
@ 2014-02-24  6:11                             ` Pratyush Anand
  -1 siblings, 0 replies; 121+ messages in thread
From: Pratyush Anand @ 2014-02-24  6:11 UTC (permalink / raw)
  To: Russell King
  Cc: Viresh Kumar, Mohit KUMAR DCG, linux-arm-kernel, Viresh Kumar,
	Chris Ball, spear-devel, linux-mmc

Hi Russell,

On Fri, Feb 21, 2014 at 06:41:28PM +0800, Russell King wrote:
> sdhci has support for using GPIOs for card detection.  If we have a
> GPIO specified, we can use that directly, without needing our own
> interrupt handler.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/mmc/host/sdhci-spear.c | 78 +++++++++---------------------------------
>  1 file changed, 16 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
> index 00a73b1a6444..af3338fb0762 100644
> --- a/drivers/mmc/host/sdhci-spear.c
> +++ b/drivers/mmc/host/sdhci-spear.c

To get mmc_gpio_request_cd declaration 

#include <linux/mmc/slot-gpio.h>

is needed.

Regards
Pratyush

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

* [PATCH 5/5] mmc: sdhci-spear: use generic card detection gpio support
@ 2014-02-24  6:11                             ` Pratyush Anand
  0 siblings, 0 replies; 121+ messages in thread
From: Pratyush Anand @ 2014-02-24  6:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On Fri, Feb 21, 2014 at 06:41:28PM +0800, Russell King wrote:
> sdhci has support for using GPIOs for card detection.  If we have a
> GPIO specified, we can use that directly, without needing our own
> interrupt handler.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  drivers/mmc/host/sdhci-spear.c | 78 +++++++++---------------------------------
>  1 file changed, 16 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
> index 00a73b1a6444..af3338fb0762 100644
> --- a/drivers/mmc/host/sdhci-spear.c
> +++ b/drivers/mmc/host/sdhci-spear.c

To get mmc_gpio_request_cd declaration 

#include <linux/mmc/slot-gpio.h>

is needed.

Regards
Pratyush

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

end of thread, other threads:[~2014-02-24  6:12 UTC | newest]

Thread overview: 121+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-18 15:08 [PATCH RFC 00/31] SDHCI and SDIO IRQ improvements Russell King - ARM Linux
2014-02-18 15:08 ` Russell King - ARM Linux
2014-02-18 15:08 ` Russell King - ARM Linux
2014-02-18 15:09 ` [PATCH RFC 01/31] genirq: Provide synchronize_hardirq() Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 02/31] genirq: Provide irq_wake_thread() Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 03/31] mmc: sdio_irq: rework sdio irq handling Russell King
2014-02-18 15:09   ` Russell King
2014-02-19  3:40   ` Nicolas Pitre
2014-02-19  3:40     ` Nicolas Pitre
2014-02-19  9:44     ` Russell King - ARM Linux
2014-02-19  9:44       ` Russell King - ARM Linux
2014-02-18 15:09 ` [PATCH RFC 04/31] mmc: sdhci: clean up interrupt handling Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 05/31] mmc: sdhci: clean up sdio interrupt enable handling Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 06/31] mmc: sdhci: convert to new SDIO IRQ handling Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 17:57   ` Russell King - ARM Linux
2014-02-18 17:57     ` Russell King - ARM Linux
2014-02-19  6:13     ` Viresh Kumar
2014-02-19  6:13       ` Viresh Kumar
2014-02-19  9:43       ` Russell King - ARM Linux
2014-02-19  9:43         ` Russell King - ARM Linux
2014-02-19  9:48         ` Viresh Kumar
2014-02-19  9:48           ` Viresh Kumar
2014-02-19  9:52           ` Russell King - ARM Linux
2014-02-19  9:52             ` Russell King - ARM Linux
2014-02-19 10:09             ` Viresh Kumar
2014-02-19 10:09               ` Viresh Kumar
2014-02-19 10:50               ` Russell King - ARM Linux
2014-02-19 10:50                 ` Russell King - ARM Linux
2014-02-19 10:55                 ` Viresh Kumar
2014-02-19 10:55                   ` Viresh Kumar
2014-02-20 10:59                   ` Russell King - ARM Linux
2014-02-20 10:59                     ` Russell King - ARM Linux
2014-02-20 11:18                     ` Viresh Kumar
2014-02-20 11:18                       ` Viresh Kumar
2014-02-21 10:37                       ` Russell King - ARM Linux
2014-02-21 10:37                         ` Russell King - ARM Linux
2014-02-21 10:41                         ` [PATCH 1/5] mmc: sdhci-spear: fix error handling paths for DT Russell King
2014-02-21 10:41                           ` Russell King
2014-02-24  5:59                           ` Viresh Kumar
2014-02-24  5:59                             ` Viresh Kumar
2014-02-21 10:41                         ` [PATCH 2/5] mmc: sdhci-spear: fix platform_data usage Russell King
2014-02-21 10:41                           ` Russell King
2014-02-21 10:41                         ` [PATCH 3/5] mmc: sdhci-spear: simplify resource handling Russell King
2014-02-21 10:41                           ` Russell King
2014-02-21 10:41                         ` [PATCH 4/5] mmc: sdhci-spear: remove support for power gpio Russell King
2014-02-21 10:41                           ` Russell King
2014-02-21 10:41                         ` [PATCH 5/5] mmc: sdhci-spear: use generic card detection gpio support Russell King
2014-02-21 10:41                           ` Russell King
2014-02-24  6:11                           ` Pratyush Anand
2014-02-24  6:11                             ` Pratyush Anand
2014-02-22 18:27                         ` [PATCH RFC 07/31] mmc: sdhci: push card_tasklet into threaded irq handler Chris Ball
2014-02-22 18:27                           ` Chris Ball
2014-02-22 19:05                           ` Russell King - ARM Linux
2014-02-22 19:05                             ` Russell King - ARM Linux
2014-02-22 19:11                             ` Chris Ball
2014-02-22 19:11                               ` Chris Ball
2014-02-18 15:09 ` [PATCH RFC 08/31] mmc: sdhci: allow sdio interrupts while sdhci runtime suspended Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 09/31] mmc: sdhci: more efficient interrupt enable register handling Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 10/31] mmc: sdhci: plug hole in disabling card detection interrupts Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09 ` [PATCH RFC 11/31] mmc: sdhci: convert generic bus width setup to library function Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:09   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 12/31] mmc: sdhci: convert reset into a " Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 13/31] mmc: sdhci: move FSL ESDHC reset handling quirk into esdhc code Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 14/31] mmc: sdhci: avoid sync'ing the SG if there's no misalignment Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 15/31] mmc: sdhci: convert ADMA descriptors to a coherent allocation Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 16/31] mmc: sdhci: clean up sdhci_update_clock()/sdhci_set_clock() Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 17/31] mmc: sdhci: move setting host->clock into sdhci_do_set_ios() Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 18/31] mmc: sdhci: move setting mmc->actual_clock into set_clock handlers Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 19/31] mmc: sdhci: convert sdhci_set_clock() into a library function Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 20/31] mmc: sdhci-esdhc-imx: avoid DMA to kernel stack Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 21/31] mmc: sdhci-esdhc-imx: avoid runtime_pm_get_sync() in esdhc_prepare_tuning() Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:10 ` [PATCH RFC 22/31] mmc: sdhci-esdhc-imx: fix lockdep splat upon tuning Russell King
2014-02-18 15:10   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 23/31] mmc: sdhci: hack up driver to make it more compliant with UHS-1 Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 24/31] mmc: sdhci: set_uhs_signaling() need not return a value Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 25/31] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 26/31] mmc: sdhci: cache timing information locally Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 27/31] mmc: sdhci: clean up sdhci_execute_tuning() decision Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 28/31] mmc: sdhci-esdhc-imx: remove emulation of uhs_mode Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 29/31] mmc: sdhci-of-esdhc: remove platform_suspend/platform_resume callbacks Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 30/31] mmc: sdhci: " Russell King
2014-02-18 15:11   ` Russell King
2014-02-18 15:11 ` [PATCH RFC 31/31] mmc: sdhci-tegra: get rid of special PRESENT_STATE register handling Russell King
2014-02-18 15:11   ` Russell King
2014-02-19 20:04   ` Stephen Warren
2014-02-19 20:04     ` Stephen Warren
2014-02-19 23:22     ` Russell King - ARM Linux
2014-02-19 23:22       ` Russell King - ARM Linux
     [not found]       ` <20140219232253.GW21483-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2014-02-19 23:28         ` Russell King - ARM Linux
2014-02-19 23:28           ` Russell King - ARM Linux

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.