add-glamo-mci-slower-clocking-dynamic-switching.patch
authorAndy Green <andy@openmoko.com>
Wed, 30 Jul 2008 11:46:44 +0000 (12:46 +0100)
committerAndy Green <agreen@pads.home.warmcat.com>
Wed, 30 Jul 2008 11:46:44 +0000 (12:46 +0100)
This patch gives glamo-mci a concept of a platform-defined
dynamic clock slowing callback.  It means that platform code
can associate some completely external state to decide if
we run the SD clock at normal rate or a rate divided by a
module parameter "sd_slow_ratio", which you can set on
kernel commandline like this:

glamo_mci.sd_slow_ratio=8

you can also change it at runtime by

echo 8 > /sys/module/glamo_mci/parameters/sd_slow_ratio

If no platform callback is defined, then no slow mode
is used.  If it is defined, then the default division
action is / 8, eg, 16MHz normal -> 2MHz slow mode.

Signed-off-by: Andy Green <andy@openmoko.com>

drivers/mfd/glamo/glamo-core.c
drivers/mfd/glamo/glamo-core.h
drivers/mfd/glamo/glamo-mci.c
include/linux/glamofb.h

index f411446..c094a8c 100644 (file)
@@ -1114,6 +1114,8 @@ static int __init glamo_probe(struct platform_device *pdev)
        /* bring MCI specific stuff over from our MFD platform data */
        glamo_mci_def_pdata.glamo_set_mci_power =
                                        glamo->pdata->glamo_set_mci_power;
+       glamo_mci_def_pdata.glamo_mci_use_slow =
+                                       glamo->pdata->glamo_mci_use_slow;
        glamo_mci_def_pdata.glamo_irq_is_wired =
                                        glamo->pdata->glamo_irq_is_wired;
        glamo_mci_def_pdata.mci_suspending =
index 8d647ec..d3f4309 100644 (file)
@@ -72,6 +72,8 @@ struct glamo_mci_pdata {
        unsigned long   ocr_avail;
        void            (*glamo_set_mci_power)(unsigned char power_mode,
                                     unsigned short vdd);
+       /* glamo-mci asking if it should use the slow clock to card */
+       int             (*glamo_mci_use_slow)(void);
        int             (*glamo_irq_is_wired)(void);
        void            (*mci_suspending)(struct platform_device *dev);
        int             (*mci_all_dependencies_resumed)(struct platform_device
index 54ba613..577021e 100644 (file)
@@ -57,6 +57,23 @@ static int sd_max_clk = 50000000 / 3;
 module_param(sd_max_clk, int, 0644);
 
 /*
+ * Slow SD clock rate
+ *
+ * you can override this on kernel commandline using
+ *
+ *   glamo_mci.sd_slow_ratio=8
+ *
+ * for example
+ *
+ * platform callback is used to decide effective clock rate, if not
+ * defined then max is used, if defined and returns nonzero, rate is
+ * divided by this factor
+ */
+
+static int sd_slow_ratio = 8;
+module_param(sd_slow_ratio, int, 0644);
+
+/*
  * SD Signal drive strength
  *
  * you can override this on kernel commandline using
@@ -554,8 +571,17 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
                 cmd->opcode, cmd->arg, cmd->data, cmd->mrq->stop,
                 cmd->flags);
 
-       /* resume requested clock rate */
-       __glamo_mci_fix_card_div(host, host->clk_div);
+       /* resume requested clock rate
+        * scale it down by sd_slow_ratio if platform requests it
+        */
+       if (host->pdata->glamo_mci_use_slow)
+               if ((host->pdata->glamo_mci_use_slow)())
+                       __glamo_mci_fix_card_div(host, host->clk_div *
+                                                                sd_slow_ratio);
+               else
+                       __glamo_mci_fix_card_div(host, host->clk_div);
+       else
+               __glamo_mci_fix_card_div(host, host->clk_div);
 
        if (glamo_mci_send_command(host, cmd))
                goto bail;
index efd315b..b101e9c 100644 (file)
@@ -31,6 +31,8 @@ struct glamofb_platform_data {
        /* glamo mmc platform specific info */
        void            (*glamo_set_mci_power)(unsigned char power_mode,
                                     unsigned short vdd);
+       /* glamo-mci asking if it should use the slow clock to card */
+       int             (*glamo_mci_use_slow)(void);
        int             (*glamo_irq_is_wired)(void);
        void            (*mci_suspending)(struct platform_device *dev);
        int             (*mci_all_dependencies_resumed)(struct platform_device