From 2ac55d5e5ec9ad0a07e194f0eaca865fe5aa3c40 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 17 Oct 2019 15:25:36 +0200 Subject: mmc: core: Re-work HW reset for SDIO cards It have turned out that it's not a good idea to unconditionally do a power cycle and then to re-initialize the SDIO card, as currently done through mmc_hw_reset() -> mmc_sdio_hw_reset(). This because there may be multiple SDIO func drivers probed, who also shares the same SDIO card. To address these scenarios, one may be tempted to use a notification mechanism, as to allow the core to inform each of the probed func drivers, about an ongoing HW reset. However, supporting such an operation from the func driver point of view, may not be entirely trivial. Therefore, let's use a more simplistic approach to solve the problem, by instead forcing the card to be removed and re-detected, via scheduling a rescan-work. In this way, we can rely on existing infrastructure, as the func driver's ->remove() and ->probe() callbacks, becomes invoked to deal with the cleanup and the re-initialization. This solution may be considered as rather heavy, especially if a func driver doesn't share its card with other func drivers. To address this, let's keep the current immediate HW reset option as well, but run it only when there is one func driver probed for the card. Finally, to allow the caller of mmc_hw_reset(), to understand if the reset is being asynchronously managed from a scheduled work, it returns 1 (propagated from mmc_sdio_hw_reset()). If the HW reset is executed successfully and synchronously it returns 0, which maintains the existing behaviour. Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Ulf Hansson --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 9b6336ad3266..e459b38ef33c 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -291,6 +291,7 @@ struct mmc_card { struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ unsigned int sdio_funcs; /* number of SDIO functions */ + atomic_t sdio_funcs_probed; /* number of probed SDIO funcs */ struct sdio_cccr cccr; /* common card info */ struct sdio_cis cis; /* common tuple info */ struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */ -- cgit v1.2.3-70-g09d2 From 4d219f4cf0322ab40c1b21a836a6d4b61e01216f Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Thu, 7 Nov 2019 11:30:41 +0100 Subject: mmc: host: omap-hsmmc: remove init_card pdata callback from pdata Now as we have removed the last user (pandora_wl1251_init_card) of this callback, we can remove it from the hsmmc code. Suggested-by: Ulf Hansson Signed-off-by: H. Nikolaus Schaller Signed-off-by: Ulf Hansson --- drivers/mmc/host/omap_hsmmc.c | 5 +---- include/linux/platform_data/hsmmc-omap.h | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d0df054b0b47..767e964ca5a2 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1510,10 +1510,7 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) { struct omap_hsmmc_host *host = mmc_priv(mmc); - if (mmc_pdata(host)->init_card) - mmc_pdata(host)->init_card(card); - else if (card->type == MMC_TYPE_SDIO || - card->type == MMC_TYPE_SD_COMBO) { + if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { struct device_node *np = mmc_dev(mmc)->of_node; /* diff --git a/include/linux/platform_data/hsmmc-omap.h b/include/linux/platform_data/hsmmc-omap.h index e79d238ff18f..7124a5f4bf06 100644 --- a/include/linux/platform_data/hsmmc-omap.h +++ b/include/linux/platform_data/hsmmc-omap.h @@ -67,9 +67,6 @@ struct omap_hsmmc_platform_data { /* string specifying a particular variant of hardware */ char *version; - /* if we have special card, init it using this callback */ - void (*init_card)(struct mmc_card *card); - const char *name; u32 ocr_mask; }; -- cgit v1.2.3-70-g09d2 From e5db673e7fe2f971ec82039a28dc0811c2100e87 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Thu, 7 Nov 2019 11:30:42 +0100 Subject: mmc: sdio: fix wl1251 vendor id v4.11-rc1 did introduce a patch series that rearranged the sdio quirks into a header file. Unfortunately this did forget to handle SDIO_VENDOR_ID_TI differently between wl1251 and wl1271 with the result that although the wl1251 was found on the sdio bus, the firmware did not load any more and there was no interface registration. This patch defines separate constants to be used by sdio quirks and drivers. Fixes: 884f38607897 ("mmc: core: move some sdio IDs out of quirks file") Signed-off-by: H. Nikolaus Schaller Cc: # v4.11+ Signed-off-by: Ulf Hansson --- include/linux/mmc/sdio_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index d1a5d5df02f5..08b25c02b5a1 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -71,6 +71,8 @@ #define SDIO_VENDOR_ID_TI 0x0097 #define SDIO_DEVICE_ID_TI_WL1271 0x4076 +#define SDIO_VENDOR_ID_TI_WL1251 0x104c +#define SDIO_DEVICE_ID_TI_WL1251 0x9066 #define SDIO_VENDOR_ID_STE 0x0020 #define SDIO_DEVICE_ID_STE_CW1200 0x2280 -- cgit v1.2.3-70-g09d2 From f3d7c2292d104519195fdb11192daec13229c219 Mon Sep 17 00:00:00 2001 From: Bradley Bolen Date: Sat, 16 Nov 2019 20:00:45 -0500 Subject: mmc: core: Fix size overflow for mmc partitions With large eMMC cards, it is possible to create general purpose partitions that are bigger than 4GB. The size member of the mmc_part struct is only an unsigned int which overflows for gp partitions larger than 4GB. Change this to a u64 to handle the overflow. Signed-off-by: Bradley Bolen Signed-off-by: Ulf Hansson --- drivers/mmc/core/mmc.c | 9 ++++----- include/linux/mmc/card.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index c8804895595f..f6912ded652d 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -297,7 +297,7 @@ static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) } } -static void mmc_part_add(struct mmc_card *card, unsigned int size, +static void mmc_part_add(struct mmc_card *card, u64 size, unsigned int part_cfg, char *name, int idx, bool ro, int area_type) { @@ -313,7 +313,7 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) { int idx; u8 hc_erase_grp_sz, hc_wp_grp_sz; - unsigned int part_size; + u64 part_size; /* * General purpose partition feature support -- @@ -343,8 +343,7 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] << 8) + ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; - part_size *= (size_t)(hc_erase_grp_sz * - hc_wp_grp_sz); + part_size *= (hc_erase_grp_sz * hc_wp_grp_sz); mmc_part_add(card, part_size << 19, EXT_CSD_PART_CONFIG_ACC_GP0 + idx, "gp%d", idx, false, @@ -362,7 +361,7 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) { int err = 0, idx; - unsigned int part_size; + u64 part_size; struct device_node *np; bool broken_hpi = false; diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index e459b38ef33c..cf3780a6ccc4 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -226,7 +226,7 @@ struct mmc_queue_req; * MMC Physical partitions */ struct mmc_part { - unsigned int size; /* partition size (in bytes) */ + u64 size; /* partition size (in bytes) */ unsigned int part_cfg; /* partition type */ char name[MAX_MMC_PART_NAME_LEN]; bool force_ro; /* to make boot parts RO by default */ -- cgit v1.2.3-70-g09d2 From 1ed7d5c8f82d2aebabb6fe24f436a68bdd8c1065 Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Wed, 20 Nov 2019 12:17:27 +0530 Subject: firmware: xilinx: Add SDIO Tap Delay nodes Add tap delay nodes for setting SDIO Tap Delays on ZynqMP platform. Signed-off-by: Manish Narani Signed-off-by: Ulf Hansson --- include/linux/firmware/xlnx-zynqmp.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 778abbbc7d94..df366f1a4cb4 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -91,7 +91,8 @@ enum pm_ret_status { }; enum pm_ioctl_id { - IOCTL_SET_PLL_FRAC_MODE = 8, + IOCTL_SET_SD_TAPDELAY = 7, + IOCTL_SET_PLL_FRAC_MODE, IOCTL_GET_PLL_FRAC_MODE, IOCTL_SET_PLL_FRAC_DATA, IOCTL_GET_PLL_FRAC_DATA, @@ -250,6 +251,16 @@ enum zynqmp_pm_request_ack { ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING, }; +enum pm_node_id { + NODE_SD_0 = 39, + NODE_SD_1, +}; + +enum tap_delay_type { + PM_TAPDELAY_INPUT = 0, + PM_TAPDELAY_OUTPUT, +}; + /** * struct zynqmp_pm_query_data - PM query data * @qid: query ID -- cgit v1.2.3-70-g09d2