Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+35 -39
+12 -3
drivers/mmc/host/cavium-octeon.c
··· 108 108 static void octeon_mmc_int_enable(struct cvm_mmc_host *host, u64 val) 109 109 { 110 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 112 writeq(val, host->base + MIO_EMM_INT_EN(host)); 113 113 } 114 114 ··· 267 267 } 268 268 269 269 host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev, 270 - "power-gpios", 270 + "power", 271 271 GPIOD_OUT_HIGH); 272 272 if (IS_ERR(host->global_pwr_gpiod)) { 273 273 dev_err(&pdev->dev, "Invalid power GPIO\n"); ··· 288 288 if (ret) { 289 289 dev_err(&pdev->dev, "Error populating slots\n"); 290 290 octeon_mmc_set_shared_power(host, 0); 291 - return ret; 291 + goto error; 292 292 } 293 293 i++; 294 294 } 295 295 return 0; 296 + 297 + error: 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 298 307 static int octeon_mmc_remove(struct platform_device *pdev)
+6
drivers/mmc/host/cavium-thunderx.c
··· 146 146 return 0; 147 147 148 148 error: 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 155 clk_disable_unprepare(host->clk); 150 156 return ret; 151 157 }
+10 -15
drivers/mmc/host/cavium.c
··· 839 839 cvm_mmc_reset_bus(slot); 840 840 if (host->global_pwr_gpiod) 841 841 host->set_shared_power(host, 0); 842 - else 842 + else if (!IS_ERR(mmc->supply.vmmc)) 843 843 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 844 844 break; 845 845 846 846 case MMC_POWER_UP: 847 847 if (host->global_pwr_gpiod) 848 848 host->set_shared_power(host, 1); 849 - else 849 + else if (!IS_ERR(mmc->supply.vmmc)) 850 850 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 851 851 break; 852 852 } ··· 968 968 return -EINVAL; 969 969 } 970 970 971 - mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc"); 972 - if (IS_ERR(mmc->supply.vmmc)) { 973 - if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER) 974 - return -EPROBE_DEFER; 975 - /* 976 - * Legacy Octeon firmware has no regulator entry, fall-back to 977 - * a hard-coded voltage to get a sane OCR. 978 - */ 971 + ret = mmc_regulator_get_supply(mmc); 972 + if (ret == -EPROBE_DEFER) 973 + return ret; 974 + /* 975 + * Legacy Octeon firmware has no regulator entry, fall-back to 976 + * a hard-coded voltage to get a sane OCR. 977 + */ 978 + if (IS_ERR(mmc->supply.vmmc)) 979 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 981 /* Common MMC bindings */ 987 982 ret = mmc_of_parse(mmc);
+2 -1
drivers/mmc/host/sdhci-iproc.c
··· 187 187 }; 188 188 189 189 static 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 192 .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN, 192 193 .ops = &sdhci_iproc_ops, 193 194 };
+1 -13
drivers/mmc/host/sdhci-xenon-phy.c
··· 787 787 return ret; 788 788 } 789 789 790 - void 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 - 798 790 static int xenon_add_phy(struct device_node *np, struct sdhci_host *host, 799 791 const char *phy_name) 800 792 { ··· 811 819 if (ret) 812 820 return ret; 813 821 814 - ret = xenon_emmc_phy_parse_param_dt(host, np, priv->phy_params); 815 - if (ret) 816 - xenon_clean_phy(host); 817 - 818 - return ret; 822 + return xenon_emmc_phy_parse_param_dt(host, np, priv->phy_params); 819 823 } 820 824 821 825 int xenon_phy_parse_dt(struct device_node *np, struct sdhci_host *host)
+1 -5
drivers/mmc/host/sdhci-xenon.c
··· 486 486 487 487 err = xenon_sdhc_prepare(host); 488 488 if (err) 489 - goto clean_phy_param; 489 + goto err_clk; 490 490 491 491 err = sdhci_add_host(host); 492 492 if (err) ··· 496 496 497 497 remove_sdhc: 498 498 xenon_sdhc_unprepare(host); 499 - clean_phy_param: 500 - xenon_clean_phy(host); 501 499 err_clk: 502 500 clk_disable_unprepare(pltfm_host->clk); 503 501 free_pltfm: ··· 507 509 { 508 510 struct sdhci_host *host = platform_get_drvdata(pdev); 509 511 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 510 - 511 - xenon_clean_phy(host); 512 512 513 513 sdhci_remove_host(host, 0); 514 514
-1
drivers/mmc/host/sdhci-xenon.h
··· 93 93 }; 94 94 95 95 int xenon_phy_adj(struct sdhci_host *host, struct mmc_ios *ios); 96 - void xenon_clean_phy(struct sdhci_host *host); 97 96 int xenon_phy_parse_dt(struct device_node *np, 98 97 struct sdhci_host *host); 99 98 void xenon_soc_pad_ctrl(struct sdhci_host *host,
+2 -1
drivers/of/platform.c
··· 523 523 arch_initcall_sync(of_platform_default_populate_init); 524 524 #endif 525 525 526 - static int of_platform_device_destroy(struct device *dev, void *data) 526 + int of_platform_device_destroy(struct device *dev, void *data) 527 527 { 528 528 /* Do not touch devices not populated from the device tree */ 529 529 if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) ··· 544 544 of_node_clear_flag(dev->of_node, OF_POPULATED_BUS); 545 545 return 0; 546 546 } 547 + EXPORT_SYMBOL_GPL(of_platform_device_destroy); 547 548 548 549 /** 549 550 * of_platform_depopulate() - Remove devices populated from device tree
+1
include/linux/of_platform.h
··· 64 64 const char *bus_id, 65 65 struct device *parent); 66 66 67 + extern int of_platform_device_destroy(struct device *dev, void *data); 67 68 extern int of_platform_bus_probe(struct device_node *root, 68 69 const struct of_device_id *matches, 69 70 struct device *parent);