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.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
"MMC core:
- mmc: core: Avoid hang when claiming host

MMC host:
- dw_mmc: Avoid hang when accessing registers
- dw_mmc: Fix out-of-bounds access for slot's caps
- dw_mmc-k3: Fix out-of-bounds access through DT alias
- sdhci-pci: Fix S0i3 for Intel BYT-based controllers"

* tag 'mmc-v4.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
mmc: core: Avoid hanging to claim host for mmc via some nested calls
mmc: dw_mmc: Avoid accessing registers in runtime suspended state
mmc: dw_mmc: Fix out-of-bounds access for slot's caps
mmc: dw_mmc: Factor out dw_mci_init_slot_caps
mmc: dw_mmc-k3: Fix out-of-bounds access through DT alias
mmc: sdhci-pci: Fix S0i3 for Intel BYT-based controllers

+94 -38
-4
drivers/mmc/core/mmc_ops.c
··· 848 848 return 1; 849 849 } 850 850 851 - mmc_claim_host(card->host); 852 851 err = mmc_send_status(card, &status); 853 852 if (err) { 854 853 pr_err("%s: Get card status fail\n", mmc_hostname(card->host)); ··· 889 890 } while (!err); 890 891 891 892 out: 892 - mmc_release_host(card->host); 893 893 return err; 894 894 } 895 895 ··· 930 932 int err; 931 933 u8 *ext_csd; 932 934 933 - mmc_claim_host(card->host); 934 935 err = mmc_get_ext_csd(card, &ext_csd); 935 - mmc_release_host(card->host); 936 936 if (err) 937 937 return err; 938 938
+1
drivers/mmc/host/dw_mmc-exynos.c
··· 487 487 488 488 static const struct dw_mci_drv_data exynos_drv_data = { 489 489 .caps = exynos_dwmmc_caps, 490 + .num_caps = ARRAY_SIZE(exynos_dwmmc_caps), 490 491 .init = dw_mci_exynos_priv_init, 491 492 .set_ios = dw_mci_exynos_set_ios, 492 493 .parse_dt = dw_mci_exynos_parse_dt,
+4
drivers/mmc/host/dw_mmc-k3.c
··· 135 135 if (priv->ctrl_id < 0) 136 136 priv->ctrl_id = 0; 137 137 138 + if (priv->ctrl_id >= TIMING_MODE) 139 + return -EINVAL; 140 + 138 141 host->priv = priv; 139 142 return 0; 140 143 } ··· 210 207 211 208 static const struct dw_mci_drv_data hi6220_data = { 212 209 .caps = dw_mci_hi6220_caps, 210 + .num_caps = ARRAY_SIZE(dw_mci_hi6220_caps), 213 211 .switch_voltage = dw_mci_hi6220_switch_voltage, 214 212 .set_ios = dw_mci_hi6220_set_ios, 215 213 .parse_dt = dw_mci_hi6220_parse_dt,
+1
drivers/mmc/host/dw_mmc-rockchip.c
··· 319 319 320 320 static const struct dw_mci_drv_data rk3288_drv_data = { 321 321 .caps = dw_mci_rk3288_dwmmc_caps, 322 + .num_caps = ARRAY_SIZE(dw_mci_rk3288_dwmmc_caps), 322 323 .set_ios = dw_mci_rk3288_set_ios, 323 324 .execute_tuning = dw_mci_rk3288_execute_tuning, 324 325 .parse_dt = dw_mci_rk3288_parse_dt,
+1
drivers/mmc/host/dw_mmc-zx.c
··· 195 195 196 196 static const struct dw_mci_drv_data zx_drv_data = { 197 197 .caps = zx_dwmmc_caps, 198 + .num_caps = ARRAY_SIZE(zx_dwmmc_caps), 198 199 .execute_tuning = dw_mci_zx_execute_tuning, 199 200 .prepare_hs400_tuning = dw_mci_zx_prepare_hs400_tuning, 200 201 .parse_dt = dw_mci_zx_parse_dt,
+54 -30
drivers/mmc/host/dw_mmc.c
··· 165 165 { 166 166 struct dw_mci *host = s->private; 167 167 168 + pm_runtime_get_sync(host->dev); 169 + 168 170 seq_printf(s, "STATUS:\t0x%08x\n", mci_readl(host, STATUS)); 169 171 seq_printf(s, "RINTSTS:\t0x%08x\n", mci_readl(host, RINTSTS)); 170 172 seq_printf(s, "CMD:\t0x%08x\n", mci_readl(host, CMD)); 171 173 seq_printf(s, "CTRL:\t0x%08x\n", mci_readl(host, CTRL)); 172 174 seq_printf(s, "INTMASK:\t0x%08x\n", mci_readl(host, INTMASK)); 173 175 seq_printf(s, "CLKENA:\t0x%08x\n", mci_readl(host, CLKENA)); 176 + 177 + pm_runtime_put_autosuspend(host->dev); 174 178 175 179 return 0; 176 180 } ··· 2782 2778 return IRQ_HANDLED; 2783 2779 } 2784 2780 2781 + static int dw_mci_init_slot_caps(struct dw_mci_slot *slot) 2782 + { 2783 + struct dw_mci *host = slot->host; 2784 + const struct dw_mci_drv_data *drv_data = host->drv_data; 2785 + struct mmc_host *mmc = slot->mmc; 2786 + int ctrl_id; 2787 + 2788 + if (host->pdata->caps) 2789 + mmc->caps = host->pdata->caps; 2790 + 2791 + /* 2792 + * Support MMC_CAP_ERASE by default. 2793 + * It needs to use trim/discard/erase commands. 2794 + */ 2795 + mmc->caps |= MMC_CAP_ERASE; 2796 + 2797 + if (host->pdata->pm_caps) 2798 + mmc->pm_caps = host->pdata->pm_caps; 2799 + 2800 + if (host->dev->of_node) { 2801 + ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); 2802 + if (ctrl_id < 0) 2803 + ctrl_id = 0; 2804 + } else { 2805 + ctrl_id = to_platform_device(host->dev)->id; 2806 + } 2807 + 2808 + if (drv_data && drv_data->caps) { 2809 + if (ctrl_id >= drv_data->num_caps) { 2810 + dev_err(host->dev, "invalid controller id %d\n", 2811 + ctrl_id); 2812 + return -EINVAL; 2813 + } 2814 + mmc->caps |= drv_data->caps[ctrl_id]; 2815 + } 2816 + 2817 + if (host->pdata->caps2) 2818 + mmc->caps2 = host->pdata->caps2; 2819 + 2820 + /* Process SDIO IRQs through the sdio_irq_work. */ 2821 + if (mmc->caps & MMC_CAP_SDIO_IRQ) 2822 + mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; 2823 + 2824 + return 0; 2825 + } 2826 + 2785 2827 static int dw_mci_init_slot(struct dw_mci *host) 2786 2828 { 2787 2829 struct mmc_host *mmc; 2788 2830 struct dw_mci_slot *slot; 2789 - const struct dw_mci_drv_data *drv_data = host->drv_data; 2790 - int ctrl_id, ret; 2831 + int ret; 2791 2832 u32 freq[2]; 2792 2833 2793 2834 mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev); ··· 2866 2817 if (!mmc->ocr_avail) 2867 2818 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 2868 2819 2869 - if (host->pdata->caps) 2870 - mmc->caps = host->pdata->caps; 2871 - 2872 - /* 2873 - * Support MMC_CAP_ERASE by default. 2874 - * It needs to use trim/discard/erase commands. 2875 - */ 2876 - mmc->caps |= MMC_CAP_ERASE; 2877 - 2878 - if (host->pdata->pm_caps) 2879 - mmc->pm_caps = host->pdata->pm_caps; 2880 - 2881 - if (host->dev->of_node) { 2882 - ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); 2883 - if (ctrl_id < 0) 2884 - ctrl_id = 0; 2885 - } else { 2886 - ctrl_id = to_platform_device(host->dev)->id; 2887 - } 2888 - if (drv_data && drv_data->caps) 2889 - mmc->caps |= drv_data->caps[ctrl_id]; 2890 - 2891 - if (host->pdata->caps2) 2892 - mmc->caps2 = host->pdata->caps2; 2893 - 2894 2820 ret = mmc_of_parse(mmc); 2895 2821 if (ret) 2896 2822 goto err_host_allocated; 2897 2823 2898 - /* Process SDIO IRQs through the sdio_irq_work. */ 2899 - if (mmc->caps & MMC_CAP_SDIO_IRQ) 2900 - mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; 2824 + ret = dw_mci_init_slot_caps(slot); 2825 + if (ret) 2826 + goto err_host_allocated; 2901 2827 2902 2828 /* Useful defaults if platform data is unset. */ 2903 2829 if (host->use_dma == TRANS_MODE_IDMAC) {
+2
drivers/mmc/host/dw_mmc.h
··· 543 543 /** 544 544 * dw_mci driver data - dw-mshc implementation specific driver data. 545 545 * @caps: mmc subsystem specified capabilities of the controller(s). 546 + * @num_caps: number of capabilities specified by @caps. 546 547 * @init: early implementation specific initialization. 547 548 * @set_ios: handle bus specific extensions. 548 549 * @parse_dt: parse implementation specific device tree properties. ··· 555 554 */ 556 555 struct dw_mci_drv_data { 557 556 unsigned long *caps; 557 + u32 num_caps; 558 558 int (*init)(struct dw_mci *host); 559 559 void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); 560 560 int (*parse_dt)(struct dw_mci *host);
+31 -4
drivers/mmc/host/sdhci-pci-core.c
··· 654 654 slot->chip->rpm_retune = intel_host->d3_retune; 655 655 } 656 656 657 + static int intel_execute_tuning(struct mmc_host *mmc, u32 opcode) 658 + { 659 + int err = sdhci_execute_tuning(mmc, opcode); 660 + struct sdhci_host *host = mmc_priv(mmc); 661 + 662 + if (err) 663 + return err; 664 + 665 + /* 666 + * Tuning can leave the IP in an active state (Buffer Read Enable bit 667 + * set) which prevents the entry to low power states (i.e. S0i3). Data 668 + * reset will clear it. 669 + */ 670 + sdhci_reset(host, SDHCI_RESET_DATA); 671 + 672 + return 0; 673 + } 674 + 675 + static void byt_probe_slot(struct sdhci_pci_slot *slot) 676 + { 677 + struct mmc_host_ops *ops = &slot->host->mmc_host_ops; 678 + 679 + byt_read_dsm(slot); 680 + 681 + ops->execute_tuning = intel_execute_tuning; 682 + } 683 + 657 684 static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) 658 685 { 659 - byt_read_dsm(slot); 686 + byt_probe_slot(slot); 660 687 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | 661 688 MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR | 662 689 MMC_CAP_CMD_DURING_TFR | ··· 806 779 { 807 780 int err; 808 781 809 - byt_read_dsm(slot); 782 + byt_probe_slot(slot); 810 783 811 784 err = ni_set_max_freq(slot); 812 785 if (err) ··· 819 792 820 793 static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) 821 794 { 822 - byt_read_dsm(slot); 795 + byt_probe_slot(slot); 823 796 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE | 824 797 MMC_CAP_WAIT_WHILE_BUSY; 825 798 return 0; ··· 827 800 828 801 static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) 829 802 { 830 - byt_read_dsm(slot); 803 + byt_probe_slot(slot); 831 804 slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | 832 805 MMC_CAP_AGGRESSIVE_PM | MMC_CAP_CD_WAKE; 833 806 slot->cd_idx = 0;