mmc: sdhci-s3c: Remove usage of clk_type member in platform data
[pandora-kernel.git] / drivers / mmc / host / sdhci-s3c.c
1 /* linux/drivers/mmc/host/sdhci-s3c.c
2  *
3  * Copyright 2008 Openmoko Inc.
4  * Copyright 2008 Simtec Electronics
5  *      Ben Dooks <ben@simtec.co.uk>
6  *      http://armlinux.simtec.co.uk/
7  *
8  * SDHCI (HSMMC) support for Samsung SoC
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/delay.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include <linux/clk.h>
20 #include <linux/io.h>
21 #include <linux/gpio.h>
22 #include <linux/module.h>
23
24 #include <linux/mmc/host.h>
25
26 #include <plat/sdhci.h>
27 #include <plat/regs-sdhci.h>
28
29 #include "sdhci.h"
30
31 #define MAX_BUS_CLK     (4)
32
33 /**
34  * struct sdhci_s3c - S3C SDHCI instance
35  * @host: The SDHCI host created
36  * @pdev: The platform device we where created from.
37  * @ioarea: The resource created when we claimed the IO area.
38  * @pdata: The platform data for this controller.
39  * @cur_clk: The index of the current bus clock.
40  * @clk_io: The clock for the internal bus interface.
41  * @clk_bus: The clocks that are available for the SD/MMC bus clock.
42  */
43 struct sdhci_s3c {
44         struct sdhci_host       *host;
45         struct platform_device  *pdev;
46         struct resource         *ioarea;
47         struct s3c_sdhci_platdata *pdata;
48         unsigned int            cur_clk;
49         int                     ext_cd_irq;
50         int                     ext_cd_gpio;
51
52         struct clk              *clk_io;
53         struct clk              *clk_bus[MAX_BUS_CLK];
54 };
55
56 /**
57  * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data
58  * @sdhci_quirks: sdhci host specific quirks.
59  *
60  * Specifies platform specific configuration of sdhci controller.
61  * Note: A structure for driver specific platform data is used for future
62  * expansion of its usage.
63  */
64 struct sdhci_s3c_drv_data {
65         unsigned int    sdhci_quirks;
66 };
67
68 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
69 {
70         return sdhci_priv(host);
71 }
72
73 /**
74  * get_curclk - convert ctrl2 register to clock source number
75  * @ctrl2: Control2 register value.
76  */
77 static u32 get_curclk(u32 ctrl2)
78 {
79         ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
80         ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
81
82         return ctrl2;
83 }
84
85 static void sdhci_s3c_check_sclk(struct sdhci_host *host)
86 {
87         struct sdhci_s3c *ourhost = to_s3c(host);
88         u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
89
90         if (get_curclk(tmp) != ourhost->cur_clk) {
91                 dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n");
92
93                 tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
94                 tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
95                 writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2);
96         }
97 }
98
99 /**
100  * sdhci_s3c_get_max_clk - callback to get maximum clock frequency.
101  * @host: The SDHCI host instance.
102  *
103  * Callback to return the maximum clock rate acheivable by the controller.
104 */
105 static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
106 {
107         struct sdhci_s3c *ourhost = to_s3c(host);
108         struct clk *busclk;
109         unsigned int rate, max;
110         int clk;
111
112         /* note, a reset will reset the clock source */
113
114         sdhci_s3c_check_sclk(host);
115
116         for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) {
117                 busclk = ourhost->clk_bus[clk];
118                 if (!busclk)
119                         continue;
120
121                 rate = clk_get_rate(busclk);
122                 if (rate > max)
123                         max = rate;
124         }
125
126         return max;
127 }
128
129 /**
130  * sdhci_s3c_consider_clock - consider one the bus clocks for current setting
131  * @ourhost: Our SDHCI instance.
132  * @src: The source clock index.
133  * @wanted: The clock frequency wanted.
134  */
135 static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
136                                              unsigned int src,
137                                              unsigned int wanted)
138 {
139         unsigned long rate;
140         struct clk *clksrc = ourhost->clk_bus[src];
141         int div;
142
143         if (!clksrc)
144                 return UINT_MAX;
145
146         /*
147          * If controller uses a non-standard clock division, find the best clock
148          * speed possible with selected clock source and skip the division.
149          */
150         if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
151                 rate = clk_round_rate(clksrc, wanted);
152                 return wanted - rate;
153         }
154
155         rate = clk_get_rate(clksrc);
156
157         for (div = 1; div < 256; div *= 2) {
158                 if ((rate / div) <= wanted)
159                         break;
160         }
161
162         dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
163                 src, rate, wanted, rate / div);
164
165         return (wanted - (rate / div));
166 }
167
168 /**
169  * sdhci_s3c_set_clock - callback on clock change
170  * @host: The SDHCI host being changed
171  * @clock: The clock rate being requested.
172  *
173  * When the card's clock is going to be changed, look at the new frequency
174  * and find the best clock source to go with it.
175 */
176 static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
177 {
178         struct sdhci_s3c *ourhost = to_s3c(host);
179         unsigned int best = UINT_MAX;
180         unsigned int delta;
181         int best_src = 0;
182         int src;
183         u32 ctrl;
184
185         /* don't bother if the clock is going off. */
186         if (clock == 0)
187                 return;
188
189         for (src = 0; src < MAX_BUS_CLK; src++) {
190                 delta = sdhci_s3c_consider_clock(ourhost, src, clock);
191                 if (delta < best) {
192                         best = delta;
193                         best_src = src;
194                 }
195         }
196
197         dev_dbg(&ourhost->pdev->dev,
198                 "selected source %d, clock %d, delta %d\n",
199                  best_src, clock, best);
200
201         /* select the new clock source */
202
203         if (ourhost->cur_clk != best_src) {
204                 struct clk *clk = ourhost->clk_bus[best_src];
205
206                 /* turn clock off to card before changing clock source */
207                 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
208
209                 ourhost->cur_clk = best_src;
210                 host->max_clk = clk_get_rate(clk);
211
212                 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
213                 ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
214                 ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
215                 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
216         }
217
218         /* reprogram default hardware configuration */
219         writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA,
220                 host->ioaddr + S3C64XX_SDHCI_CONTROL4);
221
222         ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
223         ctrl |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
224                   S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
225                   S3C_SDHCI_CTRL2_ENFBCLKRX |
226                   S3C_SDHCI_CTRL2_DFCNT_NONE |
227                   S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
228         writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
229
230         /* reconfigure the controller for new clock rate */
231         ctrl = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
232         if (clock < 25 * 1000000)
233                 ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
234         writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
235 }
236
237 /**
238  * sdhci_s3c_get_min_clock - callback to get minimal supported clock value
239  * @host: The SDHCI host being queried
240  *
241  * To init mmc host properly a minimal clock value is needed. For high system
242  * bus clock's values the standard formula gives values out of allowed range.
243  * The clock still can be set to lower values, if clock source other then
244  * system bus is selected.
245 */
246 static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
247 {
248         struct sdhci_s3c *ourhost = to_s3c(host);
249         unsigned int delta, min = UINT_MAX;
250         int src;
251
252         for (src = 0; src < MAX_BUS_CLK; src++) {
253                 delta = sdhci_s3c_consider_clock(ourhost, src, 0);
254                 if (delta == UINT_MAX)
255                         continue;
256                 /* delta is a negative value in this case */
257                 if (-delta < min)
258                         min = -delta;
259         }
260         return min;
261 }
262
263 /* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/
264 static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host)
265 {
266         struct sdhci_s3c *ourhost = to_s3c(host);
267
268         return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX);
269 }
270
271 /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */
272 static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
273 {
274         struct sdhci_s3c *ourhost = to_s3c(host);
275
276         /*
277          * initial clock can be in the frequency range of
278          * 100KHz-400KHz, so we set it as max value.
279          */
280         return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], 400000);
281 }
282
283 /* sdhci_cmu_set_clock - callback on clock change.*/
284 static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
285 {
286         struct sdhci_s3c *ourhost = to_s3c(host);
287         unsigned long timeout;
288         u16 clk = 0;
289
290         /* don't bother if the clock is going off */
291         if (clock == 0)
292                 return;
293
294         sdhci_s3c_set_clock(host, clock);
295
296         clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
297
298         host->clock = clock;
299
300         clk = SDHCI_CLOCK_INT_EN;
301         sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
302
303         /* Wait max 20 ms */
304         timeout = 20;
305         while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
306                 & SDHCI_CLOCK_INT_STABLE)) {
307                 if (timeout == 0) {
308                         printk(KERN_ERR "%s: Internal clock never "
309                                 "stabilised.\n", mmc_hostname(host->mmc));
310                         return;
311                 }
312                 timeout--;
313                 mdelay(1);
314         }
315
316         clk |= SDHCI_CLOCK_CARD_EN;
317         sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
318 }
319
320 /**
321  * sdhci_s3c_platform_8bit_width - support 8bit buswidth
322  * @host: The SDHCI host being queried
323  * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
324  *
325  * We have 8-bit width support but is not a v3 controller.
326  * So we add platform_8bit_width() and support 8bit width.
327  */
328 static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
329 {
330         u8 ctrl;
331
332         ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
333
334         switch (width) {
335         case MMC_BUS_WIDTH_8:
336                 ctrl |= SDHCI_CTRL_8BITBUS;
337                 ctrl &= ~SDHCI_CTRL_4BITBUS;
338                 break;
339         case MMC_BUS_WIDTH_4:
340                 ctrl |= SDHCI_CTRL_4BITBUS;
341                 ctrl &= ~SDHCI_CTRL_8BITBUS;
342                 break;
343         default:
344                 ctrl &= ~SDHCI_CTRL_4BITBUS;
345                 ctrl &= ~SDHCI_CTRL_8BITBUS;
346                 break;
347         }
348
349         sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
350
351         return 0;
352 }
353
354 static struct sdhci_ops sdhci_s3c_ops = {
355         .get_max_clock          = sdhci_s3c_get_max_clk,
356         .set_clock              = sdhci_s3c_set_clock,
357         .get_min_clock          = sdhci_s3c_get_min_clock,
358         .platform_8bit_width    = sdhci_s3c_platform_8bit_width,
359 };
360
361 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
362 {
363         struct sdhci_host *host = platform_get_drvdata(dev);
364         unsigned long flags;
365
366         if (host) {
367                 spin_lock_irqsave(&host->lock, flags);
368                 if (state) {
369                         dev_dbg(&dev->dev, "card inserted.\n");
370                         host->flags &= ~SDHCI_DEVICE_DEAD;
371                         host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
372                 } else {
373                         dev_dbg(&dev->dev, "card removed.\n");
374                         host->flags |= SDHCI_DEVICE_DEAD;
375                         host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
376                 }
377                 tasklet_schedule(&host->card_tasklet);
378                 spin_unlock_irqrestore(&host->lock, flags);
379         }
380 }
381
382 static irqreturn_t sdhci_s3c_gpio_card_detect_thread(int irq, void *dev_id)
383 {
384         struct sdhci_s3c *sc = dev_id;
385         int status = gpio_get_value(sc->ext_cd_gpio);
386         if (sc->pdata->ext_cd_gpio_invert)
387                 status = !status;
388         sdhci_s3c_notify_change(sc->pdev, status);
389         return IRQ_HANDLED;
390 }
391
392 static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
393 {
394         struct s3c_sdhci_platdata *pdata = sc->pdata;
395         struct device *dev = &sc->pdev->dev;
396
397         if (gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD") == 0) {
398                 sc->ext_cd_gpio = pdata->ext_cd_gpio;
399                 sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio);
400                 if (sc->ext_cd_irq &&
401                     request_threaded_irq(sc->ext_cd_irq, NULL,
402                                          sdhci_s3c_gpio_card_detect_thread,
403                                          IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
404                                          dev_name(dev), sc) == 0) {
405                         int status = gpio_get_value(sc->ext_cd_gpio);
406                         if (pdata->ext_cd_gpio_invert)
407                                 status = !status;
408                         sdhci_s3c_notify_change(sc->pdev, status);
409                 } else {
410                         dev_warn(dev, "cannot request irq for card detect\n");
411                         sc->ext_cd_irq = 0;
412                 }
413         } else {
414                 dev_err(dev, "cannot request gpio for card detect\n");
415         }
416 }
417
418 static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
419                         struct platform_device *pdev)
420 {
421         return (struct sdhci_s3c_drv_data *)
422                         platform_get_device_id(pdev)->driver_data;
423 }
424
425 static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
426 {
427         struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
428         struct sdhci_s3c_drv_data *drv_data;
429         struct device *dev = &pdev->dev;
430         struct sdhci_host *host;
431         struct sdhci_s3c *sc;
432         struct resource *res;
433         int ret, irq, ptr, clks;
434
435         if (!pdata) {
436                 dev_err(dev, "no device data specified\n");
437                 return -ENOENT;
438         }
439
440         irq = platform_get_irq(pdev, 0);
441         if (irq < 0) {
442                 dev_err(dev, "no irq specified\n");
443                 return irq;
444         }
445
446         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447         if (!res) {
448                 dev_err(dev, "no memory specified\n");
449                 return -ENOENT;
450         }
451
452         host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
453         if (IS_ERR(host)) {
454                 dev_err(dev, "sdhci_alloc_host() failed\n");
455                 return PTR_ERR(host);
456         }
457
458         drv_data = sdhci_s3c_get_driver_data(pdev);
459         sc = sdhci_priv(host);
460
461         sc->host = host;
462         sc->pdev = pdev;
463         sc->pdata = pdata;
464         sc->ext_cd_gpio = -1; /* invalid gpio number */
465
466         platform_set_drvdata(pdev, host);
467
468         sc->clk_io = clk_get(dev, "hsmmc");
469         if (IS_ERR(sc->clk_io)) {
470                 dev_err(dev, "failed to get io clock\n");
471                 ret = PTR_ERR(sc->clk_io);
472                 goto err_io_clk;
473         }
474
475         /* enable the local io clock and keep it running for the moment. */
476         clk_enable(sc->clk_io);
477
478         for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
479                 struct clk *clk;
480                 char name[14];
481
482                 snprintf(name, 14, "mmc_busclk.%d", ptr);
483                 clk = clk_get(dev, name);
484                 if (IS_ERR(clk)) {
485                         continue;
486                 }
487
488                 clks++;
489                 sc->clk_bus[ptr] = clk;
490
491                 /*
492                  * save current clock index to know which clock bus
493                  * is used later in overriding functions.
494                  */
495                 sc->cur_clk = ptr;
496
497                 clk_enable(clk);
498
499                 dev_info(dev, "clock source %d: %s (%ld Hz)\n",
500                          ptr, name, clk_get_rate(clk));
501         }
502
503         if (clks == 0) {
504                 dev_err(dev, "failed to find any bus clocks\n");
505                 ret = -ENOENT;
506                 goto err_no_busclks;
507         }
508
509         sc->ioarea = request_mem_region(res->start, resource_size(res),
510                                         mmc_hostname(host->mmc));
511         if (!sc->ioarea) {
512                 dev_err(dev, "failed to reserve register area\n");
513                 ret = -ENXIO;
514                 goto err_req_regs;
515         }
516
517         host->ioaddr = ioremap_nocache(res->start, resource_size(res));
518         if (!host->ioaddr) {
519                 dev_err(dev, "failed to map registers\n");
520                 ret = -ENXIO;
521                 goto err_req_regs;
522         }
523
524         /* Ensure we have minimal gpio selected CMD/CLK/Detect */
525         if (pdata->cfg_gpio)
526                 pdata->cfg_gpio(pdev, pdata->max_width);
527
528         host->hw_name = "samsung-hsmmc";
529         host->ops = &sdhci_s3c_ops;
530         host->quirks = 0;
531         host->irq = irq;
532
533         /* Setup quirks for the controller */
534         host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
535         host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
536         if (drv_data)
537                 host->quirks |= drv_data->sdhci_quirks;
538
539 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
540
541         /* we currently see overruns on errors, so disable the SDMA
542          * support as well. */
543         host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
544
545 #endif /* CONFIG_MMC_SDHCI_S3C_DMA */
546
547         /* It seems we do not get an DATA transfer complete on non-busy
548          * transfers, not sure if this is a problem with this specific
549          * SDHCI block, or a missing configuration that needs to be set. */
550         host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ;
551
552         /* This host supports the Auto CMD12 */
553         host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
554
555         /* Samsung SoCs need BROKEN_ADMA_ZEROLEN_DESC */
556         host->quirks |= SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC;
557
558         if (pdata->cd_type == S3C_SDHCI_CD_NONE ||
559             pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
560                 host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
561
562         if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
563                 host->mmc->caps = MMC_CAP_NONREMOVABLE;
564
565         if (pdata->pm_caps)
566                 host->mmc->pm_caps |= pdata->pm_caps;
567
568         host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
569                          SDHCI_QUIRK_32BIT_DMA_SIZE);
570
571         /* HSMMC on Samsung SoCs uses SDCLK as timeout clock */
572         host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
573
574         /*
575          * If controller does not have internal clock divider,
576          * we can use overriding functions instead of default.
577          */
578         if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
579                 sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
580                 sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
581                 sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
582         }
583
584         /* It supports additional host capabilities if needed */
585         if (pdata->host_caps)
586                 host->mmc->caps |= pdata->host_caps;
587
588         if (pdata->host_caps2)
589                 host->mmc->caps2 |= pdata->host_caps2;
590
591         ret = sdhci_add_host(host);
592         if (ret) {
593                 dev_err(dev, "sdhci_add_host() failed\n");
594                 goto err_add_host;
595         }
596
597         /* The following two methods of card detection might call
598            sdhci_s3c_notify_change() immediately, so they can be called
599            only after sdhci_add_host(). Setup errors are ignored. */
600         if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_init)
601                 pdata->ext_cd_init(&sdhci_s3c_notify_change);
602         if (pdata->cd_type == S3C_SDHCI_CD_GPIO &&
603             gpio_is_valid(pdata->ext_cd_gpio))
604                 sdhci_s3c_setup_card_detect_gpio(sc);
605
606         return 0;
607
608  err_add_host:
609         release_resource(sc->ioarea);
610         kfree(sc->ioarea);
611
612  err_req_regs:
613         for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
614                 if (sc->clk_bus[ptr]) {
615                         clk_disable(sc->clk_bus[ptr]);
616                         clk_put(sc->clk_bus[ptr]);
617                 }
618         }
619
620  err_no_busclks:
621         clk_disable(sc->clk_io);
622         clk_put(sc->clk_io);
623
624  err_io_clk:
625         sdhci_free_host(host);
626
627         return ret;
628 }
629
630 static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
631 {
632         struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
633         struct sdhci_host *host =  platform_get_drvdata(pdev);
634         struct sdhci_s3c *sc = sdhci_priv(host);
635         int ptr;
636
637         if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
638                 pdata->ext_cd_cleanup(&sdhci_s3c_notify_change);
639
640         if (sc->ext_cd_irq)
641                 free_irq(sc->ext_cd_irq, sc);
642
643         if (gpio_is_valid(sc->ext_cd_gpio))
644                 gpio_free(sc->ext_cd_gpio);
645
646         sdhci_remove_host(host, 1);
647
648         for (ptr = 0; ptr < 3; ptr++) {
649                 if (sc->clk_bus[ptr]) {
650                         clk_disable(sc->clk_bus[ptr]);
651                         clk_put(sc->clk_bus[ptr]);
652                 }
653         }
654         clk_disable(sc->clk_io);
655         clk_put(sc->clk_io);
656
657         iounmap(host->ioaddr);
658         release_resource(sc->ioarea);
659         kfree(sc->ioarea);
660
661         sdhci_free_host(host);
662         platform_set_drvdata(pdev, NULL);
663
664         return 0;
665 }
666
667 #ifdef CONFIG_PM
668
669 static int sdhci_s3c_suspend(struct device *dev)
670 {
671         struct sdhci_host *host = dev_get_drvdata(dev);
672
673         return sdhci_suspend_host(host);
674 }
675
676 static int sdhci_s3c_resume(struct device *dev)
677 {
678         struct sdhci_host *host = dev_get_drvdata(dev);
679
680         return sdhci_resume_host(host);
681 }
682
683 static const struct dev_pm_ops sdhci_s3c_pmops = {
684         .suspend        = sdhci_s3c_suspend,
685         .resume         = sdhci_s3c_resume,
686 };
687
688 #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops)
689
690 #else
691 #define SDHCI_S3C_PMOPS NULL
692 #endif
693
694 #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
695 static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
696         .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
697 };
698 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
699 #else
700 #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL)
701 #endif
702
703 static struct platform_device_id sdhci_s3c_driver_ids[] = {
704         {
705                 .name           = "s3c-sdhci",
706                 .driver_data    = (kernel_ulong_t)NULL,
707         }, {
708                 .name           = "exynos4-sdhci",
709                 .driver_data    = EXYNOS4_SDHCI_DRV_DATA,
710         },
711         { }
712 };
713 MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
714
715 static struct platform_driver sdhci_s3c_driver = {
716         .probe          = sdhci_s3c_probe,
717         .remove         = __devexit_p(sdhci_s3c_remove),
718         .id_table       = sdhci_s3c_driver_ids,
719         .driver         = {
720                 .owner  = THIS_MODULE,
721                 .name   = "s3c-sdhci",
722                 .pm     = SDHCI_S3C_PMOPS,
723         },
724 };
725
726 module_platform_driver(sdhci_s3c_driver);
727
728 MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue");
729 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
730 MODULE_LICENSE("GPL v2");
731 MODULE_ALIAS("platform:s3c-sdhci");