diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2009-06-04 14:12:31 -0400 |
---|---|---|
committer | Pierre Ossman <pierre@ossman.eu> | 2009-06-13 16:42:59 -0400 |
commit | f0e46cc4971f6be96010d9248e0fc076b229d989 (patch) | |
tree | 5fc0b80993c82337b8928f063df0749fadc9d13e | |
parent | fdd858db7113ca64132de390188d7ca00701013d (diff) |
MFD,mmc: tmio_mmc: make HCLK configurable
The Toshiba parts all have a 24 MHz HCLK, but HTC ASIC3 has a 24.576 MHz HCLK
and AMD Imageon w228x's HCLK is 80 MHz. With this patch, the MFD driver
provides the HCLK frequency to tmio_mmc via mfd_cell->driver_data.
Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Acked-by: Ian Molton <ian@mnementh.co.uk>
Acked-by: Samuel Ortiz <sameo@openedhand.com>
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
-rw-r--r-- | drivers/mfd/t7l66xb.c | 5 | ||||
-rw-r--r-- | drivers/mfd/tc6387xb.c | 5 | ||||
-rw-r--r-- | drivers/mfd/tc6393xb.c | 5 | ||||
-rw-r--r-- | drivers/mmc/host/tmio_mmc.c | 24 | ||||
-rw-r--r-- | include/linux/mfd/tmio.h | 7 |
5 files changed, 33 insertions, 13 deletions
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index e9f4323dd2cb..875f7a875734 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -108,6 +108,10 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc) | |||
108 | 108 | ||
109 | /*--------------------------------------------------------------------------*/ | 109 | /*--------------------------------------------------------------------------*/ |
110 | 110 | ||
111 | static const struct tmio_mmc_data t7166xb_mmc_data = { | ||
112 | .hclk = 24000000, | ||
113 | }; | ||
114 | |||
111 | static const struct resource t7l66xb_mmc_resources[] = { | 115 | static const struct resource t7l66xb_mmc_resources[] = { |
112 | { | 116 | { |
113 | .start = 0x800, | 117 | .start = 0x800, |
@@ -149,6 +153,7 @@ static struct mfd_cell t7l66xb_cells[] = { | |||
149 | .name = "tmio-mmc", | 153 | .name = "tmio-mmc", |
150 | .enable = t7l66xb_mmc_enable, | 154 | .enable = t7l66xb_mmc_enable, |
151 | .disable = t7l66xb_mmc_disable, | 155 | .disable = t7l66xb_mmc_disable, |
156 | .driver_data = &t7166xb_mmc_data, | ||
152 | .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), | 157 | .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), |
153 | .resources = t7l66xb_mmc_resources, | 158 | .resources = t7l66xb_mmc_resources, |
154 | }, | 159 | }, |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index 43222c12fec1..c3993ac20542 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -75,6 +75,10 @@ static int tc6387xb_mmc_disable(struct platform_device *mmc) | |||
75 | 75 | ||
76 | /*--------------------------------------------------------------------------*/ | 76 | /*--------------------------------------------------------------------------*/ |
77 | 77 | ||
78 | const static struct tmio_mmc_data tc6387xb_mmc_data = { | ||
79 | .hclk = 24000000, | ||
80 | }; | ||
81 | |||
78 | static struct resource tc6387xb_mmc_resources[] = { | 82 | static struct resource tc6387xb_mmc_resources[] = { |
79 | { | 83 | { |
80 | .start = 0x800, | 84 | .start = 0x800, |
@@ -98,6 +102,7 @@ static struct mfd_cell tc6387xb_cells[] = { | |||
98 | .name = "tmio-mmc", | 102 | .name = "tmio-mmc", |
99 | .enable = tc6387xb_mmc_enable, | 103 | .enable = tc6387xb_mmc_enable, |
100 | .disable = tc6387xb_mmc_disable, | 104 | .disable = tc6387xb_mmc_disable, |
105 | .driver_data = &tc6387xb_mmc_data, | ||
101 | .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), | 106 | .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), |
102 | .resources = tc6387xb_mmc_resources, | 107 | .resources = tc6387xb_mmc_resources, |
103 | }, | 108 | }, |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 77a12fc8045e..9d2abb5d6e2c 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -136,6 +136,10 @@ static int tc6393xb_nand_enable(struct platform_device *nand) | |||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | const static struct tmio_mmc_data tc6393xb_mmc_data = { | ||
140 | .hclk = 24000000, | ||
141 | }; | ||
142 | |||
139 | static struct resource __devinitdata tc6393xb_nand_resources[] = { | 143 | static struct resource __devinitdata tc6393xb_nand_resources[] = { |
140 | { | 144 | { |
141 | .start = 0x1000, | 145 | .start = 0x1000, |
@@ -351,6 +355,7 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
351 | }, | 355 | }, |
352 | [TC6393XB_CELL_MMC] = { | 356 | [TC6393XB_CELL_MMC] = { |
353 | .name = "tmio-mmc", | 357 | .name = "tmio-mmc", |
358 | .driver_data = &tc6393xb_mmc_data, | ||
354 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), | 359 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), |
355 | .resources = tc6393xb_mmc_resources, | 360 | .resources = tc6393xb_mmc_resources, |
356 | }, | 361 | }, |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 63fbd5b7d312..49df71e6be17 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -35,23 +35,14 @@ | |||
35 | 35 | ||
36 | #include "tmio_mmc.h" | 36 | #include "tmio_mmc.h" |
37 | 37 | ||
38 | /* | ||
39 | * Fixme - documentation conflicts on what the clock values are for the | ||
40 | * various dividers. | ||
41 | * One document I have says that its a divisor of a 24MHz clock, another 33. | ||
42 | * This probably depends on HCLK for a given platform, so we may need to | ||
43 | * require HCLK be passed to us from the MFD core. | ||
44 | * | ||
45 | */ | ||
46 | |||
47 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) | 38 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) |
48 | { | 39 | { |
49 | void __iomem *cnf = host->cnf; | 40 | void __iomem *cnf = host->cnf; |
50 | void __iomem *ctl = host->ctl; | 41 | void __iomem *ctl = host->ctl; |
51 | u32 clk = 0, clock; | 42 | u32 clk = 0, clock, f_min = host->mmc->f_min; |
52 | 43 | ||
53 | if (new_clock) { | 44 | if (new_clock) { |
54 | for (clock = 46875, clk = 0x100; new_clock >= (clock<<1); ) { | 45 | for (clock = f_min, clk = 0x100; new_clock >= (clock<<1); ) { |
55 | clock <<= 1; | 46 | clock <<= 1; |
56 | clk >>= 1; | 47 | clk >>= 1; |
57 | } | 48 | } |
@@ -545,6 +536,7 @@ out: | |||
545 | static int __devinit tmio_mmc_probe(struct platform_device *dev) | 536 | static int __devinit tmio_mmc_probe(struct platform_device *dev) |
546 | { | 537 | { |
547 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | 538 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; |
539 | struct tmio_mmc_data *pdata; | ||
548 | struct resource *res_ctl, *res_cnf; | 540 | struct resource *res_ctl, *res_cnf; |
549 | struct tmio_mmc_host *host; | 541 | struct tmio_mmc_host *host; |
550 | struct mmc_host *mmc; | 542 | struct mmc_host *mmc; |
@@ -560,6 +552,12 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
560 | goto out; | 552 | goto out; |
561 | } | 553 | } |
562 | 554 | ||
555 | pdata = cell->driver_data; | ||
556 | if (!pdata || !pdata->hclk) { | ||
557 | ret = -EINVAL; | ||
558 | goto out; | ||
559 | } | ||
560 | |||
563 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); | 561 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev); |
564 | if (!mmc) | 562 | if (!mmc) |
565 | goto out; | 563 | goto out; |
@@ -578,8 +576,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
578 | 576 | ||
579 | mmc->ops = &tmio_mmc_ops; | 577 | mmc->ops = &tmio_mmc_ops; |
580 | mmc->caps = MMC_CAP_4_BIT_DATA; | 578 | mmc->caps = MMC_CAP_4_BIT_DATA; |
581 | mmc->f_min = 46875; /* 24000000 / 512 */ | 579 | mmc->f_max = pdata->hclk; |
582 | mmc->f_max = 24000000; | 580 | mmc->f_min = mmc->f_max / 512; |
583 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 581 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
584 | 582 | ||
585 | /* Enable the MMC/SD Control registers */ | 583 | /* Enable the MMC/SD Control registers */ |
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 516d955ab8a1..c377118884e6 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h | |||
@@ -19,6 +19,13 @@ | |||
19 | } while (0) | 19 | } while (0) |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * data for the MMC controller | ||
23 | */ | ||
24 | struct tmio_mmc_data { | ||
25 | unsigned int hclk; | ||
26 | }; | ||
27 | |||
28 | /* | ||
22 | * data for the NAND controller | 29 | * data for the NAND controller |
23 | */ | 30 | */ |
24 | struct tmio_nand_data { | 31 | struct tmio_nand_data { |