aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-24 11:21:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-24 11:21:56 -0400
commit590d4b333d12cbf85dae37257d81960a280232df (patch)
treeae87599e93d935a96acf88e95df601524af47735
parent56fff1bb0f31358bf81a3c64a8dcd6da0dc44263 (diff)
parentf5f968f2371ccdebb8a365487649673c9af68d09 (diff)
Merge tag 'mmc-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson: "A couple of MMC host fixes intended for v4.12 rc3: - sdhci-xenon: Don't free data for phy allocated by devm* - sdhci-iproc: Suppress spurious interrupts - cavium: Fix probing race with regulator - cavium: Prevent crash with incomplete DT - cavium-octeon: Use proper GPIO name for power control - cavium-octeon: Fix interrupt enable code" * tag 'mmc-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci-iproc: suppress spurious interrupt with Multiblock read mmc: cavium: Fix probing race with regulator of/platform: Make of_platform_device_destroy globally visible mmc: cavium: Prevent crash with incomplete DT mmc: cavium-octeon: Use proper GPIO name for power control mmc: cavium-octeon: Fix interrupt enable code mmc: sdhci-xenon: kill xenon_clean_phy()
-rw-r--r--drivers/mmc/host/cavium-octeon.c15
-rw-r--r--drivers/mmc/host/cavium-thunderx.c6
-rw-r--r--drivers/mmc/host/cavium.c25
-rw-r--r--drivers/mmc/host/sdhci-iproc.c3
-rw-r--r--drivers/mmc/host/sdhci-xenon-phy.c14
-rw-r--r--drivers/mmc/host/sdhci-xenon.c6
-rw-r--r--drivers/mmc/host/sdhci-xenon.h1
-rw-r--r--drivers/of/platform.c3
-rw-r--r--include/linux/of_platform.h1
9 files changed, 35 insertions, 39 deletions
diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c
index 772d0900026d..951d2cdd7888 100644
--- a/drivers/mmc/host/cavium-octeon.c
+++ b/drivers/mmc/host/cavium-octeon.c
@@ -108,7 +108,7 @@ static void octeon_mmc_release_bus(struct cvm_mmc_host *host)
108static void octeon_mmc_int_enable(struct cvm_mmc_host *host, u64 val) 108static void octeon_mmc_int_enable(struct cvm_mmc_host *host, u64 val)
109{ 109{
110 writeq(val, host->base + MIO_EMM_INT(host)); 110 writeq(val, host->base + MIO_EMM_INT(host));
111 if (!host->dma_active || (host->dma_active && !host->has_ciu3)) 111 if (!host->has_ciu3)
112 writeq(val, host->base + MIO_EMM_INT_EN(host)); 112 writeq(val, host->base + MIO_EMM_INT_EN(host));
113} 113}
114 114
@@ -267,7 +267,7 @@ static int octeon_mmc_probe(struct platform_device *pdev)
267 } 267 }
268 268
269 host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev, 269 host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev,
270 "power-gpios", 270 "power",
271 GPIOD_OUT_HIGH); 271 GPIOD_OUT_HIGH);
272 if (IS_ERR(host->global_pwr_gpiod)) { 272 if (IS_ERR(host->global_pwr_gpiod)) {
273 dev_err(&pdev->dev, "Invalid power GPIO\n"); 273 dev_err(&pdev->dev, "Invalid power GPIO\n");
@@ -288,11 +288,20 @@ static int octeon_mmc_probe(struct platform_device *pdev)
288 if (ret) { 288 if (ret) {
289 dev_err(&pdev->dev, "Error populating slots\n"); 289 dev_err(&pdev->dev, "Error populating slots\n");
290 octeon_mmc_set_shared_power(host, 0); 290 octeon_mmc_set_shared_power(host, 0);
291 return ret; 291 goto error;
292 } 292 }
293 i++; 293 i++;
294 } 294 }
295 return 0; 295 return 0;
296
297error:
298 for (i = 0; i < CAVIUM_MAX_MMC; i++) {
299 if (host->slot[i])
300 cvm_mmc_of_slot_remove(host->slot[i]);
301 if (host->slot_pdev[i])
302 of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
303 }
304 return ret;
296} 305}
297 306
298static int octeon_mmc_remove(struct platform_device *pdev) 307static int octeon_mmc_remove(struct platform_device *pdev)
diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c
index fe3d77267cd6..b9cc95998799 100644
--- a/drivers/mmc/host/cavium-thunderx.c
+++ b/drivers/mmc/host/cavium-thunderx.c
@@ -146,6 +146,12 @@ static int thunder_mmc_probe(struct pci_dev *pdev,
146 return 0; 146 return 0;
147 147
148error: 148error:
149 for (i = 0; i < CAVIUM_MAX_MMC; i++) {
150 if (host->slot[i])
151 cvm_mmc_of_slot_remove(host->slot[i]);
152 if (host->slot_pdev[i])
153 of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
154 }
149 clk_disable_unprepare(host->clk); 155 clk_disable_unprepare(host->clk);
150 return ret; 156 return ret;
151} 157}
diff --git a/drivers/mmc/host/cavium.c b/drivers/mmc/host/cavium.c
index 58b51ba6aabd..b8aaf0fdb77c 100644
--- a/drivers/mmc/host/cavium.c
+++ b/drivers/mmc/host/cavium.c
@@ -839,14 +839,14 @@ static void cvm_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
839 cvm_mmc_reset_bus(slot); 839 cvm_mmc_reset_bus(slot);
840 if (host->global_pwr_gpiod) 840 if (host->global_pwr_gpiod)
841 host->set_shared_power(host, 0); 841 host->set_shared_power(host, 0);
842 else 842 else if (!IS_ERR(mmc->supply.vmmc))
843 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 843 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
844 break; 844 break;
845 845
846 case MMC_POWER_UP: 846 case MMC_POWER_UP:
847 if (host->global_pwr_gpiod) 847 if (host->global_pwr_gpiod)
848 host->set_shared_power(host, 1); 848 host->set_shared_power(host, 1);
849 else 849 else if (!IS_ERR(mmc->supply.vmmc))
850 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 850 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
851 break; 851 break;
852 } 852 }
@@ -968,20 +968,15 @@ static int cvm_mmc_of_parse(struct device *dev, struct cvm_mmc_slot *slot)
968 return -EINVAL; 968 return -EINVAL;
969 } 969 }
970 970
971 mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); 971 ret = mmc_regulator_get_supply(mmc);
972 if (IS_ERR(mmc->supply.vmmc)) { 972 if (ret == -EPROBE_DEFER)
973 if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) 973 return ret;
974 return -EPROBE_DEFER; 974 /*
975 /* 975 * Legacy Octeon firmware has no regulator entry, fall-back to
976 * Legacy Octeon firmware has no regulator entry, fall-back to 976 * a hard-coded voltage to get a sane OCR.
977 * a hard-coded voltage to get a sane OCR. 977 */
978 */ 978 if (IS_ERR(mmc->supply.vmmc))
979 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 979 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
980 } else {
981 ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
982 if (ret > 0)
983 mmc->ocr_avail = ret;
984 }
985 980
986 /* Common MMC bindings */ 981 /* Common MMC bindings */
987 ret = mmc_of_parse(mmc); 982 ret = mmc_of_parse(mmc);
diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 3275d4995812..61666d269771 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -187,7 +187,8 @@ static const struct sdhci_iproc_data iproc_cygnus_data = {
187}; 187};
188 188
189static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = { 189static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = {
190 .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, 190 .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
191 SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
191 .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN, 192 .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,
192 .ops = &sdhci_iproc_ops, 193 .ops = &sdhci_iproc_ops,
193}; 194};
diff --git a/drivers/mmc/host/sdhci-xenon-phy.c b/drivers/mmc/host/sdhci-xenon-phy.c
index 6356781f1cca..f7e26b031e76 100644
--- a/drivers/mmc/host/sdhci-xenon-phy.c
+++ b/drivers/mmc/host/sdhci-xenon-phy.c
@@ -787,14 +787,6 @@ int xenon_phy_adj(struct sdhci_host *host, struct mmc_ios *ios)
787 return ret; 787 return ret;
788} 788}
789 789
790void xenon_clean_phy(struct sdhci_host *host)
791{
792 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
793 struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
794
795 kfree(priv->phy_params);
796}
797
798static int xenon_add_phy(struct device_node *np, struct sdhci_host *host, 790static int xenon_add_phy(struct device_node *np, struct sdhci_host *host,
799 const char *phy_name) 791 const char *phy_name)
800{ 792{
@@ -819,11 +811,7 @@ static int xenon_add_phy(struct device_node *np, struct sdhci_host *host,
819 if (ret) 811 if (ret)
820 return ret; 812 return ret;
821 813
822 ret = xenon_emmc_phy_parse_param_dt(host, np, priv->phy_params); 814 return xenon_emmc_phy_parse_param_dt(host, np, priv->phy_params);
823 if (ret)
824 xenon_clean_phy(host);
825
826 return ret;
827} 815}
828 816
829int xenon_phy_parse_dt(struct device_node *np, struct sdhci_host *host) 817int xenon_phy_parse_dt(struct device_node *np, struct sdhci_host *host)
diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
index 67246655315b..bc1781bb070b 100644
--- a/drivers/mmc/host/sdhci-xenon.c
+++ b/drivers/mmc/host/sdhci-xenon.c
@@ -486,7 +486,7 @@ static int xenon_probe(struct platform_device *pdev)
486 486
487 err = xenon_sdhc_prepare(host); 487 err = xenon_sdhc_prepare(host);
488 if (err) 488 if (err)
489 goto clean_phy_param; 489 goto err_clk;
490 490
491 err = sdhci_add_host(host); 491 err = sdhci_add_host(host);
492 if (err) 492 if (err)
@@ -496,8 +496,6 @@ static int xenon_probe(struct platform_device *pdev)
496 496
497remove_sdhc: 497remove_sdhc:
498 xenon_sdhc_unprepare(host); 498 xenon_sdhc_unprepare(host);
499clean_phy_param:
500 xenon_clean_phy(host);
501err_clk: 499err_clk:
502 clk_disable_unprepare(pltfm_host->clk); 500 clk_disable_unprepare(pltfm_host->clk);
503free_pltfm: 501free_pltfm:
@@ -510,8 +508,6 @@ static int xenon_remove(struct platform_device *pdev)
510 struct sdhci_host *host = platform_get_drvdata(pdev); 508 struct sdhci_host *host = platform_get_drvdata(pdev);
511 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 509 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
512 510
513 xenon_clean_phy(host);
514
515 sdhci_remove_host(host, 0); 511 sdhci_remove_host(host, 0);
516 512
517 xenon_sdhc_unprepare(host); 513 xenon_sdhc_unprepare(host);
diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h
index 6e6523ea01ce..73debb42dc2f 100644
--- a/drivers/mmc/host/sdhci-xenon.h
+++ b/drivers/mmc/host/sdhci-xenon.h
@@ -93,7 +93,6 @@ struct xenon_priv {
93}; 93};
94 94
95int xenon_phy_adj(struct sdhci_host *host, struct mmc_ios *ios); 95int xenon_phy_adj(struct sdhci_host *host, struct mmc_ios *ios);
96void xenon_clean_phy(struct sdhci_host *host);
97int xenon_phy_parse_dt(struct device_node *np, 96int xenon_phy_parse_dt(struct device_node *np,
98 struct sdhci_host *host); 97 struct sdhci_host *host);
99void xenon_soc_pad_ctrl(struct sdhci_host *host, 98void xenon_soc_pad_ctrl(struct sdhci_host *host,
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 71fecc2debfc..703a42118ffc 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -523,7 +523,7 @@ static int __init of_platform_default_populate_init(void)
523arch_initcall_sync(of_platform_default_populate_init); 523arch_initcall_sync(of_platform_default_populate_init);
524#endif 524#endif
525 525
526static int of_platform_device_destroy(struct device *dev, void *data) 526int of_platform_device_destroy(struct device *dev, void *data)
527{ 527{
528 /* Do not touch devices not populated from the device tree */ 528 /* Do not touch devices not populated from the device tree */
529 if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) 529 if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED))
@@ -544,6 +544,7 @@ static int of_platform_device_destroy(struct device *dev, void *data)
544 of_node_clear_flag(dev->of_node, OF_POPULATED_BUS); 544 of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
545 return 0; 545 return 0;
546} 546}
547EXPORT_SYMBOL_GPL(of_platform_device_destroy);
547 548
548/** 549/**
549 * of_platform_depopulate() - Remove devices populated from device tree 550 * of_platform_depopulate() - Remove devices populated from device tree
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index dc8224ae28d5..e0d1946270f3 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -64,6 +64,7 @@ extern struct platform_device *of_platform_device_create(struct device_node *np,
64 const char *bus_id, 64 const char *bus_id,
65 struct device *parent); 65 struct device *parent);
66 66
67extern int of_platform_device_destroy(struct device *dev, void *data);
67extern int of_platform_bus_probe(struct device_node *root, 68extern int of_platform_bus_probe(struct device_node *root,
68 const struct of_device_id *matches, 69 const struct of_device_id *matches,
69 struct device *parent); 70 struct device *parent);