Skip to contentSkip to conversation

sdhci-s3c: support clock enable/disable (clock-gating)

RFC In review Jaehoon Chung 7 participants 11 messages Sep 16, 2010 – Oct 5, 2010

Subsystems (3)
lore
Share & tools
lore

Jaehoon Chung

author maintainer
#0 lore raw

RFC 1/1 sdhci-s3c: support clock enable/disable (clock-gating)

Hi all,
This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
(using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

Thank you all

---
 drivers/mmc/host/sdhci-s3c.c |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c     |   30 ++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.h     |    4 ++++
 3 files changed, 70 insertions(+), 0 deletions(-)
drivers/mmc/host/sdhci-s3c.c +36 -0
index 71ad416..9b430fb 100644
@@ -47,6 +47,7 @@ struct sdhci_s3c {
 	unsigned int		cur_clk;
 	int			ext_cd_irq;
 	int			ext_cd_gpio;
+	int			flag;
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
@@ -232,10 +233,45 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
 	return min;
 }
 
+static int sdhci_s3c_enable_clk(struct sdhci_host *host)
+{
+	struct sdhci_s3c *sc = to_s3c(host);
+
+	if (sc->flag != 1) {
+		clk_disable(sc->clk_io);
+		clk_disable(sc->clk_bus[sc->cur_clk]);
+	}
+
+	if (sc->host->clk_cnt == 0) {
+		clk_enable(sc->clk_io);
+		clk_enable(sc->clk_bus[sc->cur_clk]);
+		sc->host->clk_cnt++;
+		sc->flag = 1;
+	}
+
+	return 0;
+}
+
+static int sdhci_s3c_disable_clk(struct sdhci_host *host, int lazy)
+{
+	struct sdhci_s3c *sc = to_s3c(host);
+
+	if (sc->host->clk_cnt) {
+		clk_disable(sc->clk_io);
+		clk_disable(sc->clk_bus[sc->cur_clk]);
+		if (sc->host->clk_cnt)
+			sc->host->clk_cnt--;
+	}
+
+	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,
+	.enable			= sdhci_s3c_enable_clk,
+	.disable		= sdhci_s3c_disable_clk,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
drivers/mmc/host/sdhci.c +30 -0
index 401527d..fa2e55d 100644
@@ -1245,7 +1245,37 @@ out:
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_enable_clk(struct mmc_host *mmc)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->old_clock != 0 && host->clock == 0) {
+		if (host->ops->enable)
+			ret = host->ops->enable(host);
+		sdhci_set_clock(host, host->old_clock);
+	}
+
+	return ret;
+}
+
+static int sdhci_disable_clk(struct mmc_host *mmc, int lazy)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->clock != 0) {
+		host->old_clock = host->clock;
+		sdhci_set_clock(host, 0);
+		if (host->ops->disable)
+			ret = host->ops->disable(host, lazy);
+	}
+	return ret;
+}
+
 static const struct mmc_host_ops sdhci_ops = {
+	.enable		= sdhci_enable_clk,
+	.disable	= sdhci_disable_clk,
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
drivers/mmc/host/sdhci.h +4 -0
index d316bc7..0c6f143 100644
@@ -278,6 +278,8 @@ struct sdhci_host {
 	unsigned int		timeout_clk;	/* Timeout freq (KHz) */
 
 	unsigned int		clock;		/* Current clock (MHz) */
+	unsigned int		old_clock;	/* Old clock (MHz) */
+	unsigned int		clk_cnt;	/* Clock user count */
 	u8			pwr;		/* Current voltage */
 
 	struct mmc_request	*mrq;		/* Current request */
@@ -323,6 +325,8 @@ 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		(*enable)(struct sdhci_host *host);
+	int		(*disable)(struct sdhci_host *host, int lazy);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

-- 1.6.0.4

#1 lore raw
Quoted 19 lines · Jaehoon Chung

Hi all,
This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
(using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

Thank you all

---
 drivers/mmc/host/sdhci-s3c.c |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c     |   30 ++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.h     |    4 ++++
 3 files changed, 70 insertions(+), 0 deletions(-)

[...]

Quoted 56 lines
drivers/mmc/host/sdhci.c +30 -0
index 401527d..fa2e55d 100644
@@ -1245,7 +1245,37 @@ out:
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_enable_clk(struct mmc_host *mmc)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->old_clock != 0 && host->clock == 0) {
+		if (host->ops->enable)
+			ret = host->ops->enable(host);
+		sdhci_set_clock(host, host->old_clock);
+	}
+
+	return ret;
+}
+
+static int sdhci_disable_clk(struct mmc_host *mmc, int lazy)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->clock != 0) {
+		host->old_clock = host->clock;
+		sdhci_set_clock(host, 0);
+		if (host->ops->disable)
+			ret = host->ops->disable(host, lazy);
+	}
+	return ret;
+}
+
 static const struct mmc_host_ops sdhci_ops = {
+	.enable		= sdhci_enable_clk,
+	.disable	= sdhci_disable_clk,
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
drivers/mmc/host/sdhci.h +2 -0
index d316bc7..0c6f143 100644
@@ -278,6 +278,8 @@ struct sdhci_host {
 	unsigned int		timeout_clk;	/* Timeout freq (KHz) */
 
 	unsigned int		clock;		/* Current clock (MHz) */
+	unsigned int		old_clock;	/* Old clock (MHz) */
+	unsigned int		clk_cnt;	/* Clock user count */
 	u8			pwr;		/* Current voltage */
 
 	struct mmc_request	*mrq;		/* Current request */

drivers/mmc/host/sdhci.h struct sdhci_ops { · line 332

Quoted 8 lines
drivers/mmc/host/sdhci.h +2 -0
@@ -323,6 +325,8 @@ 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		(*enable)(struct sdhci_host *host);
+	int		(*disable)(struct sdhci_host *host, int lazy);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

I could have misunderstood something, but do you really need this new 'old_clock' member? Is the previous clock value not stored in host->ios.clock?

#2 lore raw

2010/9/17 Matt Fleming <[email protected]>:

Quoted 86 lines · Jaehoon Chung
Quoted 19 lines

Hi all,
  This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
  (using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

Thank you all

---
 drivers/mmc/host/sdhci-s3c.c |   36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c     |   30 ++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h     |    4 ++++

 3 files changed, 70 insertions(+), 0 deletions(-)

[...]

Quoted 63 lines
drivers/mmc/host/sdhci.c +30 -0
index 401527d..fa2e55d 100644
@@ -1245,7 +1245,37 @@ out:
       spin_unlock_irqrestore(&host->lock, flags);
  }
 
+static int sdhci_enable_clk(struct mmc_host *mmc)
+{
+     struct sdhci_host *host = mmc_priv(mmc);
+     int ret = 0;
+
+     if (host->old_clock != 0 && host->clock == 0) {
+             if (host->ops->enable)
+                     ret = host->ops->enable(host);
+             sdhci_set_clock(host, host->old_clock);
+     }
+
+     return ret;
+}
+
+static int sdhci_disable_clk(struct mmc_host *mmc, int lazy)
+{
+     struct sdhci_host *host = mmc_priv(mmc);
+     int ret = 0;
+
+     if (host->clock != 0) {
+             host->old_clock = host->clock;
+             sdhci_set_clock(host, 0);
+             if (host->ops->disable)
+                     ret = host->ops->disable(host, lazy);
+     }
+     return ret;
+}
+
  static const struct mmc_host_ops sdhci_ops = {
+     .enable         = sdhci_enable_clk,
+     .disable        = sdhci_disable_clk,
       .request        = sdhci_request,
       .set_ios        = sdhci_set_ios,
       .get_ro         = sdhci_get_ro,
drivers/mmc/host/sdhci.h +0 -0
index d316bc7..0c6f143 100644
@@ -278,6 +278,8 @@ struct sdhci_host {

      unsigned int            timeout_clk;    /* Timeout freq (KHz) */

      unsigned int            clock;          /* Current clock (MHz) */
+     unsigned int            old_clock;      /* Old clock (MHz) */
+     unsigned int            clk_cnt;        /* Clock user count */ u8                      pwr;            /* Current voltage */

      struct mmc_request      *mrq;           /* Current request */

drivers/mmc/host/sdhci.h +2 -0
@@ -323,6 +325,8 @@ 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             (*enable)(struct sdhci_host *host);
+     int             (*disable)(struct sdhci_host *host, int lazy);
  };
 
Quoted 5 lines

drivers/mmc/host/sdhci.h struct sdhci_ops { · line 332

Quoted 1 line
drivers/mmc/host/sdhci.h +0 -0
  #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

I could have misunderstood something, but do you really need this new 'old_clock' member? Is the previous clock value not stored in host->ios.clock?

Thanks Matt for your comment.
if host->ios.clock set zero, i think that need previous value (for example 52MHz..)
So i add 'old_clock' member...i will test, after removed 'old_clock'

anyother doubt? and problem?
Thanks

author maintainer
#3 lore raw
Quoted 91 lines · Jae hoon Chung

2010/9/17 Matt Fleming <[email protected]>:

Quoted 85 lines · Jaehoon Chung
Quoted 19 lines

Hi all,
This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
(using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

Thank you all

---
 drivers/mmc/host/sdhci-s3c.c |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c     |   30 ++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.h     |    4 ++++
 3 files changed, 70 insertions(+), 0 deletions(-)

[...]

Quoted 63 lines
drivers/mmc/host/sdhci.c +30 -0
index 401527d..fa2e55d 100644
@@ -1245,7 +1245,37 @@ out:
      spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_enable_clk(struct mmc_host *mmc)
+{
+     struct sdhci_host *host = mmc_priv(mmc);
+     int ret = 0;
+
+     if (host->old_clock != 0 && host->clock == 0) {
+             if (host->ops->enable)
+                     ret = host->ops->enable(host);
+             sdhci_set_clock(host, host->old_clock);
+     }
+
+     return ret;
+}
+
+static int sdhci_disable_clk(struct mmc_host *mmc, int lazy)
+{
+     struct sdhci_host *host = mmc_priv(mmc);
+     int ret = 0;
+
+     if (host->clock != 0) {
+             host->old_clock = host->clock;
+             sdhci_set_clock(host, 0);
+             if (host->ops->disable)
+                     ret = host->ops->disable(host, lazy);
+     }
+     return ret;
+}
+
 static const struct mmc_host_ops sdhci_ops = {
+     .enable         = sdhci_enable_clk,
+     .disable        = sdhci_disable_clk,
      .request        = sdhci_request,
      .set_ios        = sdhci_set_ios,
      .get_ro         = sdhci_get_ro,
drivers/mmc/host/sdhci.h +4 -0
index d316bc7..0c6f143 100644
@@ -278,6 +278,8 @@ struct sdhci_host {
      unsigned int            timeout_clk;    /* Timeout freq (KHz) */
 
      unsigned int            clock;          /* Current clock (MHz) */
+     unsigned int            old_clock;      /* Old clock (MHz) */
+     unsigned int            clk_cnt;        /* Clock user count */
      u8                      pwr;            /* Current voltage */
 
      struct mmc_request      *mrq;           /* Current request */
@@ -323,6 +325,8 @@ 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             (*enable)(struct sdhci_host *host);
+     int             (*disable)(struct sdhci_host *host, int lazy);
 };
 
Quoted 4 lines

drivers/mmc/host/sdhci.h struct sdhci_ops { · line 332

Quoted 1 line
drivers/mmc/host/sdhci.h +0 -0
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

I could have misunderstood something, but do you really need this new 'old_clock' member? Is the previous clock value not stored in host->ios.clock?

Quoted 8 lines

Thanks Matt for your comment.
if host->ios.clock set zero, i think that need previous value (for example 52MHz..)
So i add 'old_clock' member...i will test, after removed 'old_clock'

anyother doubt? and problem?
Thanks

Hi Chris.
I want to know how do you think about this patch. If you have any doubt in this patch, let me know plz.

Thanks
Jaehoon Chung

#4 lore raw
In reply to Jaehoon Chung

Hi Jaehoon/Adrian,

Quoted 8 lines · Jaehoon Chung

Hi all,
This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
(using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

A few points:
* Have you tested this patch? Did you see a decrease in power consumption? How large was the decrease?
* I don't understand exactly how/when you're expecting to save power with this approach of defining .{enable,disable}() without then calling them from your driver code. Under which circumstances do you think this will power down the clock?
* CC'ing Adrian for help with review, since he wrote these callbacks.

Thanks,

- Chris.

Quoted 134 lines

Thank you all

---
 drivers/mmc/host/sdhci-s3c.c |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.c     |   30 ++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci.h     |    4 ++++
 3 files changed, 70 insertions(+), 0 deletions(-)
drivers/mmc/host/sdhci-s3c.c +36 -0
index 71ad416..9b430fb 100644
@@ -47,6 +47,7 @@ struct sdhci_s3c {
 	unsigned int		cur_clk;
 	int			ext_cd_irq;
 	int			ext_cd_gpio;
+	int			flag;
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
@@ -232,10 +233,45 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
 	return min;
 }
 
+static int sdhci_s3c_enable_clk(struct sdhci_host *host)
+{
+	struct sdhci_s3c *sc = to_s3c(host);
+
+	if (sc->flag != 1) {
+		clk_disable(sc->clk_io);
+		clk_disable(sc->clk_bus[sc->cur_clk]);
+	}
+
+	if (sc->host->clk_cnt == 0) {
+		clk_enable(sc->clk_io);
+		clk_enable(sc->clk_bus[sc->cur_clk]);
+		sc->host->clk_cnt++;
+		sc->flag = 1;
+	}
+
+	return 0;
+}
+
+static int sdhci_s3c_disable_clk(struct sdhci_host *host, int lazy)
+{
+	struct sdhci_s3c *sc = to_s3c(host);
+
+	if (sc->host->clk_cnt) {
+		clk_disable(sc->clk_io);
+		clk_disable(sc->clk_bus[sc->cur_clk]);
+		if (sc->host->clk_cnt)
+			sc->host->clk_cnt--;
+	}
+
+	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,
+	.enable			= sdhci_s3c_enable_clk,
+	.disable		= sdhci_s3c_disable_clk,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
drivers/mmc/host/sdhci.c +30 -0
index 401527d..fa2e55d 100644
@@ -1245,7 +1245,37 @@ out:
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_enable_clk(struct mmc_host *mmc)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->old_clock != 0 && host->clock == 0) {
+		if (host->ops->enable)
+			ret = host->ops->enable(host);
+		sdhci_set_clock(host, host->old_clock);
+	}
+
+	return ret;
+}
+
+static int sdhci_disable_clk(struct mmc_host *mmc, int lazy)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	if (host->clock != 0) {
+		host->old_clock = host->clock;
+		sdhci_set_clock(host, 0);
+		if (host->ops->disable)
+			ret = host->ops->disable(host, lazy);
+	}
+	return ret;
+}
+
 static const struct mmc_host_ops sdhci_ops = {
+	.enable		= sdhci_enable_clk,
+	.disable	= sdhci_disable_clk,
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
drivers/mmc/host/sdhci.h +4 -1
index d316bc7..0c6f143 100644
@@ -278,6 +278,8 @@ struct sdhci_host {
 	unsigned int		timeout_clk;	/* Timeout freq (KHz) */
 
 	unsigned int		clock;		/* Current clock (MHz) */
+	unsigned int		old_clock;	/* Old clock (MHz) */
+	unsigned int		clk_cnt;	/* Clock user count */
 	u8			pwr;		/* Current voltage */
 
 	struct mmc_request	*mrq;		/* Current request */
@@ -323,6 +325,8 @@ 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		(*enable)(struct sdhci_host *host);
+	int		(*disable)(struct sdhci_host *host, int lazy);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
-- 1.6.0.4 
Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
#5 lore raw
Quoted 12 lines · Chris Ball

Hi Jaehoon/Adrian,

Quoted 8 lines · Jaehoon Chung

Hi all,
This is a RFC patch that support clock-gating for saving power consumption. I found mmc_host_enable/mmc_host_disable function in core.c
(using MMC_CAP_DSIABLE. i think that use when host enable/disable) So, i used that functions and implemented some functions in sdhci-s3c.c & sdhci.c

i want any feedback. how do you think about this patch? Plz let me know...

Quoted 8 lines

A few points:
* Have you tested this patch? Did you see a decrease in power consumption? How large was the decrease?
* I don't understand exactly how/when you're expecting to save power with this approach of defining .{enable,disable}() without then calling them from your driver code. Under which circumstances do you think this will power down the clock?
* CC'ing Adrian for help with review, since he wrote these callbacks.

As I already said here:

	http://article.gmane.org/gmane.linux.ports.arm.omap/39411

I find those callbacks rather problematic. Currently, mmc_host_disable() is called by the host driver (currently OMAP) and that's wrong. Such decision cannot be made in the controller driver -- it has to be made higher up the stack.

Nicolas

#6 lore raw

Hi,

Quoted 8 lines · Nicolas Pitre

As I already said here:

	http://article.gmane.org/gmane.linux.ports.arm.omap/39411

I find those callbacks rather problematic. Currently, mmc_host_disable() is called by the host driver (currently OMAP) and that's wrong. Such decision cannot be made in the controller driver -- it has to be made higher up the stack.

I strongly agree. I hadn't noticed that aspect of this design until today. It looked like Linus W had a nice core-integrated clocking framework almost ready to go a year ago, but it lost out. (Something left to do was to give extra time after a request in case we're on a broken card which requires the card clock to be present during its writeback.)

I'm not sure where to go from here -- advice welcome. It would perhaps be ideal if Linus W and Adrian could work together to make the current framework look more like Linus' original intent and then move omap_hsmmc to it as painlessly as possible. Of course I wouldn't expect this to happen quickly.

In the meantime, I would suggest that we should not accept any more users of this framework, which would be a NACK to Jaehoon's patch (which appears to my reading not to achieve any power-saving anyway).

Adrian, I'm sorry that I'm suggesting reverting -- or at least strongly modifying -- a framework after it's already shipped in a release; if you think this is unreasonable, I'll consider your argument carefully.

Thanks,

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
#7 lore raw
Quoted 12 lines · Chris Ball

Hi,

Quoted 8 lines · Nicolas Pitre

As I already said here:

      http://article.gmane.org/gmane.linux.ports.arm.omap/39411

I find those callbacks rather problematic.  Currently, mmc_host_disable() is called by the host driver (currently OMAP) and that's wrong.  Such decision cannot be made in the controller driver -- it has to be made higher up the stack.

Quoted 6 lines

I strongly agree.  I hadn't noticed that aspect of this design until today.  It looked like Linus W had a nice core-integrated clocking framework almost ready to go a year ago, but it lost out.  (Something left to do was to give extra time after a request in case we're on a broken card which requires the card clock to be present during its writeback.)

Do you mean this one?
http://www.mail-archive.com/[email protected]/msg01883.html

In previous time it used for our kernel and find it's difficult to handle and maintain and can't support the SD card.
So try to find another method and implemente it at SDHCI drivers.

Quoted 10 lines

I'm not sure where to go from here -- advice welcome.  It would perhaps be ideal if Linus W and Adrian could work together to make the current framework look more like Linus' original intent and then move omap_hsmmc to it as painlessly as possible.  Of course I wouldn't expect this to happen quickly.

In the meantime, I would suggest that we should not accept any more users of this framework, which would be a NACK to Jaehoon's patch (which appears to my reading not to achieve any power-saving anyway).

No, In our case it deduce the about 10mA. so it's mandatory and basic functionality to reduce the power.

Thank you,
Kyungmin Park

Quoted 15 lines

Adrian, I'm sorry that I'm suggesting reverting -- or at least strongly modifying -- a framework after it's already shipped in a release; if you think this is unreasonable, I'll consider your argument carefully.

Thanks,

--
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

#8 lore raw

2010/9/30 Kyungmin Park <[email protected]>:

Quoted 20 lines · Chris Ball
Quoted 12 lines

Hi,

Quoted 8 lines · Nicolas Pitre

As I already said here:

      http://article.gmane.org/gmane.linux.ports.arm.omap/39411

I find those callbacks rather problematic.  Currently, mmc_host_disable() is called by the host driver (currently OMAP) and that's wrong.  Such decision cannot be made in the controller driver -- it has to be made higher up the stack.

Quoted 6 lines

I strongly agree.  I hadn't noticed that aspect of this design until today.  It looked like Linus W had a nice core-integrated clocking framework almost ready to go a year ago, but it lost out.  (Something left to do was to give extra time after a request in case we're on a broken card which requires the card clock to be present during its writeback.)

Quoted 2 lines

Do you mean this one?
http://www.mail-archive.com/[email protected]/msg01883.html

That's it. If there is interest I can surely pick it up and wrap the current enable/disable calls around it or even rewrite all drivers to use the set_ios() approach as in this patchset I think.

What happened was that I had this iterated a few times as Pierre was getting increasingly overloaded and it was on the verge of merging when he resigned as MMC maintainer.

The next week or so the big hammer callbacks from OMAP were merged as part of their mainline procedure.

Quoted 3 lines

In previous time it used for our kernel and find it's difficult to handle and maintain and can't support the SD card.
So try to find another method and implemente it at SDHCI drivers.

Why? The only difference between this solution and the one that is inside the kernel now is that this will use set_ios() with a zero argument to gate off the clock after a timeout instead of special callbacks. (A features especially requested by Pierre.)

I can move the timeing code to wrap the current callbacks instead atleast that would make things more according to spec.

For MMC cards that is.

For SD cards IIRC the spec is the same, but in practice all SD cards (and especially all MicroSD and eMMCs we see these days) survive gating the clock off like these current callbacks do. That I believe is why people have so little trouble with the present code.

Yours,
Linus Walleij

#9 lore raw
Quoted 7 lines · Linus Walleij

2010/9/30 Kyungmin Park <[email protected]>:

Quoted 1 line

So try to find another method and implemente it at SDHCI drivers.

Why? The only difference between this solution and the one that is inside the kernel now is that this will use set_ios() with a zero argument to gate off the clock after a timeout instead of special callbacks. (A features especially requested by Pierre.)

Good! I didn't look at your solution before, but in my mind that always been how it should be done.

Nicolas

#10 lore raw
In reply to Linus Walleij

Hi Linus,

Quoted 8 lines · Linus Walleij

That's it. If there is interest I can surely pick it up and wrap the current enable/disable calls around it or even rewrite all drivers to use the set_ios() approach as in this patchset I think.

What happened was that I had this iterated a few times as Pierre was getting increasingly overloaded and it was on the verge of merging when he resigned as MMC maintainer.

Quoted 5 lines

The next week or so the big hammer callbacks from OMAP were merged as part of their mainline procedure.

I can move the timeing code to wrap the current callbacks instead atleast that would make things more according to spec.

Sounds excellent. Thank you!

There are a few groups to keep in touch with on this:

* The omap_hsmmc folks, of course
* Ohad Ben-Cohen has SDIO runtime PM patches¹, which I think should be merged
* Kevin Hilman is working on converting omap_hsmmc over to runtime PM²
* Matthew Garrett is working on a patch to power down unused SDHCI devices using runtime PM

- Chris.

¹: http://thread.gmane.org/gmane.linux.kernel.mmc/3968
²: http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=shortlog;h=refs/heads/pm-wip/mmc

Signature · 2 lines
Chris Ball   <[email protected]>   <http://printf.net/>
One Laptop Per Child