diff options
Diffstat (limited to 'drivers/mmc/host/sh_mmcif.c')
-rw-r--r-- | drivers/mmc/host/sh_mmcif.c | 185 |
1 files changed, 122 insertions, 63 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 724b35e85a26..b2af7136cd27 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -54,6 +54,8 @@ | |||
54 | #include <linux/mmc/mmc.h> | 54 | #include <linux/mmc/mmc.h> |
55 | #include <linux/mmc/sdio.h> | 55 | #include <linux/mmc/sdio.h> |
56 | #include <linux/mmc/sh_mmcif.h> | 56 | #include <linux/mmc/sh_mmcif.h> |
57 | #include <linux/mmc/slot-gpio.h> | ||
58 | #include <linux/mod_devicetable.h> | ||
57 | #include <linux/pagemap.h> | 59 | #include <linux/pagemap.h> |
58 | #include <linux/platform_device.h> | 60 | #include <linux/platform_device.h> |
59 | #include <linux/pm_qos.h> | 61 | #include <linux/pm_qos.h> |
@@ -384,6 +386,9 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host, | |||
384 | struct sh_dmae_slave *tx, *rx; | 386 | struct sh_dmae_slave *tx, *rx; |
385 | host->dma_active = false; | 387 | host->dma_active = false; |
386 | 388 | ||
389 | if (!pdata) | ||
390 | return; | ||
391 | |||
387 | /* We can only either use DMA for both Tx and Rx or not use it at all */ | 392 | /* We can only either use DMA for both Tx and Rx or not use it at all */ |
388 | if (pdata->dma) { | 393 | if (pdata->dma) { |
389 | dev_warn(&host->pd->dev, | 394 | dev_warn(&host->pd->dev, |
@@ -444,13 +449,14 @@ static void sh_mmcif_release_dma(struct sh_mmcif_host *host) | |||
444 | static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) | 449 | static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) |
445 | { | 450 | { |
446 | struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; | 451 | struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; |
452 | bool sup_pclk = p ? p->sup_pclk : false; | ||
447 | 453 | ||
448 | sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); | 454 | sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); |
449 | sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR); | 455 | sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR); |
450 | 456 | ||
451 | if (!clk) | 457 | if (!clk) |
452 | return; | 458 | return; |
453 | if (p->sup_pclk && clk == host->clk) | 459 | if (sup_pclk && clk == host->clk) |
454 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); | 460 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); |
455 | else | 461 | else |
456 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & | 462 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & |
@@ -892,21 +898,15 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
892 | 898 | ||
893 | switch (mrq->cmd->opcode) { | 899 | switch (mrq->cmd->opcode) { |
894 | /* MMCIF does not support SD/SDIO command */ | 900 | /* MMCIF does not support SD/SDIO command */ |
895 | case SD_IO_SEND_OP_COND: | 901 | case MMC_SLEEP_AWAKE: /* = SD_IO_SEND_OP_COND (5) */ |
902 | case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ | ||
903 | if ((mrq->cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR) | ||
904 | break; | ||
896 | case MMC_APP_CMD: | 905 | case MMC_APP_CMD: |
897 | host->state = STATE_IDLE; | 906 | host->state = STATE_IDLE; |
898 | mrq->cmd->error = -ETIMEDOUT; | 907 | mrq->cmd->error = -ETIMEDOUT; |
899 | mmc_request_done(mmc, mrq); | 908 | mmc_request_done(mmc, mrq); |
900 | return; | 909 | return; |
901 | case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ | ||
902 | if (!mrq->data) { | ||
903 | /* send_if_cond cmd (not support) */ | ||
904 | host->state = STATE_IDLE; | ||
905 | mrq->cmd->error = -ETIMEDOUT; | ||
906 | mmc_request_done(mmc, mrq); | ||
907 | return; | ||
908 | } | ||
909 | break; | ||
910 | default: | 910 | default: |
911 | break; | 911 | break; |
912 | } | 912 | } |
@@ -916,10 +916,35 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
916 | sh_mmcif_start_cmd(host, mrq); | 916 | sh_mmcif_start_cmd(host, mrq); |
917 | } | 917 | } |
918 | 918 | ||
919 | static int sh_mmcif_clk_update(struct sh_mmcif_host *host) | ||
920 | { | ||
921 | int ret = clk_enable(host->hclk); | ||
922 | |||
923 | if (!ret) { | ||
924 | host->clk = clk_get_rate(host->hclk); | ||
925 | host->mmc->f_max = host->clk / 2; | ||
926 | host->mmc->f_min = host->clk / 512; | ||
927 | } | ||
928 | |||
929 | return ret; | ||
930 | } | ||
931 | |||
932 | static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios) | ||
933 | { | ||
934 | struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data; | ||
935 | struct mmc_host *mmc = host->mmc; | ||
936 | |||
937 | if (pd && pd->set_pwr) | ||
938 | pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF); | ||
939 | if (!IS_ERR(mmc->supply.vmmc)) | ||
940 | /* Errors ignored... */ | ||
941 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, | ||
942 | ios->power_mode ? ios->vdd : 0); | ||
943 | } | ||
944 | |||
919 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 945 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
920 | { | 946 | { |
921 | struct sh_mmcif_host *host = mmc_priv(mmc); | 947 | struct sh_mmcif_host *host = mmc_priv(mmc); |
922 | struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; | ||
923 | unsigned long flags; | 948 | unsigned long flags; |
924 | 949 | ||
925 | spin_lock_irqsave(&host->lock, flags); | 950 | spin_lock_irqsave(&host->lock, flags); |
@@ -937,6 +962,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
937 | sh_mmcif_request_dma(host, host->pd->dev.platform_data); | 962 | sh_mmcif_request_dma(host, host->pd->dev.platform_data); |
938 | host->card_present = true; | 963 | host->card_present = true; |
939 | } | 964 | } |
965 | sh_mmcif_set_power(host, ios); | ||
940 | } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { | 966 | } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { |
941 | /* clock stop */ | 967 | /* clock stop */ |
942 | sh_mmcif_clock_control(host, 0); | 968 | sh_mmcif_clock_control(host, 0); |
@@ -948,9 +974,10 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
948 | } | 974 | } |
949 | if (host->power) { | 975 | if (host->power) { |
950 | pm_runtime_put(&host->pd->dev); | 976 | pm_runtime_put(&host->pd->dev); |
977 | clk_disable(host->hclk); | ||
951 | host->power = false; | 978 | host->power = false; |
952 | if (p->down_pwr && ios->power_mode == MMC_POWER_OFF) | 979 | if (ios->power_mode == MMC_POWER_OFF) |
953 | p->down_pwr(host->pd); | 980 | sh_mmcif_set_power(host, ios); |
954 | } | 981 | } |
955 | host->state = STATE_IDLE; | 982 | host->state = STATE_IDLE; |
956 | return; | 983 | return; |
@@ -958,8 +985,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
958 | 985 | ||
959 | if (ios->clock) { | 986 | if (ios->clock) { |
960 | if (!host->power) { | 987 | if (!host->power) { |
961 | if (p->set_pwr) | 988 | sh_mmcif_clk_update(host); |
962 | p->set_pwr(host->pd, ios->power_mode); | ||
963 | pm_runtime_get_sync(&host->pd->dev); | 989 | pm_runtime_get_sync(&host->pd->dev); |
964 | host->power = true; | 990 | host->power = true; |
965 | sh_mmcif_sync_reset(host); | 991 | sh_mmcif_sync_reset(host); |
@@ -975,8 +1001,12 @@ static int sh_mmcif_get_cd(struct mmc_host *mmc) | |||
975 | { | 1001 | { |
976 | struct sh_mmcif_host *host = mmc_priv(mmc); | 1002 | struct sh_mmcif_host *host = mmc_priv(mmc); |
977 | struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; | 1003 | struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; |
1004 | int ret = mmc_gpio_get_cd(mmc); | ||
1005 | |||
1006 | if (ret >= 0) | ||
1007 | return ret; | ||
978 | 1008 | ||
979 | if (!p->get_cd) | 1009 | if (!p || !p->get_cd) |
980 | return -ENOSYS; | 1010 | return -ENOSYS; |
981 | else | 1011 | else |
982 | return p->get_cd(host->pd); | 1012 | return p->get_cd(host->pd); |
@@ -1242,12 +1272,28 @@ static void mmcif_timeout_work(struct work_struct *work) | |||
1242 | mmc_request_done(host->mmc, mrq); | 1272 | mmc_request_done(host->mmc, mrq); |
1243 | } | 1273 | } |
1244 | 1274 | ||
1275 | static void sh_mmcif_init_ocr(struct sh_mmcif_host *host) | ||
1276 | { | ||
1277 | struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data; | ||
1278 | struct mmc_host *mmc = host->mmc; | ||
1279 | |||
1280 | mmc_regulator_get_supply(mmc); | ||
1281 | |||
1282 | if (!pd) | ||
1283 | return; | ||
1284 | |||
1285 | if (!mmc->ocr_avail) | ||
1286 | mmc->ocr_avail = pd->ocr; | ||
1287 | else if (pd->ocr) | ||
1288 | dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); | ||
1289 | } | ||
1290 | |||
1245 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) | 1291 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) |
1246 | { | 1292 | { |
1247 | int ret = 0, irq[2]; | 1293 | int ret = 0, irq[2]; |
1248 | struct mmc_host *mmc; | 1294 | struct mmc_host *mmc; |
1249 | struct sh_mmcif_host *host; | 1295 | struct sh_mmcif_host *host; |
1250 | struct sh_mmcif_plat_data *pd; | 1296 | struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; |
1251 | struct resource *res; | 1297 | struct resource *res; |
1252 | void __iomem *reg; | 1298 | void __iomem *reg; |
1253 | char clk_name[8]; | 1299 | char clk_name[8]; |
@@ -1268,42 +1314,26 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1268 | dev_err(&pdev->dev, "ioremap error.\n"); | 1314 | dev_err(&pdev->dev, "ioremap error.\n"); |
1269 | return -ENOMEM; | 1315 | return -ENOMEM; |
1270 | } | 1316 | } |
1271 | pd = pdev->dev.platform_data; | 1317 | |
1272 | if (!pd) { | ||
1273 | dev_err(&pdev->dev, "sh_mmcif plat data error.\n"); | ||
1274 | ret = -ENXIO; | ||
1275 | goto clean_up; | ||
1276 | } | ||
1277 | mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev); | 1318 | mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev); |
1278 | if (!mmc) { | 1319 | if (!mmc) { |
1279 | ret = -ENOMEM; | 1320 | ret = -ENOMEM; |
1280 | goto clean_up; | 1321 | goto ealloch; |
1281 | } | 1322 | } |
1282 | host = mmc_priv(mmc); | 1323 | host = mmc_priv(mmc); |
1283 | host->mmc = mmc; | 1324 | host->mmc = mmc; |
1284 | host->addr = reg; | 1325 | host->addr = reg; |
1285 | host->timeout = 1000; | 1326 | host->timeout = 1000; |
1286 | 1327 | ||
1287 | snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id); | ||
1288 | host->hclk = clk_get(&pdev->dev, clk_name); | ||
1289 | if (IS_ERR(host->hclk)) { | ||
1290 | dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
1291 | ret = PTR_ERR(host->hclk); | ||
1292 | goto clean_up1; | ||
1293 | } | ||
1294 | clk_enable(host->hclk); | ||
1295 | host->clk = clk_get_rate(host->hclk); | ||
1296 | host->pd = pdev; | 1328 | host->pd = pdev; |
1297 | 1329 | ||
1298 | spin_lock_init(&host->lock); | 1330 | spin_lock_init(&host->lock); |
1299 | 1331 | ||
1300 | mmc->ops = &sh_mmcif_ops; | 1332 | mmc->ops = &sh_mmcif_ops; |
1301 | mmc->f_max = host->clk / 2; | 1333 | sh_mmcif_init_ocr(host); |
1302 | mmc->f_min = host->clk / 512; | 1334 | |
1303 | if (pd->ocr) | ||
1304 | mmc->ocr_avail = pd->ocr; | ||
1305 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; | 1335 | mmc->caps = MMC_CAP_MMC_HIGHSPEED; |
1306 | if (pd->caps) | 1336 | if (pd && pd->caps) |
1307 | mmc->caps |= pd->caps; | 1337 | mmc->caps |= pd->caps; |
1308 | mmc->max_segs = 32; | 1338 | mmc->max_segs = 32; |
1309 | mmc->max_blk_size = 512; | 1339 | mmc->max_blk_size = 512; |
@@ -1311,34 +1341,52 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1311 | mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size; | 1341 | mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size; |
1312 | mmc->max_seg_size = mmc->max_req_size; | 1342 | mmc->max_seg_size = mmc->max_req_size; |
1313 | 1343 | ||
1314 | sh_mmcif_sync_reset(host); | ||
1315 | platform_set_drvdata(pdev, host); | 1344 | platform_set_drvdata(pdev, host); |
1316 | 1345 | ||
1317 | pm_runtime_enable(&pdev->dev); | 1346 | pm_runtime_enable(&pdev->dev); |
1318 | host->power = false; | 1347 | host->power = false; |
1319 | 1348 | ||
1349 | snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id); | ||
1350 | host->hclk = clk_get(&pdev->dev, clk_name); | ||
1351 | if (IS_ERR(host->hclk)) { | ||
1352 | ret = PTR_ERR(host->hclk); | ||
1353 | dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret); | ||
1354 | goto eclkget; | ||
1355 | } | ||
1356 | ret = sh_mmcif_clk_update(host); | ||
1357 | if (ret < 0) | ||
1358 | goto eclkupdate; | ||
1359 | |||
1320 | ret = pm_runtime_resume(&pdev->dev); | 1360 | ret = pm_runtime_resume(&pdev->dev); |
1321 | if (ret < 0) | 1361 | if (ret < 0) |
1322 | goto clean_up2; | 1362 | goto eresume; |
1323 | 1363 | ||
1324 | INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); | 1364 | INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); |
1325 | 1365 | ||
1366 | sh_mmcif_sync_reset(host); | ||
1326 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1367 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
1327 | 1368 | ||
1328 | ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host); | 1369 | ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host); |
1329 | if (ret) { | 1370 | if (ret) { |
1330 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); | 1371 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); |
1331 | goto clean_up3; | 1372 | goto ereqirq0; |
1332 | } | 1373 | } |
1333 | ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); | 1374 | ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); |
1334 | if (ret) { | 1375 | if (ret) { |
1335 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); | 1376 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); |
1336 | goto clean_up4; | 1377 | goto ereqirq1; |
1378 | } | ||
1379 | |||
1380 | if (pd && pd->use_cd_gpio) { | ||
1381 | ret = mmc_gpio_request_cd(mmc, pd->cd_gpio); | ||
1382 | if (ret < 0) | ||
1383 | goto erqcd; | ||
1337 | } | 1384 | } |
1338 | 1385 | ||
1386 | clk_disable(host->hclk); | ||
1339 | ret = mmc_add_host(mmc); | 1387 | ret = mmc_add_host(mmc); |
1340 | if (ret < 0) | 1388 | if (ret < 0) |
1341 | goto clean_up5; | 1389 | goto emmcaddh; |
1342 | 1390 | ||
1343 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); | 1391 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); |
1344 | 1392 | ||
@@ -1347,33 +1395,42 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1347 | sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); | 1395 | sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); |
1348 | return ret; | 1396 | return ret; |
1349 | 1397 | ||
1350 | clean_up5: | 1398 | emmcaddh: |
1399 | if (pd && pd->use_cd_gpio) | ||
1400 | mmc_gpio_free_cd(mmc); | ||
1401 | erqcd: | ||
1351 | free_irq(irq[1], host); | 1402 | free_irq(irq[1], host); |
1352 | clean_up4: | 1403 | ereqirq1: |
1353 | free_irq(irq[0], host); | 1404 | free_irq(irq[0], host); |
1354 | clean_up3: | 1405 | ereqirq0: |
1355 | pm_runtime_suspend(&pdev->dev); | 1406 | pm_runtime_suspend(&pdev->dev); |
1356 | clean_up2: | 1407 | eresume: |
1357 | pm_runtime_disable(&pdev->dev); | ||
1358 | clk_disable(host->hclk); | 1408 | clk_disable(host->hclk); |
1359 | clean_up1: | 1409 | eclkupdate: |
1410 | clk_put(host->hclk); | ||
1411 | eclkget: | ||
1412 | pm_runtime_disable(&pdev->dev); | ||
1360 | mmc_free_host(mmc); | 1413 | mmc_free_host(mmc); |
1361 | clean_up: | 1414 | ealloch: |
1362 | if (reg) | 1415 | iounmap(reg); |
1363 | iounmap(reg); | ||
1364 | return ret; | 1416 | return ret; |
1365 | } | 1417 | } |
1366 | 1418 | ||
1367 | static int __devexit sh_mmcif_remove(struct platform_device *pdev) | 1419 | static int __devexit sh_mmcif_remove(struct platform_device *pdev) |
1368 | { | 1420 | { |
1369 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | 1421 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); |
1422 | struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; | ||
1370 | int irq[2]; | 1423 | int irq[2]; |
1371 | 1424 | ||
1372 | host->dying = true; | 1425 | host->dying = true; |
1426 | clk_enable(host->hclk); | ||
1373 | pm_runtime_get_sync(&pdev->dev); | 1427 | pm_runtime_get_sync(&pdev->dev); |
1374 | 1428 | ||
1375 | dev_pm_qos_hide_latency_limit(&pdev->dev); | 1429 | dev_pm_qos_hide_latency_limit(&pdev->dev); |
1376 | 1430 | ||
1431 | if (pd && pd->use_cd_gpio) | ||
1432 | mmc_gpio_free_cd(host->mmc); | ||
1433 | |||
1377 | mmc_remove_host(host->mmc); | 1434 | mmc_remove_host(host->mmc); |
1378 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1435 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
1379 | 1436 | ||
@@ -1395,9 +1452,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
1395 | 1452 | ||
1396 | platform_set_drvdata(pdev, NULL); | 1453 | platform_set_drvdata(pdev, NULL); |
1397 | 1454 | ||
1398 | clk_disable(host->hclk); | ||
1399 | mmc_free_host(host->mmc); | 1455 | mmc_free_host(host->mmc); |
1400 | pm_runtime_put_sync(&pdev->dev); | 1456 | pm_runtime_put_sync(&pdev->dev); |
1457 | clk_disable(host->hclk); | ||
1401 | pm_runtime_disable(&pdev->dev); | 1458 | pm_runtime_disable(&pdev->dev); |
1402 | 1459 | ||
1403 | return 0; | 1460 | return 0; |
@@ -1406,24 +1463,18 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
1406 | #ifdef CONFIG_PM | 1463 | #ifdef CONFIG_PM |
1407 | static int sh_mmcif_suspend(struct device *dev) | 1464 | static int sh_mmcif_suspend(struct device *dev) |
1408 | { | 1465 | { |
1409 | struct platform_device *pdev = to_platform_device(dev); | 1466 | struct sh_mmcif_host *host = dev_get_drvdata(dev); |
1410 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | ||
1411 | int ret = mmc_suspend_host(host->mmc); | 1467 | int ret = mmc_suspend_host(host->mmc); |
1412 | 1468 | ||
1413 | if (!ret) { | 1469 | if (!ret) |
1414 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1470 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
1415 | clk_disable(host->hclk); | ||
1416 | } | ||
1417 | 1471 | ||
1418 | return ret; | 1472 | return ret; |
1419 | } | 1473 | } |
1420 | 1474 | ||
1421 | static int sh_mmcif_resume(struct device *dev) | 1475 | static int sh_mmcif_resume(struct device *dev) |
1422 | { | 1476 | { |
1423 | struct platform_device *pdev = to_platform_device(dev); | 1477 | struct sh_mmcif_host *host = dev_get_drvdata(dev); |
1424 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | ||
1425 | |||
1426 | clk_enable(host->hclk); | ||
1427 | 1478 | ||
1428 | return mmc_resume_host(host->mmc); | 1479 | return mmc_resume_host(host->mmc); |
1429 | } | 1480 | } |
@@ -1432,6 +1483,12 @@ static int sh_mmcif_resume(struct device *dev) | |||
1432 | #define sh_mmcif_resume NULL | 1483 | #define sh_mmcif_resume NULL |
1433 | #endif /* CONFIG_PM */ | 1484 | #endif /* CONFIG_PM */ |
1434 | 1485 | ||
1486 | static const struct of_device_id mmcif_of_match[] = { | ||
1487 | { .compatible = "renesas,sh-mmcif" }, | ||
1488 | { } | ||
1489 | }; | ||
1490 | MODULE_DEVICE_TABLE(of, mmcif_of_match); | ||
1491 | |||
1435 | static const struct dev_pm_ops sh_mmcif_dev_pm_ops = { | 1492 | static const struct dev_pm_ops sh_mmcif_dev_pm_ops = { |
1436 | .suspend = sh_mmcif_suspend, | 1493 | .suspend = sh_mmcif_suspend, |
1437 | .resume = sh_mmcif_resume, | 1494 | .resume = sh_mmcif_resume, |
@@ -1443,6 +1500,8 @@ static struct platform_driver sh_mmcif_driver = { | |||
1443 | .driver = { | 1500 | .driver = { |
1444 | .name = DRIVER_NAME, | 1501 | .name = DRIVER_NAME, |
1445 | .pm = &sh_mmcif_dev_pm_ops, | 1502 | .pm = &sh_mmcif_dev_pm_ops, |
1503 | .owner = THIS_MODULE, | ||
1504 | .of_match_table = mmcif_of_match, | ||
1446 | }, | 1505 | }, |
1447 | }; | 1506 | }; |
1448 | 1507 | ||