From 911b448d4b528c403f973f9e5aa34be94bffaf1e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Wed, 30 Jul 2008 14:37:01 +0100 Subject: [PATCH] add-glamo-mci-slower-clocking-dynamic-switching.patch 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 --- drivers/mfd/glamo/glamo-core.c | 2 ++ drivers/mfd/glamo/glamo-core.h | 2 ++ drivers/mfd/glamo/glamo-mci.c | 30 ++++++++++++++++++++++++++++-- include/linux/glamofb.h | 2 ++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c index cb9b056..0e7a650 100644 --- a/drivers/mfd/glamo/glamo-core.c +++ b/drivers/mfd/glamo/glamo-core.c @@ -1116,6 +1116,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 = diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h index c89f810..dd6f67c 100644 --- a/drivers/mfd/glamo/glamo-core.h +++ b/drivers/mfd/glamo/glamo-core.h @@ -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 *dev); diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c index 7a2b060..d34632a 100644 --- a/drivers/mfd/glamo/glamo-mci.c +++ b/drivers/mfd/glamo/glamo-mci.c @@ -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; diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h index bb1a398..ca63355 100644 --- a/include/linux/glamofb.h +++ b/include/linux/glamofb.h @@ -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 *dev); -- 1.5.6.3