diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1322-fix-gta01-s3c-mci-stop-clock-when-idle.patch.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1322-fix-gta01-s3c-mci-stop-clock-when-idle.patch.patch | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1322-fix-gta01-s3c-mci-stop-clock-when-idle.patch.patch b/target/linux/s3c24xx/patches-2.6.24/1322-fix-gta01-s3c-mci-stop-clock-when-idle.patch.patch deleted file mode 100644 index 7717199..0000000 --- a/target/linux/s3c24xx/patches-2.6.24/1322-fix-gta01-s3c-mci-stop-clock-when-idle.patch.patch +++ /dev/null @@ -1,211 +0,0 @@ -From ff31834cfaac386f94ddd65fab8b87d090c69bcc Mon Sep 17 00:00:00 2001 -From: Mike Westerhof <mwester@dls.net> -Date: Thu, 13 Nov 2008 20:38:35 +0000 -Subject: [PATCH] fix-gta01-s3c-mci-stop-clock-when-idle.patch - -This patch, based on the work done by Andy Green for the Glamo mci -driver, makes sure that the SD clock only runs during data transfers. -This can be overridden on the kernel command line if desired. Also -added is the ability for the maximum SD clock speed to be limited. - -Signed-off-by: Mike Westerhof (mwester@dls.net) ---- - drivers/mmc/host/s3cmci.c | 113 +++++++++++++++++++++++++++++++++++++++++++-- - 1 files changed, 109 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c -index edba055..8f88721 100644 ---- a/drivers/mmc/host/s3cmci.c -+++ b/drivers/mmc/host/s3cmci.c -@@ -15,6 +15,8 @@ - #include <linux/mmc/host.h> - #include <linux/platform_device.h> - #include <linux/irq.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> - - #include <asm/dma.h> - #include <asm/dma-mapping.h> -@@ -29,6 +31,37 @@ - - #define DRIVER_NAME "s3c-mci" - -+static spinlock_t clock_lock; -+ -+/* -+ * Max SD clock rate (in Hz) -+ * -+ * you can override this on the kernel command line using -+ * -+ * s3cmci.sd_max_clk=10000000 -+ * -+ * for example. -+ */ -+ -+static int sd_max_clk = 25000000; -+module_param(sd_max_clk, int, 0644); -+ -+/* -+ * SD allow SD clock to run while idle -+ * -+ * you can override this on kernel commandline using -+ * -+ * s3cmci.sd_idleclk=0 -+ * -+ * for example. -+ */ -+ -+static int sd_idleclk; /* disallow idle clock by default */ -+module_param(sd_idleclk, int, 0644); -+ -+/* used to stash real idleclk state in suspend: we force it to run in there */ -+static int suspend_sd_idleclk; -+ - enum dbg_channels { - dbg_err = (1 << 0), - dbg_debug = (1 << 1), -@@ -368,6 +401,40 @@ static void pio_tasklet(unsigned long data) - enable_irq(host->irq); - } - -+static void __s3cmci_enable_clock(struct s3cmci_host *host) -+{ -+ u32 mci_con; -+ unsigned long flags; -+ -+ /* enable the clock if clock rate is > 0 */ -+ if (host->real_rate) { -+ spin_lock_irqsave(&clock_lock, flags); -+ -+ mci_con = readl(host->base + S3C2410_SDICON); -+ mci_con |= S3C2410_SDICON_CLOCKTYPE; -+ writel(mci_con, host->base + S3C2410_SDICON); -+ -+ spin_unlock_irqrestore(&clock_lock, flags); -+ } -+} -+ -+static void __s3cmci_disable_clock(struct s3cmci_host *host) -+{ -+ u32 mci_con; -+ unsigned long flags; -+ -+ if (!sd_idleclk) { -+ spin_lock_irqsave(&clock_lock, flags); -+ -+ mci_con = readl(host->base + S3C2410_SDICON); -+ mci_con &= ~S3C2410_SDICON_CLOCKTYPE; -+ writel(mci_con, host->base + S3C2410_SDICON); -+ -+ spin_unlock_irqrestore(&clock_lock, flags); -+ } -+} -+ -+ - /* - * ISR for SDI Interface IRQ - * Communication between driver and ISR works as follows: -@@ -749,6 +816,7 @@ static void finalize_request(struct s3cmci_host *host) - } - - request_done: -+ __s3cmci_disable_clock(host); - host->complete_what = COMPLETION_NONE; - host->mrq = NULL; - mmc_request_done(host->mmc, mrq); -@@ -1005,6 +1073,7 @@ static void s3cmci_send_request(struct mmc_host *mmc) - - } - -+ __s3cmci_enable_clock(host); - s3cmci_send_command(host, cmd); - enable_irq(host->irq); - } -@@ -1087,14 +1156,30 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - if ((ios->power_mode == MMC_POWER_ON) - || (ios->power_mode == MMC_POWER_UP)) { - -- dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n", -- host->real_rate/1000, ios->clock/1000); -+ dbg(host, dbg_conf, -+ "powered (vdd: %d), clk: %lukHz div=%lu (req: %ukHz)," -+ " bus width: %d\n", ios->vdd, host->real_rate / 1000, -+ host->clk_div * (host->prescaler + 1), -+ ios->clock / 1000, ios->bus_width); -+ -+ /* After power-up, we need to give the card 74 clocks to -+ * initialize, so sleep just a moment before we disable -+ * the clock again. -+ */ -+ if (ios->clock) -+ msleep(1); -+ - } else { - dbg(host, dbg_conf, "powered down.\n"); - } - - host->bus_width = ios->bus_width; - -+ /* No need to run the clock until we have data to move */ -+ if (!sd_idleclk) { -+ __s3cmci_disable_clock(host); -+ dbg(host, dbg_conf, "SD clock disabled when idle.\n"); -+ } - } - - static void s3cmci_reset(struct s3cmci_host *host) -@@ -1267,7 +1352,7 @@ static int s3cmci_probe(struct platform_device *pdev, int is2440) - mmc->ocr_avail = host->pdata->ocr_avail; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; - mmc->f_min = host->clk_rate / (host->clk_div * 256); -- mmc->f_max = host->clk_rate / host->clk_div; -+ mmc->f_max = sd_max_clk; - - mmc->max_blk_count = 4095; - mmc->max_blk_size = 4095; -@@ -1354,14 +1439,33 @@ static int s3cmci_probe_2440(struct platform_device *dev) - static int s3cmci_suspend(struct platform_device *dev, pm_message_t state) - { - struct mmc_host *mmc = platform_get_drvdata(dev); -+ struct s3cmci_host *host = mmc_priv(mmc); -+ int ret; -+ -+ /* Ensure clock is running so it will be running on resume */ -+ __s3cmci_enable_clock(host); - -- return mmc_suspend_host(mmc, state); -+ /* We will do more commands, make sure the clock stays running, -+ * and save our state so that we can restore it on resume. -+ */ -+ suspend_sd_idleclk = sd_idleclk; -+ sd_idleclk = 1; -+ -+ ret = mmc_suspend_host(mmc, state); -+ -+ /* so that when we resume, we use any modified max rate */ -+ mmc->f_max = sd_max_clk; -+ -+ return ret; - } - - static int s3cmci_resume(struct platform_device *dev) - { - struct mmc_host *mmc = platform_get_drvdata(dev); - -+ /* Put the sd_idleclk state back to what it was */ -+ sd_idleclk = suspend_sd_idleclk; -+ - return mmc_resume_host(mmc); - } - -@@ -1398,6 +1502,7 @@ static struct platform_driver s3cmci_driver_2440 = { - - static int __init s3cmci_init(void) - { -+ spin_lock_init(&clock_lock); - platform_driver_register(&s3cmci_driver_2410); - platform_driver_register(&s3cmci_driver_2412); - platform_driver_register(&s3cmci_driver_2440); --- -1.5.6.5 - |