Commit ab769f227f79bedae7840f99b6c0c4d66aafc78e
1 parent
2c072c958b
Exists in
v2017.01-smarct4x
and in
48 other branches
mmc: Remove ops from struct mmc and put in mmc_ops
Remove the in-structure ops and put them in mmc_ops with a constant pointer to it. This makes the mmc structure smaller as well as conserving code space (in theory). All in-tree drivers are converted as well; this is done in a single patch in order to not break git bisect. Changes since V1: Fix compilation b0rked issue on omap platforms where OMAP_GPIO was not set. Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
Showing 17 changed files with 184 additions and 119 deletions Side-by-side Diff
- drivers/mmc/arm_pl180_mmci.c
- drivers/mmc/bfin_sdh.c
- drivers/mmc/davinci_mmc.c
- drivers/mmc/dw_mmc.c
- drivers/mmc/fsl_esdhc.c
- drivers/mmc/ftsdc010_mci.c
- drivers/mmc/gen_atmel_mci.c
- drivers/mmc/mmc.c
- drivers/mmc/mmc_spi.c
- drivers/mmc/mxcmmc.c
- drivers/mmc/mxsmmc.c
- drivers/mmc/omap_hsmmc.c
- drivers/mmc/pxa_mmc_gen.c
- drivers/mmc/sdhci.c
- drivers/mmc/sh_mmcif.c
- drivers/mmc/tegra_mmc.c
- include/mmc.h
drivers/mmc/arm_pl180_mmci.c
... | ... | @@ -335,6 +335,12 @@ |
335 | 335 | udelay(CLK_CHANGE_DELAY); |
336 | 336 | } |
337 | 337 | |
338 | +static const struct mmc_ops arm_pl180_mmci_ops = { | |
339 | + .send_cmd = host_request, | |
340 | + .set_ios = host_set_ios, | |
341 | + .init = mmc_host_reset, | |
342 | +}; | |
343 | + | |
338 | 344 | /* |
339 | 345 | * mmc_host_init - initialize the mmc controller. |
340 | 346 | * Set initial clock and power for mmc slot. |
... | ... | @@ -360,11 +366,7 @@ |
360 | 366 | sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; |
361 | 367 | writel(sdi_u32, &host->base->mask0); |
362 | 368 | strncpy(dev->name, host->name, sizeof(dev->name)); |
363 | - dev->send_cmd = host_request; | |
364 | - dev->set_ios = host_set_ios; | |
365 | - dev->init = mmc_host_reset; | |
366 | - dev->getcd = NULL; | |
367 | - dev->getwp = NULL; | |
369 | + dev->ops = &arm_pl180_mmci_ops; | |
368 | 370 | dev->host_caps = host->caps; |
369 | 371 | dev->voltages = host->voltages; |
370 | 372 | dev->f_min = host->clock_min; |
drivers/mmc/bfin_sdh.c
... | ... | @@ -274,6 +274,11 @@ |
274 | 274 | return 0; |
275 | 275 | } |
276 | 276 | |
277 | +static const struct mmc_ops bfin_mmc_ops = { | |
278 | + .send_cmd = bfin_sdh_request, | |
279 | + .set_ios = bfin_sdh_set_ios, | |
280 | + .init = bfin_sdh_init, | |
281 | +}; | |
277 | 282 | |
278 | 283 | int bfin_mmc_init(bd_t *bis) |
279 | 284 | { |
... | ... | @@ -284,11 +289,7 @@ |
284 | 289 | if (!mmc) |
285 | 290 | return -ENOMEM; |
286 | 291 | sprintf(mmc->name, "Blackfin SDH"); |
287 | - mmc->send_cmd = bfin_sdh_request; | |
288 | - mmc->set_ios = bfin_sdh_set_ios; | |
289 | - mmc->init = bfin_sdh_init; | |
290 | - mmc->getcd = NULL; | |
291 | - mmc->getwp = NULL; | |
292 | + mmc->ops = &bfin_mmc_ops; | |
292 | 293 | mmc->host_caps = MMC_MODE_4BIT; |
293 | 294 | |
294 | 295 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; |
drivers/mmc/davinci_mmc.c
... | ... | @@ -363,6 +363,12 @@ |
363 | 363 | dmmc_set_clock(mmc, mmc->clock); |
364 | 364 | } |
365 | 365 | |
366 | +static const struct mmc_ops dmmc_ops = { | |
367 | + .send_cmd = dmmc_send_cmd, | |
368 | + .set_ios = dmmc_set_ios, | |
369 | + .init = dmmc_init, | |
370 | +}; | |
371 | + | |
366 | 372 | /* Called from board_mmc_init during startup. Can be called multiple times |
367 | 373 | * depending on the number of slots available on board and controller |
368 | 374 | */ |
... | ... | @@ -375,12 +381,7 @@ |
375 | 381 | |
376 | 382 | sprintf(mmc->name, "davinci"); |
377 | 383 | mmc->priv = host; |
378 | - mmc->send_cmd = dmmc_send_cmd; | |
379 | - mmc->set_ios = dmmc_set_ios; | |
380 | - mmc->init = dmmc_init; | |
381 | - mmc->getcd = NULL; | |
382 | - mmc->getwp = NULL; | |
383 | - | |
384 | + mmc->ops = &dmmc_ops; | |
384 | 385 | mmc->f_min = 200000; |
385 | 386 | mmc->f_max = 25000000; |
386 | 387 | mmc->voltages = host->voltages; |
drivers/mmc/dw_mmc.c
... | ... | @@ -343,6 +343,12 @@ |
343 | 343 | return 0; |
344 | 344 | } |
345 | 345 | |
346 | +static const struct mmc_ops dwmci_ops = { | |
347 | + .send_cmd = dwmci_send_cmd, | |
348 | + .set_ios = dwmci_set_ios, | |
349 | + .init = dwmci_init, | |
350 | +}; | |
351 | + | |
346 | 352 | int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) |
347 | 353 | { |
348 | 354 | struct mmc *mmc; |
... | ... | @@ -358,9 +364,7 @@ |
358 | 364 | host->mmc = mmc; |
359 | 365 | |
360 | 366 | sprintf(mmc->name, "%s", host->name); |
361 | - mmc->send_cmd = dwmci_send_cmd; | |
362 | - mmc->set_ios = dwmci_set_ios; | |
363 | - mmc->init = dwmci_init; | |
367 | + mmc->ops = &dwmci_ops; | |
364 | 368 | mmc->f_min = min_clk; |
365 | 369 | mmc->f_max = max_clk; |
366 | 370 |
drivers/mmc/fsl_esdhc.c
... | ... | @@ -524,6 +524,13 @@ |
524 | 524 | printf("MMC/SD: Reset never completed.\n"); |
525 | 525 | } |
526 | 526 | |
527 | +static const struct mmc_ops esdhc_ops = { | |
528 | + .send_cmd = esdhc_send_cmd, | |
529 | + .set_ios = esdhc_set_ios, | |
530 | + .init = esdhc_init, | |
531 | + .getcd = esdhc_getcd, | |
532 | +}; | |
533 | + | |
527 | 534 | int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) |
528 | 535 | { |
529 | 536 | struct fsl_esdhc *regs; |
... | ... | @@ -548,12 +555,7 @@ |
548 | 555 | | SYSCTL_IPGEN | SYSCTL_CKEN); |
549 | 556 | |
550 | 557 | mmc->priv = cfg; |
551 | - mmc->send_cmd = esdhc_send_cmd; | |
552 | - mmc->set_ios = esdhc_set_ios; | |
553 | - mmc->init = esdhc_init; | |
554 | - mmc->getcd = esdhc_getcd; | |
555 | - mmc->getwp = NULL; | |
556 | - | |
558 | + mmc->ops = &esdhc_ops; | |
557 | 559 | voltage_caps = 0; |
558 | 560 | caps = regs->hostcapblt; |
559 | 561 |
drivers/mmc/ftsdc010_mci.c
... | ... | @@ -316,6 +316,12 @@ |
316 | 316 | return 0; |
317 | 317 | } |
318 | 318 | |
319 | +static const struct mmc_ops ftsdc010_ops = { | |
320 | + .send_cmd = ftsdc010_request, | |
321 | + .set_ios = ftsdc010_set_ios, | |
322 | + .init = ftsdc010_init, | |
323 | +}; | |
324 | + | |
319 | 325 | int ftsdc010_mmc_init(int devid) |
320 | 326 | { |
321 | 327 | struct mmc *mmc; |
... | ... | @@ -347,10 +353,7 @@ |
347 | 353 | mmc->priv = chip; |
348 | 354 | |
349 | 355 | sprintf(mmc->name, "ftsdc010"); |
350 | - mmc->send_cmd = ftsdc010_request; | |
351 | - mmc->set_ios = ftsdc010_set_ios; | |
352 | - mmc->init = ftsdc010_init; | |
353 | - | |
356 | + mmc->ops = &ftsdc010_ops; | |
354 | 357 | mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz; |
355 | 358 | switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) { |
356 | 359 | case FTSDC010_BWR_CAPS_4BIT: |
drivers/mmc/gen_atmel_mci.c
... | ... | @@ -344,6 +344,12 @@ |
344 | 344 | return 0; |
345 | 345 | } |
346 | 346 | |
347 | +static const struct mmc_ops atmel_mci_ops = { | |
348 | + .send_cmd = mci_send_cmd, | |
349 | + .set_ios = mci_set_ios, | |
350 | + .init = mci_init, | |
351 | +}; | |
352 | + | |
347 | 353 | /* |
348 | 354 | * This is the only exported function |
349 | 355 | * |
... | ... | @@ -360,11 +366,7 @@ |
360 | 366 | |
361 | 367 | strcpy(mmc->name, "mci"); |
362 | 368 | mmc->priv = regs; |
363 | - mmc->send_cmd = mci_send_cmd; | |
364 | - mmc->set_ios = mci_set_ios; | |
365 | - mmc->init = mci_init; | |
366 | - mmc->getcd = NULL; | |
367 | - mmc->getwp = NULL; | |
369 | + mmc->ops = &atmel_mci_ops; | |
368 | 370 | |
369 | 371 | /* need to be able to pass these in on a board by board basis */ |
370 | 372 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; |
drivers/mmc/mmc.c
... | ... | @@ -37,8 +37,8 @@ |
37 | 37 | wp = board_mmc_getwp(mmc); |
38 | 38 | |
39 | 39 | if (wp < 0) { |
40 | - if (mmc->getwp) | |
41 | - wp = mmc->getwp(mmc); | |
40 | + if (mmc->ops->getwp) | |
41 | + wp = mmc->ops->getwp(mmc); | |
42 | 42 | else |
43 | 43 | wp = 0; |
44 | 44 | } |
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | |
64 | 64 | printf("CMD_SEND:%d\n", cmd->cmdidx); |
65 | 65 | printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); |
66 | - ret = mmc->send_cmd(mmc, cmd, data); | |
66 | + ret = mmc->ops->send_cmd(mmc, cmd, data); | |
67 | 67 | switch (cmd->resp_type) { |
68 | 68 | case MMC_RSP_NONE: |
69 | 69 | printf("\t\tMMC_RSP_NONE\n"); |
... | ... | @@ -106,7 +106,7 @@ |
106 | 106 | break; |
107 | 107 | } |
108 | 108 | #else |
109 | - ret = mmc->send_cmd(mmc, cmd, data); | |
109 | + ret = mmc->ops->send_cmd(mmc, cmd, data); | |
110 | 110 | #endif |
111 | 111 | return ret; |
112 | 112 | } |
... | ... | @@ -578,8 +578,8 @@ |
578 | 578 | cd = board_mmc_getcd(mmc); |
579 | 579 | |
580 | 580 | if (cd < 0) { |
581 | - if (mmc->getcd) | |
582 | - cd = mmc->getcd(mmc); | |
581 | + if (mmc->ops->getcd) | |
582 | + cd = mmc->ops->getcd(mmc); | |
583 | 583 | else |
584 | 584 | cd = 1; |
585 | 585 | } |
... | ... | @@ -751,7 +751,8 @@ |
751 | 751 | |
752 | 752 | static void mmc_set_ios(struct mmc *mmc) |
753 | 753 | { |
754 | - mmc->set_ios(mmc); | |
754 | + if (mmc->ops->set_ios) | |
755 | + mmc->ops->set_ios(mmc); | |
755 | 756 | } |
756 | 757 | |
757 | 758 | void mmc_set_clock(struct mmc *mmc, uint clock) |
... | ... | @@ -1207,7 +1208,8 @@ |
1207 | 1208 | { |
1208 | 1209 | int err; |
1209 | 1210 | |
1210 | - if (mmc_getcd(mmc) == 0) { | |
1211 | + /* we pretend there's no card when init is NULL */ | |
1212 | + if (mmc_getcd(mmc) == 0 || mmc->ops->init == NULL) { | |
1211 | 1213 | mmc->has_init = 0; |
1212 | 1214 | #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) |
1213 | 1215 | printf("MMC: no card present\n"); |
... | ... | @@ -1218,7 +1220,8 @@ |
1218 | 1220 | if (mmc->has_init) |
1219 | 1221 | return 0; |
1220 | 1222 | |
1221 | - err = mmc->init(mmc); | |
1223 | + /* made sure it's not NULL earlier */ | |
1224 | + err = mmc->ops->init(mmc); | |
1222 | 1225 | |
1223 | 1226 | if (err) |
1224 | 1227 | return err; |
drivers/mmc/mmc_spi.c
... | ... | @@ -255,6 +255,12 @@ |
255 | 255 | return 0; |
256 | 256 | } |
257 | 257 | |
258 | +static const struct mmc_ops mmc_spi_ops = { | |
259 | + .send_cmd = mmc_spi_request, | |
260 | + .set_ios = mmc_spi_set_ios, | |
261 | + .init = mmc_spi_init_p, | |
262 | +}; | |
263 | + | |
258 | 264 | struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) |
259 | 265 | { |
260 | 266 | struct mmc *mmc; |
... | ... | @@ -269,11 +275,7 @@ |
269 | 275 | return NULL; |
270 | 276 | } |
271 | 277 | sprintf(mmc->name, "MMC_SPI"); |
272 | - mmc->send_cmd = mmc_spi_request; | |
273 | - mmc->set_ios = mmc_spi_set_ios; | |
274 | - mmc->init = mmc_spi_init_p; | |
275 | - mmc->getcd = NULL; | |
276 | - mmc->getwp = NULL; | |
278 | + mmc->ops = &mmc_spi_ops; | |
277 | 279 | mmc->host_caps = MMC_MODE_SPI; |
278 | 280 | |
279 | 281 | mmc->voltages = MMC_SPI_VOLTAGE; |
drivers/mmc/mxcmmc.c
... | ... | @@ -485,6 +485,12 @@ |
485 | 485 | return 0; |
486 | 486 | } |
487 | 487 | |
488 | +static const struct mmc_ops mxcmci_ops = { | |
489 | + .send_cmd = mxcmci_request, | |
490 | + .set_ios = mxcmci_set_ios, | |
491 | + .init = mxcmci_init, | |
492 | +}; | |
493 | + | |
488 | 494 | static int mxcmci_initialize(bd_t *bis) |
489 | 495 | { |
490 | 496 | struct mmc *mmc = NULL; |
... | ... | @@ -495,11 +501,7 @@ |
495 | 501 | return -ENOMEM; |
496 | 502 | |
497 | 503 | sprintf(mmc->name, "MXC MCI"); |
498 | - mmc->send_cmd = mxcmci_request; | |
499 | - mmc->set_ios = mxcmci_set_ios; | |
500 | - mmc->init = mxcmci_init; | |
501 | - mmc->getcd = NULL; | |
502 | - mmc->getwp = NULL; | |
504 | + mmc->ops = &mxcmci_ops; | |
503 | 505 | mmc->host_caps = MMC_MODE_4BIT; |
504 | 506 | |
505 | 507 | host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE; |
drivers/mmc/mxsmmc.c
... | ... | @@ -363,6 +363,12 @@ |
363 | 363 | return 0; |
364 | 364 | } |
365 | 365 | |
366 | +static const struct mmc_ops mxsmmc_ops = { | |
367 | + .send_cmd = mxsmmc_send_cmd, | |
368 | + .set_ios = mxsmmc_set_ios, | |
369 | + .init = mxsmmc_init, | |
370 | +}; | |
371 | + | |
366 | 372 | int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int)) |
367 | 373 | { |
368 | 374 | struct mmc *mmc = NULL; |
... | ... | @@ -400,11 +406,7 @@ |
400 | 406 | priv->regs = mxs_ssp_regs_by_bus(id); |
401 | 407 | |
402 | 408 | sprintf(mmc->name, "MXS MMC"); |
403 | - mmc->send_cmd = mxsmmc_send_cmd; | |
404 | - mmc->set_ios = mxsmmc_set_ios; | |
405 | - mmc->init = mxsmmc_init; | |
406 | - mmc->getcd = NULL; | |
407 | - mmc->getwp = NULL; | |
409 | + mmc->ops = &mxsmmc_ops; | |
408 | 410 | mmc->priv = priv; |
409 | 411 | |
410 | 412 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; |
drivers/mmc/omap_hsmmc.c
... | ... | @@ -35,14 +35,24 @@ |
35 | 35 | #include <asm/arch/mmc_host_def.h> |
36 | 36 | #include <asm/arch/sys_proto.h> |
37 | 37 | |
38 | +/* simplify defines to OMAP_HSMMC_USE_GPIO */ | |
39 | +#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ | |
40 | + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) | |
41 | +#define OMAP_HSMMC_USE_GPIO | |
42 | +#else | |
43 | +#undef OMAP_HSMMC_USE_GPIO | |
44 | +#endif | |
45 | + | |
38 | 46 | /* common definitions for all OMAPs */ |
39 | 47 | #define SYSCTL_SRC (1 << 25) |
40 | 48 | #define SYSCTL_SRD (1 << 26) |
41 | 49 | |
42 | 50 | struct omap_hsmmc_data { |
43 | 51 | struct hsmmc *base_addr; |
52 | +#ifdef OMAP_HSMMC_USE_GPIO | |
44 | 53 | int cd_gpio; |
45 | 54 | int wp_gpio; |
55 | +#endif | |
46 | 56 | }; |
47 | 57 | |
48 | 58 | /* If we fail after 1 second wait, something is really bad */ |
... | ... | @@ -54,8 +64,7 @@ |
54 | 64 | static struct mmc hsmmc_dev[3]; |
55 | 65 | static struct omap_hsmmc_data hsmmc_dev_data[3]; |
56 | 66 | |
57 | -#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ | |
58 | - (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) | |
67 | +#ifdef OMAP_HSMMC_USE_GPIO | |
59 | 68 | static int omap_mmc_setup_gpio_in(int gpio, const char *label) |
60 | 69 | { |
61 | 70 | if (!gpio_is_valid(gpio)) |
... | ... | @@ -69,26 +78,6 @@ |
69 | 78 | |
70 | 79 | return gpio; |
71 | 80 | } |
72 | - | |
73 | -static int omap_mmc_getcd(struct mmc *mmc) | |
74 | -{ | |
75 | - int cd_gpio = ((struct omap_hsmmc_data *)mmc->priv)->cd_gpio; | |
76 | - return gpio_get_value(cd_gpio); | |
77 | -} | |
78 | - | |
79 | -static int omap_mmc_getwp(struct mmc *mmc) | |
80 | -{ | |
81 | - int wp_gpio = ((struct omap_hsmmc_data *)mmc->priv)->wp_gpio; | |
82 | - return gpio_get_value(wp_gpio); | |
83 | -} | |
84 | -#else | |
85 | -static inline int omap_mmc_setup_gpio_in(int gpio, const char *label) | |
86 | -{ | |
87 | - return -1; | |
88 | -} | |
89 | - | |
90 | -#define omap_mmc_getcd NULL | |
91 | -#define omap_mmc_getwp NULL | |
92 | 81 | #endif |
93 | 82 | |
94 | 83 | #if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) |
... | ... | @@ -213,7 +202,7 @@ |
213 | 202 | } |
214 | 203 | |
215 | 204 | |
216 | -static int mmc_init_setup(struct mmc *mmc) | |
205 | +static int omap_hsmmc_init_setup(struct mmc *mmc) | |
217 | 206 | { |
218 | 207 | struct hsmmc *mmc_base; |
219 | 208 | unsigned int reg_val; |
... | ... | @@ -322,7 +311,7 @@ |
322 | 311 | } |
323 | 312 | } |
324 | 313 | |
325 | -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, | |
314 | +static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, | |
326 | 315 | struct mmc_data *data) |
327 | 316 | { |
328 | 317 | struct hsmmc *mmc_base; |
... | ... | @@ -552,7 +541,7 @@ |
552 | 541 | return 0; |
553 | 542 | } |
554 | 543 | |
555 | -static void mmc_set_ios(struct mmc *mmc) | |
544 | +static void omap_hsmmc_set_ios(struct mmc *mmc) | |
556 | 545 | { |
557 | 546 | struct hsmmc *mmc_base; |
558 | 547 | unsigned int dsor = 0; |
... | ... | @@ -606,6 +595,44 @@ |
606 | 595 | writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); |
607 | 596 | } |
608 | 597 | |
598 | +#ifdef OMAP_HSMMC_USE_GPIO | |
599 | +static int omap_hsmmc_getcd(struct mmc *mmc) | |
600 | +{ | |
601 | + struct omap_hsmmc_data *priv_data = mmc->priv; | |
602 | + int cd_gpio; | |
603 | + | |
604 | + /* if no CD return as 1 */ | |
605 | + cd_gpio = priv_data->cd_gpio; | |
606 | + if (cd_gpio < 0) | |
607 | + return 1; | |
608 | + | |
609 | + return gpio_get_value(cd_gpio); | |
610 | +} | |
611 | + | |
612 | +static int omap_hsmmc_getwp(struct mmc *mmc) | |
613 | +{ | |
614 | + struct omap_hsmmc_data *priv_data = mmc->priv; | |
615 | + int wp_gpio; | |
616 | + | |
617 | + /* if no WP return as 0 */ | |
618 | + wp_gpio = priv_data->wp_gpio; | |
619 | + if (wp_gpio < 0) | |
620 | + return 0; | |
621 | + | |
622 | + return gpio_get_value(wp_gpio); | |
623 | +} | |
624 | +#endif | |
625 | + | |
626 | +static const struct mmc_ops omap_hsmmc_ops = { | |
627 | + .send_cmd = omap_hsmmc_send_cmd, | |
628 | + .set_ios = omap_hsmmc_set_ios, | |
629 | + .init = omap_hsmmc_init_setup, | |
630 | +#ifdef OMAP_HSMMC_USE_GPIO | |
631 | + .getcd = omap_hsmmc_getcd, | |
632 | + .getwp = omap_hsmmc_getwp, | |
633 | +#endif | |
634 | +}; | |
635 | + | |
609 | 636 | int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, |
610 | 637 | int wp_gpio) |
611 | 638 | { |
... | ... | @@ -615,9 +642,7 @@ |
615 | 642 | MMC_MODE_HC; |
616 | 643 | |
617 | 644 | sprintf(mmc->name, "OMAP SD/MMC"); |
618 | - mmc->send_cmd = mmc_send_cmd; | |
619 | - mmc->set_ios = mmc_set_ios; | |
620 | - mmc->init = mmc_init_setup; | |
645 | + mmc->ops = &omap_hsmmc_ops; | |
621 | 646 | mmc->priv = priv_data; |
622 | 647 | |
623 | 648 | switch (dev_index) { |
624 | 649 | |
625 | 650 | |
... | ... | @@ -647,13 +672,11 @@ |
647 | 672 | priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; |
648 | 673 | return 1; |
649 | 674 | } |
675 | +#ifdef OMAP_HSMMC_USE_GPIO | |
676 | + /* on error gpio values are set to -1, which is what we want */ | |
650 | 677 | priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); |
651 | - if (priv_data->cd_gpio != -1) | |
652 | - mmc->getcd = omap_mmc_getcd; | |
653 | - | |
654 | 678 | priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp"); |
655 | - if (priv_data->wp_gpio != -1) | |
656 | - mmc->getwp = omap_mmc_getwp; | |
679 | +#endif | |
657 | 680 | |
658 | 681 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; |
659 | 682 | mmc->host_caps = host_caps_val & ~host_caps_mask; |
drivers/mmc/pxa_mmc_gen.c
... | ... | @@ -366,6 +366,12 @@ |
366 | 366 | return 0; |
367 | 367 | } |
368 | 368 | |
369 | +static const struct mmc_ops pxa_mmc_ops = { | |
370 | + .send_cmd = pxa_mmc_request, | |
371 | + .set_ios = pxa_mmc_set_ios, | |
372 | + .init = pxa_mmc_init, | |
373 | +}; | |
374 | + | |
369 | 375 | int pxa_mmc_register(int card_index) |
370 | 376 | { |
371 | 377 | struct mmc *mmc; |
... | ... | @@ -397,10 +403,7 @@ |
397 | 403 | mmc->priv = priv; |
398 | 404 | |
399 | 405 | sprintf(mmc->name, "PXA MMC"); |
400 | - mmc->send_cmd = pxa_mmc_request; | |
401 | - mmc->set_ios = pxa_mmc_set_ios; | |
402 | - mmc->init = pxa_mmc_init; | |
403 | - mmc->getcd = NULL; | |
406 | + mmc->ops = &pxa_mmc_ops; | |
404 | 407 | |
405 | 408 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; |
406 | 409 | mmc->f_max = PXAMMC_MAX_SPEED; |
drivers/mmc/sdhci.c
... | ... | @@ -430,6 +430,13 @@ |
430 | 430 | return 0; |
431 | 431 | } |
432 | 432 | |
433 | + | |
434 | +static const struct mmc_ops sdhci_ops = { | |
435 | + .send_cmd = sdhci_send_command, | |
436 | + .set_ios = sdhci_set_ios, | |
437 | + .init = sdhci_init, | |
438 | +}; | |
439 | + | |
433 | 440 | int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) |
434 | 441 | { |
435 | 442 | struct mmc *mmc; |
... | ... | @@ -445,11 +452,7 @@ |
445 | 452 | host->mmc = mmc; |
446 | 453 | |
447 | 454 | sprintf(mmc->name, "%s", host->name); |
448 | - mmc->send_cmd = sdhci_send_command; | |
449 | - mmc->set_ios = sdhci_set_ios; | |
450 | - mmc->init = sdhci_init; | |
451 | - mmc->getcd = NULL; | |
452 | - mmc->getwp = NULL; | |
455 | + mmc->ops = &sdhci_ops; | |
453 | 456 | |
454 | 457 | caps = sdhci_readl(host, SDHCI_CAPABILITIES); |
455 | 458 | #ifdef CONFIG_MMC_SDMA |
drivers/mmc/sh_mmcif.c
... | ... | @@ -574,6 +574,12 @@ |
574 | 574 | return 0; |
575 | 575 | } |
576 | 576 | |
577 | +static const struct mmc_ops sh_mmcif_ops = { | |
578 | + .send_cmd = sh_mmcif_request, | |
579 | + .set_ios = sh_mmcif_set_ios, | |
580 | + .init = sh_mmcif_init, | |
581 | +}; | |
582 | + | |
577 | 583 | int mmcif_mmc_init(void) |
578 | 584 | { |
579 | 585 | int ret = 0; |
... | ... | @@ -595,11 +601,7 @@ |
595 | 601 | mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | |
596 | 602 | MMC_MODE_8BIT | MMC_MODE_HC; |
597 | 603 | memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); |
598 | - mmc->send_cmd = sh_mmcif_request; | |
599 | - mmc->set_ios = sh_mmcif_set_ios; | |
600 | - mmc->init = sh_mmcif_init; | |
601 | - mmc->getcd = NULL; | |
602 | - mmc->getwp = NULL; | |
604 | + mmc->ops = &sh_mmcif_ops; | |
603 | 605 | host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; |
604 | 606 | host->clk = CONFIG_SH_MMCIF_CLK; |
605 | 607 | mmc->priv = host; |
drivers/mmc/tegra_mmc.c
... | ... | @@ -314,7 +314,7 @@ |
314 | 314 | return 0; |
315 | 315 | } |
316 | 316 | |
317 | -static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, | |
317 | +static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, | |
318 | 318 | struct mmc_data *data) |
319 | 319 | { |
320 | 320 | void *buf; |
... | ... | @@ -396,7 +396,7 @@ |
396 | 396 | host->clock = clock; |
397 | 397 | } |
398 | 398 | |
399 | -static void mmc_set_ios(struct mmc *mmc) | |
399 | +static void tegra_mmc_set_ios(struct mmc *mmc) | |
400 | 400 | { |
401 | 401 | struct mmc_host *host = mmc->priv; |
402 | 402 | unsigned char ctrl; |
... | ... | @@ -464,7 +464,7 @@ |
464 | 464 | pad_init_mmc(host); |
465 | 465 | } |
466 | 466 | |
467 | -static int mmc_core_init(struct mmc *mmc) | |
467 | +static int tegra_mmc_core_init(struct mmc *mmc) | |
468 | 468 | { |
469 | 469 | struct mmc_host *host = (struct mmc_host *)mmc->priv; |
470 | 470 | unsigned int mask; |
... | ... | @@ -521,6 +521,13 @@ |
521 | 521 | return 1; |
522 | 522 | } |
523 | 523 | |
524 | +static const struct mmc_ops tegra_mmc_ops = { | |
525 | + .send_cmd = tegra_mmc_send_cmd, | |
526 | + .set_ios = tegra_mmc_set_ios, | |
527 | + .init = tegra_mmc_core_init, | |
528 | + .getcd = tegra_mmc_getcd, | |
529 | +}; | |
530 | + | |
524 | 531 | static int do_mmc_init(int dev_index) |
525 | 532 | { |
526 | 533 | struct mmc_host *host; |
... | ... | @@ -558,11 +565,7 @@ |
558 | 565 | |
559 | 566 | sprintf(mmc->name, "Tegra SD/MMC"); |
560 | 567 | mmc->priv = host; |
561 | - mmc->send_cmd = mmc_send_cmd; | |
562 | - mmc->set_ios = mmc_set_ios; | |
563 | - mmc->init = mmc_core_init; | |
564 | - mmc->getcd = tegra_mmc_getcd; | |
565 | - mmc->getwp = NULL; | |
568 | + mmc->ops = &tegra_mmc_ops; | |
566 | 569 | |
567 | 570 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; |
568 | 571 | mmc->host_caps = 0; |
include/mmc.h
... | ... | @@ -250,6 +250,18 @@ |
250 | 250 | uint blocksize; |
251 | 251 | }; |
252 | 252 | |
253 | +/* forward decl. */ | |
254 | +struct mmc; | |
255 | + | |
256 | +struct mmc_ops { | |
257 | + int (*send_cmd)(struct mmc *mmc, | |
258 | + struct mmc_cmd *cmd, struct mmc_data *data); | |
259 | + void (*set_ios)(struct mmc *mmc); | |
260 | + int (*init)(struct mmc *mmc); | |
261 | + int (*getcd)(struct mmc *mmc); | |
262 | + int (*getwp)(struct mmc *mmc); | |
263 | +}; | |
264 | + | |
253 | 265 | struct mmc { |
254 | 266 | struct list_head link; |
255 | 267 | char name[32]; |
... | ... | @@ -283,12 +295,7 @@ |
283 | 295 | u64 capacity_rpmb; |
284 | 296 | u64 capacity_gp[4]; |
285 | 297 | block_dev_desc_t block_dev; |
286 | - int (*send_cmd)(struct mmc *mmc, | |
287 | - struct mmc_cmd *cmd, struct mmc_data *data); | |
288 | - void (*set_ios)(struct mmc *mmc); | |
289 | - int (*init)(struct mmc *mmc); | |
290 | - int (*getcd)(struct mmc *mmc); | |
291 | - int (*getwp)(struct mmc *mmc); | |
298 | + const struct mmc_ops *ops; | |
292 | 299 | uint b_max; |
293 | 300 | char op_cond_pending; /* 1 if we are waiting on an op_cond command */ |
294 | 301 | char init_in_progress; /* 1 if we have done mmc_start_init() */ |