diff options
Diffstat (limited to 'drivers/mmc')
39 files changed, 834 insertions, 555 deletions
| diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 90e1bcd03b46..4e61b28a002f 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -264,7 +264,7 @@ static ssize_t power_ro_lock_store(struct device *dev,  		goto out_put;  	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP; -	blk_execute_rq(NULL, req, 0); +	blk_execute_rq(req, false);  	ret = req_to_mmc_queue_req(req)->drv_op_result;  	blk_mq_free_request(req); @@ -657,7 +657,7 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;  	req_to_mmc_queue_req(req)->drv_op_data = idatas;  	req_to_mmc_queue_req(req)->ioc_count = 1; -	blk_execute_rq(NULL, req, 0); +	blk_execute_rq(req, false);  	ioc_err = req_to_mmc_queue_req(req)->drv_op_result;  	err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata);  	blk_mq_free_request(req); @@ -726,7 +726,7 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,  		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;  	req_to_mmc_queue_req(req)->drv_op_data = idata;  	req_to_mmc_queue_req(req)->ioc_count = num_of_cmds; -	blk_execute_rq(NULL, req, 0); +	blk_execute_rq(req, false);  	ioc_err = req_to_mmc_queue_req(req)->drv_op_result;  	/* copy to user if data and response */ @@ -1837,7 +1837,7 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)  	/* Reset if the card is in a bad state */  	if (!mmc_host_is_spi(mq->card->host) &&  	    err && mmc_blk_reset(md, card->host, type)) { -		pr_err("%s: recovery failed!\n", req->rq_disk->disk_name); +		pr_err("%s: recovery failed!\n", req->q->disk->disk_name);  		mqrq->retries = MMC_NO_RETRIES;  		return;  	} @@ -1908,8 +1908,8 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)  	cb_data.card = card;  	cb_data.status = 0; -	err = __mmc_poll_for_busy(card, MMC_BLK_TIMEOUT_MS, &mmc_blk_busy_cb, -				  &cb_data); +	err = __mmc_poll_for_busy(card->host, MMC_BLK_TIMEOUT_MS, +				  &mmc_blk_busy_cb, &cb_data);  	/*  	 * Do not assume data transferred correctly if there are any error bits @@ -2051,7 +2051,8 @@ static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req)  		mmc_put_card(mq->card, &mq->ctx);  } -static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req) +static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req, +				bool can_sleep)  {  	struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);  	struct mmc_request *mrq = &mqrq->brq.mrq; @@ -2063,10 +2064,14 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req)  	 * Block layer timeouts race with completions which means the normal  	 * completion path cannot be used during recovery.  	 */ -	if (mq->in_recovery) +	if (mq->in_recovery) {  		mmc_blk_mq_complete_rq(mq, req); -	else if (likely(!blk_should_fake_timeout(req->q))) -		blk_mq_complete_request(req); +	} else if (likely(!blk_should_fake_timeout(req->q))) { +		if (can_sleep) +			blk_mq_complete_request_direct(req, mmc_blk_mq_complete); +		else +			blk_mq_complete_request(req); +	}  	mmc_blk_mq_dec_in_flight(mq, req);  } @@ -2087,7 +2092,7 @@ void mmc_blk_mq_recovery(struct mmc_queue *mq)  	mmc_blk_urgent_bkops(mq, mqrq); -	mmc_blk_mq_post_req(mq, req); +	mmc_blk_mq_post_req(mq, req, true);  }  static void mmc_blk_mq_complete_prev_req(struct mmc_queue *mq, @@ -2106,7 +2111,7 @@ static void mmc_blk_mq_complete_prev_req(struct mmc_queue *mq,  	if (prev_req)  		*prev_req = mq->complete_req;  	else -		mmc_blk_mq_post_req(mq, mq->complete_req); +		mmc_blk_mq_post_req(mq, mq->complete_req, true);  	mq->complete_req = NULL; @@ -2178,7 +2183,8 @@ static void mmc_blk_mq_req_done(struct mmc_request *mrq)  	mq->rw_wait = false;  	wake_up(&mq->wait); -	mmc_blk_mq_post_req(mq, req); +	/* context unknown */ +	mmc_blk_mq_post_req(mq, req, false);  }  static bool mmc_blk_rw_wait_cond(struct mmc_queue *mq, int *err) @@ -2238,7 +2244,7 @@ static int mmc_blk_mq_issue_rw_rq(struct mmc_queue *mq,  	err = mmc_start_request(host, &mqrq->brq.mrq);  	if (prev_req) -		mmc_blk_mq_post_req(mq, prev_req); +		mmc_blk_mq_post_req(mq, prev_req, true);  	if (err)  		mq->rw_wait = false; @@ -2395,10 +2401,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,  	md->disk->private_data = md;  	md->parent = parent;  	set_disk_ro(md->disk, md->read_only || default_ro); -	md->disk->flags = GENHD_FL_EXT_DEVT;  	if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) -		md->disk->flags |= GENHD_FL_NO_PART_SCAN -				   | GENHD_FL_SUPPRESS_PARTITION_INFO; +		md->disk->flags |= GENHD_FL_NO_PART;  	/*  	 * As discussed on lkml, GENHD_FL_REMOVABLE should: @@ -2739,7 +2743,7 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)  	if (IS_ERR(req))  		return PTR_ERR(req);  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS; -	blk_execute_rq(NULL, req, 0); +	blk_execute_rq(req, false);  	ret = req_to_mmc_queue_req(req)->drv_op_result;  	if (ret >= 0) {  		*val = ret; @@ -2778,7 +2782,7 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)  	}  	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD;  	req_to_mmc_queue_req(req)->drv_op_data = &ext_csd; -	blk_execute_rq(NULL, req, 0); +	blk_execute_rq(req, false);  	err = req_to_mmc_queue_req(req)->drv_op_result;  	blk_mq_free_request(req);  	if (err) { diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index f6b7a9c5bbff..096ae624be9a 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -53,16 +53,6 @@ static struct attribute *mmc_dev_attrs[] = {  };  ATTRIBUTE_GROUPS(mmc_dev); -/* - * This currently matches any MMC driver to any MMC card - drivers - * themselves make the decision whether to drive this card in their - * probe method. - */ -static int mmc_bus_match(struct device *dev, struct device_driver *drv) -{ -	return 1; -} -  static int  mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)  { @@ -226,7 +216,6 @@ static const struct dev_pm_ops mmc_bus_pm_ops = {  static struct bus_type mmc_bus_type = {  	.name		= "mmc",  	.dev_groups	= mmc_dev_groups, -	.match		= mmc_bus_match,  	.uevent		= mmc_bus_uevent,  	.probe		= mmc_bus_probe,  	.remove		= mmc_bus_remove, diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 7bd392d55cfa..99045e138ba4 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h @@ -59,6 +59,9 @@ struct mmc_fixup {  	/* for MMC cards */  	unsigned int ext_csd_rev; +	/* Match against functions declared in device tree */ +	const char *of_compatible; +  	void (*vendor_fixup)(struct mmc_card *card, int data);  	int data;  }; @@ -119,6 +122,21 @@ struct mmc_fixup {  		   _vendor, _device,					\  		   _fixup, _data, EXT_CSD_REV_ANY)			\ +#define SDIO_FIXUP_COMPATIBLE(_compatible, _fixup, _data)		\ +	{						\ +		.name = CID_NAME_ANY,			\ +		.manfid = CID_MANFID_ANY,		\ +		.oemid = CID_OEMID_ANY,			\ +		.rev_start = 0,				\ +		.rev_end = -1ull,			\ +		.cis_vendor = SDIO_ANY_ID,		\ +		.cis_device = SDIO_ANY_ID,		\ +		.vendor_fixup = (_fixup),		\ +		.data = (_data),			\ +		.ext_csd_rev = EXT_CSD_REV_ANY,		\ +		.of_compatible = _compatible,	\ +	} +  #define cid_rev(hwrev, fwrev, year, month)	\  	(((u64) hwrev) << 40 |			\  	 ((u64) fwrev) << 32 |			\ @@ -150,6 +168,24 @@ static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card,  	card->quirk_max_rate = data;  } +static inline void __maybe_unused wl1251_quirk(struct mmc_card *card, +					       int data) +{ +	/* +	 * We have TI wl1251 attached to this mmc. Pass this +	 * information to the SDIO core because it can't be +	 * probed by normal methods. +	 */ + +	dev_info(card->host->parent, "found wl1251\n"); +	card->quirks |= MMC_QUIRK_NONSTD_SDIO; +	card->cccr.wide_bus = 1; +	card->cis.vendor = 0x104c; +	card->cis.device = 0x9066; +	card->cis.blksize = 512; +	card->cis.max_dtr = 24000000; +} +  /*   * Quirk add/remove for MMC products.   */ diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index b1c1716dacf0..bbbbcaf70a59 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1962,7 +1962,7 @@ static int mmc_sleep(struct mmc_host *host)  		goto out_release;  	} -	err = __mmc_poll_for_busy(card, timeout_ms, &mmc_sleep_busy_cb, host); +	err = __mmc_poll_for_busy(host, timeout_ms, &mmc_sleep_busy_cb, host);  out_release:  	mmc_retune_release(host); diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 0c54858e89c0..d63d1c735335 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -58,6 +58,12 @@ struct mmc_busy_data {  	enum mmc_busy_cmd busy_cmd;  }; +struct mmc_op_cond_busy_data { +	struct mmc_host *host; +	u32 ocr; +	struct mmc_command *cmd; +}; +  int __mmc_send_status(struct mmc_card *card, u32 *status, unsigned int retries)  {  	int err; @@ -173,43 +179,62 @@ int mmc_go_idle(struct mmc_host *host)  	return err;  } +static int __mmc_send_op_cond_cb(void *cb_data, bool *busy) +{ +	struct mmc_op_cond_busy_data *data = cb_data; +	struct mmc_host *host = data->host; +	struct mmc_command *cmd = data->cmd; +	u32 ocr = data->ocr; +	int err = 0; + +	err = mmc_wait_for_cmd(host, cmd, 0); +	if (err) +		return err; + +	if (mmc_host_is_spi(host)) { +		if (!(cmd->resp[0] & R1_SPI_IDLE)) { +			*busy = false; +			return 0; +		} +	} else { +		if (cmd->resp[0] & MMC_CARD_BUSY) { +			*busy = false; +			return 0; +		} +	} + +	*busy = true; + +	/* +	 * According to eMMC specification v5.1 section 6.4.3, we +	 * should issue CMD1 repeatedly in the idle state until +	 * the eMMC is ready. Otherwise some eMMC devices seem to enter +	 * the inactive mode after mmc_init_card() issued CMD0 when +	 * the eMMC device is busy. +	 */ +	if (!ocr && !mmc_host_is_spi(host)) +		cmd->arg = cmd->resp[0] | BIT(30); + +	return 0; +} +  int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)  {  	struct mmc_command cmd = {}; -	int i, err = 0; +	int err = 0; +	struct mmc_op_cond_busy_data cb_data = { +		.host = host, +		.ocr = ocr, +		.cmd = &cmd +	};  	cmd.opcode = MMC_SEND_OP_COND;  	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;  	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR; -	for (i = 100; i; i--) { -		err = mmc_wait_for_cmd(host, &cmd, 0); -		if (err) -			break; - -		/* wait until reset completes */ -		if (mmc_host_is_spi(host)) { -			if (!(cmd.resp[0] & R1_SPI_IDLE)) -				break; -		} else { -			if (cmd.resp[0] & MMC_CARD_BUSY) -				break; -		} - -		err = -ETIMEDOUT; - -		mmc_delay(10); - -		/* -		 * According to eMMC specification v5.1 section 6.4.3, we -		 * should issue CMD1 repeatedly in the idle state until -		 * the eMMC is ready. Otherwise some eMMC devices seem to enter -		 * the inactive mode after mmc_init_card() issued CMD0 when -		 * the eMMC device is busy. -		 */ -		if (!ocr && !mmc_host_is_spi(host)) -			cmd.arg = cmd.resp[0] | BIT(30); -	} +	err = __mmc_poll_for_busy(host, 1000, &__mmc_send_op_cond_cb, &cb_data); +	if (err) +		return err;  	if (rocr && !mmc_host_is_spi(host))  		*rocr = cmd.resp[0]; @@ -470,11 +495,10 @@ static int mmc_busy_cb(void *cb_data, bool *busy)  	return 0;  } -int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, +int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms,  			int (*busy_cb)(void *cb_data, bool *busy),  			void *cb_data)  { -	struct mmc_host *host = card->host;  	int err;  	unsigned long timeout;  	unsigned int udelay = 32, udelay_max = 32768; @@ -515,13 +539,14 @@ EXPORT_SYMBOL_GPL(__mmc_poll_for_busy);  int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,  		      bool retry_crc_err, enum mmc_busy_cmd busy_cmd)  { +	struct mmc_host *host = card->host;  	struct mmc_busy_data cb_data;  	cb_data.card = card;  	cb_data.retry_crc_err = retry_crc_err;  	cb_data.busy_cmd = busy_cmd; -	return __mmc_poll_for_busy(card, timeout_ms, &mmc_busy_cb, &cb_data); +	return __mmc_poll_for_busy(host, timeout_ms, &mmc_busy_cb, &cb_data);  }  EXPORT_SYMBOL_GPL(mmc_poll_for_busy); diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index e5e94567a9a9..9c813b851d0b 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -41,7 +41,7 @@ int mmc_can_ext_csd(struct mmc_card *card);  int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);  bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd,  			  unsigned int timeout_ms); -int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, +int __mmc_poll_for_busy(struct mmc_host *host, unsigned int timeout_ms,  			int (*busy_cb)(void *cb_data, bool *busy),  			void *cb_data);  int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index ea4d3670560e..988467fbb621 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c @@ -54,7 +54,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,  		gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc,  					       reset_gpios->info, values); -		kfree(values); +		bitmap_free(values);  	}  } diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index b15c034b42fb..c69b2d9df6f1 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -234,7 +234,7 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,  	enum mmc_issue_type issue_type;  	enum mmc_issued issued;  	bool get_card, cqe_retune_ok; -	int ret; +	blk_status_t ret;  	if (mmc_card_removed(mq->card)) {  		req->rq_flags |= RQF_QUIET; diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index d68e6e513a4f..20f568727277 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -10,6 +10,7 @@   *   */ +#include <linux/of.h>  #include <linux/mmc/sdio_ids.h>  #include "card.h" @@ -145,6 +146,25 @@ static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = {  	END_FIXUP  }; +static const struct mmc_fixup __maybe_unused sdio_card_init_methods[] = { +	SDIO_FIXUP_COMPATIBLE("ti,wl1251", wl1251_quirk, 0), + +	END_FIXUP +}; + +static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card, +						 const char *compatible) +{ +	struct device_node *np; + +	for_each_child_of_node(mmc_dev(card->host)->of_node, np) { +		if (of_device_is_compatible(np, compatible)) +			return true; +	} + +	return false; +} +  static inline void mmc_fixup_device(struct mmc_card *card,  				    const struct mmc_fixup *table)  { @@ -152,22 +172,32 @@ static inline void mmc_fixup_device(struct mmc_card *card,  	u64 rev = cid_rev_card(card);  	for (f = table; f->vendor_fixup; f++) { -		if ((f->manfid == CID_MANFID_ANY || -		     f->manfid == card->cid.manfid) && -		    (f->oemid == CID_OEMID_ANY || -		     f->oemid == card->cid.oemid) && -		    (f->name == CID_NAME_ANY || -		     !strncmp(f->name, card->cid.prod_name, -			      sizeof(card->cid.prod_name))) && -		    (f->cis_vendor == card->cis.vendor || -		     f->cis_vendor == (u16) SDIO_ANY_ID) && -		    (f->cis_device == card->cis.device || -		     f->cis_device == (u16) SDIO_ANY_ID) && -		    (f->ext_csd_rev == EXT_CSD_REV_ANY || -		     f->ext_csd_rev == card->ext_csd.rev) && -		    rev >= f->rev_start && rev <= f->rev_end) { -			dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); -			f->vendor_fixup(card, f->data); -		} +		if (f->manfid != CID_MANFID_ANY && +		    f->manfid != card->cid.manfid) +			continue; +		if (f->oemid != CID_OEMID_ANY && +		    f->oemid != card->cid.oemid) +			continue; +		if (f->name != CID_NAME_ANY && +		    strncmp(f->name, card->cid.prod_name, +			    sizeof(card->cid.prod_name))) +			continue; +		if (f->cis_vendor != (u16)SDIO_ANY_ID && +		    f->cis_vendor != card->cis.vendor) +			continue; +		if (f->cis_device != (u16)SDIO_ANY_ID && +		    f->cis_device != card->cis.device) +			continue; +		if (f->ext_csd_rev != EXT_CSD_REV_ANY && +		    f->ext_csd_rev != card->ext_csd.rev) +			continue; +		if (rev < f->rev_start || rev > f->rev_end) +			continue; +		if (f->of_compatible && +		    !mmc_fixup_of_compatible_match(card, f->of_compatible)) +			continue; + +		dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup); +		f->vendor_fixup(card, f->data);  	}  } diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c9db24e16af1..45f578793980 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1666,7 +1666,7 @@ static int sd_poweroff_notify(struct mmc_card *card)  	cb_data.card = card;  	cb_data.reg_buf = reg_buf; -	err = __mmc_poll_for_busy(card, SD_POWEROFF_NOTIFY_TIMEOUT_MS, +	err = __mmc_poll_for_busy(card->host, SD_POWEROFF_NOTIFY_TIMEOUT_MS,  				  &sd_busy_poweroff_notify_cb, &cb_data);  out: diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 68edf7a615be..41164748723d 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -707,6 +707,9 @@ try_again:  	 */  	if (host->ops->init_card)  		host->ops->init_card(host, card); +	mmc_fixup_device(card, sdio_card_init_methods); + +	card->ocr = ocr_card;  	/*  	 * If the host and card support UHS-I mode request the card @@ -820,7 +823,7 @@ try_again:  			goto mismatch;  		}  	} -	card->ocr = ocr_card; +  	mmc_fixup_device(card, sdio_fixup_methods);  	if (card->type == MMC_TYPE_SD_COMBO) { diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5af8494c31b5..52b0b27a6839 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -966,6 +966,7 @@ config MMC_REALTEK_USB  config MMC_SUNXI  	tristate "Allwinner sunxi SD/MMC Host Controller support"  	depends on ARCH_SUNXI || COMPILE_TEST +	depends on SUNXI_CCU  	help  	  This selects support for the SD/MMC Host Controller on  	  Allwinner sunxi SoCs. diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 0acc237843f7..a9a0837153d8 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -969,8 +969,10 @@ static int au1xmmc_probe(struct platform_device *pdev)  	}  	host->irq = platform_get_irq(pdev, 0); -	if (host->irq < 0) +	if (host->irq < 0) { +		ret = host->irq;  		goto out3; +	}  	mmc->ops = &au1xmmc_ops; diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c index 8c2361e66277..463b707d9e99 100644 --- a/drivers/mmc/host/bcm2835.c +++ b/drivers/mmc/host/bcm2835.c @@ -1293,14 +1293,12 @@ static int bcm2835_add_host(struct bcm2835_host *host)  		host->dma_cfg_tx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;  		host->dma_cfg_tx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -		host->dma_cfg_tx.slave_id = 13;		/* DREQ channel */  		host->dma_cfg_tx.direction = DMA_MEM_TO_DEV;  		host->dma_cfg_tx.src_addr = 0;  		host->dma_cfg_tx.dst_addr = host->phys_addr + SDDATA;  		host->dma_cfg_rx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;  		host->dma_cfg_rx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -		host->dma_cfg_rx.slave_id = 13;		/* DREQ channel */  		host->dma_cfg_rx.direction = DMA_DEV_TO_MEM;  		host->dma_cfg_rx.src_addr = host->phys_addr + SDDATA;  		host->dma_cfg_rx.dst_addr = 0; diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index c2dd29ef45c6..ca5be4445ae0 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -28,6 +28,7 @@ enum dw_mci_exynos_type {  	DW_MCI_TYPE_EXYNOS5420_SMU,  	DW_MCI_TYPE_EXYNOS7,  	DW_MCI_TYPE_EXYNOS7_SMU, +	DW_MCI_TYPE_ARTPEC8,  };  /* Exynos implementation specific driver private data */ @@ -69,6 +70,9 @@ static struct dw_mci_exynos_compatible {  	}, {  		.compatible	= "samsung,exynos7-dw-mshc-smu",  		.ctrl_type	= DW_MCI_TYPE_EXYNOS7_SMU, +	}, { +		.compatible	= "axis,artpec8-dw-mshc", +		.ctrl_type	= DW_MCI_TYPE_ARTPEC8,  	},  }; @@ -81,7 +85,8 @@ static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)  	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)  		return EXYNOS4210_FIXED_CIU_CLK_DIV;  	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +			priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;  	else  		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; @@ -122,6 +127,11 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)  				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);  	} +	if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) { +		/* Quirk needed for the ARTPEC-8 SoC */ +		host->quirks |= DW_MMC_QUIRK_EXTENDED_TMOUT; +	} +  	host->bus_hz /= (priv->ciu_div + 1);  	return 0; @@ -133,7 +143,8 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)  	u32 clksel;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		clksel = mci_readl(host, CLKSEL64);  	else  		clksel = mci_readl(host, CLKSEL); @@ -141,7 +152,8 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)  	clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		mci_writel(host, CLKSEL64, clksel);  	else  		mci_writel(host, CLKSEL, clksel); @@ -210,14 +222,16 @@ static int dw_mci_exynos_resume_noirq(struct device *dev)  		return ret;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		clksel = mci_readl(host, CLKSEL64);  	else  		clksel = mci_readl(host, CLKSEL);  	if (clksel & SDMMC_CLKSEL_WAKEUP_INT) {  		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +			priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  			mci_writel(host, CLKSEL64, clksel);  		else  			mci_writel(host, CLKSEL, clksel); @@ -238,7 +252,8 @@ static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)  	 * Not supported to configure register  	 * related to HS400  	 */ -	if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) { +	if ((priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) || +		(priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)) {  		if (timing == MMC_TIMING_MMC_HS400)  			dev_warn(host->dev,  				 "cannot configure HS400, unsupported chipset\n"); @@ -394,7 +409,8 @@ static inline u8 dw_mci_exynos_get_clksmpl(struct dw_mci *host)  	struct dw_mci_exynos_priv_data *priv = host->priv;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL64));  	else  		return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL)); @@ -406,13 +422,15 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)  	struct dw_mci_exynos_priv_data *priv = host->priv;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		clksel = mci_readl(host, CLKSEL64);  	else  		clksel = mci_readl(host, CLKSEL);  	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		mci_writel(host, CLKSEL64, clksel);  	else  		mci_writel(host, CLKSEL, clksel); @@ -425,7 +443,8 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)  	u8 sample;  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		clksel = mci_readl(host, CLKSEL64);  	else  		clksel = mci_readl(host, CLKSEL); @@ -434,7 +453,8 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)  	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || -		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || +		priv->ctrl_type == DW_MCI_TYPE_ARTPEC8)  		mci_writel(host, CLKSEL64, clksel);  	else  		mci_writel(host, CLKSEL, clksel); @@ -524,17 +544,65 @@ static int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,  	return 0;  } +static void dw_mci_exynos_set_data_timeout(struct dw_mci *host, +					   unsigned int timeout_ns) +{ +	u32 clk_div, tmout; +	u64 tmp; +	unsigned int tmp2; + +	clk_div = (mci_readl(host, CLKDIV) & 0xFF) * 2; +	if (clk_div == 0) +		clk_div = 1; + +	tmp = DIV_ROUND_UP_ULL((u64)timeout_ns * host->bus_hz, NSEC_PER_SEC); +	tmp = DIV_ROUND_UP_ULL(tmp, clk_div); + +	/* TMOUT[7:0] (RESPONSE_TIMEOUT) */ +	tmout = 0xFF; /* Set maximum */ + +	/* +	 * Extended HW timer (max = 0x6FFFFF2): +	 * ((TMOUT[10:8] - 1) * 0xFFFFFF + TMOUT[31:11] * 8) +	 */ +	if (!tmp || tmp > 0x6FFFFF2) +		tmout |= (0xFFFFFF << 8); +	else { +		/* TMOUT[10:8] */ +		tmp2 = (((unsigned int)tmp / 0xFFFFFF) + 1) & 0x7; +		tmout |= tmp2 << 8; + +		/* TMOUT[31:11] */ +		tmp = tmp - ((tmp2 - 1) * 0xFFFFFF); +		tmout |= (tmp & 0xFFFFF8) << 8; +	} + +	mci_writel(host, TMOUT, tmout); +	dev_dbg(host->dev, "timeout_ns: %u => TMOUT[31:8]: %#08x", +		timeout_ns, tmout >> 8); +} + +static u32 dw_mci_exynos_get_drto_clks(struct dw_mci *host) +{ +	u32 drto_clks; + +	drto_clks = mci_readl(host, TMOUT) >> 8; + +	return (((drto_clks & 0x7) - 1) * 0xFFFFFF) + ((drto_clks & 0xFFFFF8)); +} +  /* Common capabilities of Exynos4/Exynos5 SoC */  static unsigned long exynos_dwmmc_caps[4] = { -	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, +	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA, +	0, +	0, +	0,  };  static const struct dw_mci_drv_data exynos_drv_data = {  	.caps			= exynos_dwmmc_caps,  	.num_caps		= ARRAY_SIZE(exynos_dwmmc_caps), +	.common_caps		= MMC_CAP_CMD23,  	.init			= dw_mci_exynos_priv_init,  	.set_ios		= dw_mci_exynos_set_ios,  	.parse_dt		= dw_mci_exynos_parse_dt, @@ -542,6 +610,16 @@ static const struct dw_mci_drv_data exynos_drv_data = {  	.prepare_hs400_tuning	= dw_mci_exynos_prepare_hs400_tuning,  }; +static const struct dw_mci_drv_data artpec_drv_data = { +	.common_caps		= MMC_CAP_CMD23, +	.init			= dw_mci_exynos_priv_init, +	.set_ios		= dw_mci_exynos_set_ios, +	.parse_dt		= dw_mci_exynos_parse_dt, +	.execute_tuning		= dw_mci_exynos_execute_tuning, +	.set_data_timeout		= dw_mci_exynos_set_data_timeout, +	.get_drto_clks		= dw_mci_exynos_get_drto_clks, +}; +  static const struct of_device_id dw_mci_exynos_match[] = {  	{ .compatible = "samsung,exynos4412-dw-mshc",  			.data = &exynos_drv_data, }, @@ -555,6 +633,8 @@ static const struct of_device_id dw_mci_exynos_match[] = {  			.data = &exynos_drv_data, },  	{ .compatible = "samsung,exynos7-dw-mshc-smu",  			.data = &exynos_drv_data, }, +	{ .compatible = "axis,artpec8-dw-mshc", +			.data = &artpec_drv_data, },  	{},  };  MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); diff --git a/drivers/mmc/host/dw_mmc-hi3798cv200.c b/drivers/mmc/host/dw_mmc-hi3798cv200.c index 39794f93826f..e9437ef8ef19 100644 --- a/drivers/mmc/host/dw_mmc-hi3798cv200.c +++ b/drivers/mmc/host/dw_mmc-hi3798cv200.c @@ -23,12 +23,6 @@ struct hi3798cv200_priv {  	struct clk *drive_clk;  }; -static unsigned long dw_mci_hi3798cv200_caps[] = { -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, -	MMC_CAP_CMD23 -}; -  static void dw_mci_hi3798cv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)  {  	struct hi3798cv200_priv *priv = host->priv; @@ -166,8 +160,7 @@ disable_sample_clk:  }  static const struct dw_mci_drv_data hi3798cv200_data = { -	.caps = dw_mci_hi3798cv200_caps, -	.num_caps = ARRAY_SIZE(dw_mci_hi3798cv200_caps), +	.common_caps = MMC_CAP_CMD23,  	.init = dw_mci_hi3798cv200_init,  	.set_ios = dw_mci_hi3798cv200_set_ios,  	.execute_tuning = dw_mci_hi3798cv200_execute_tuning, diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index d36991acd6df..95d0ec0f5f3a 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -300,21 +300,12 @@ static int dw_mci_rockchip_init(struct dw_mci *host)  	return 0;  } -/* Common capabilities of RK3288 SoC */ -static unsigned long dw_mci_rk3288_dwmmc_caps[4] = { -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, -	MMC_CAP_CMD23, -}; -  static const struct dw_mci_drv_data rk2928_drv_data = {  	.init			= dw_mci_rockchip_init,  };  static const struct dw_mci_drv_data rk3288_drv_data = { -	.caps			= dw_mci_rk3288_dwmmc_caps, -	.num_caps		= ARRAY_SIZE(dw_mci_rk3288_dwmmc_caps), +	.common_caps		= MMC_CAP_CMD23,  	.set_ios		= dw_mci_rk3288_set_ios,  	.execute_tuning		= dw_mci_rk3288_execute_tuning,  	.parse_dt		= dw_mci_rk3288_parse_dt, diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index d977f34f6b55..42bf8a2287ba 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -335,7 +335,8 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)  	    cmdr == MMC_WRITE_BLOCK ||  	    cmdr == MMC_WRITE_MULTIPLE_BLOCK ||  	    cmdr == MMC_SEND_TUNING_BLOCK || -	    cmdr == MMC_SEND_TUNING_BLOCK_HS200) { +	    cmdr == MMC_SEND_TUNING_BLOCK_HS200 || +	    cmdr == MMC_GEN_CMD) {  		stop->opcode = MMC_STOP_TRANSMISSION;  		stop->arg = 0;  		stop->flags = MMC_RSP_R1B | MMC_CMD_AC; @@ -1283,6 +1284,37 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)  	mci_writel(host, CTYPE, (slot->ctype << slot->id));  } +static void dw_mci_set_data_timeout(struct dw_mci *host, +				    unsigned int timeout_ns) +{ +	const struct dw_mci_drv_data *drv_data = host->drv_data; +	u32 clk_div, tmout; +	u64 tmp; + +	if (drv_data && drv_data->set_data_timeout) +		return drv_data->set_data_timeout(host, timeout_ns); + +	clk_div = (mci_readl(host, CLKDIV) & 0xFF) * 2; +	if (clk_div == 0) +		clk_div = 1; + +	tmp = DIV_ROUND_UP_ULL((u64)timeout_ns * host->bus_hz, NSEC_PER_SEC); +	tmp = DIV_ROUND_UP_ULL(tmp, clk_div); + +	/* TMOUT[7:0] (RESPONSE_TIMEOUT) */ +	tmout = 0xFF; /* Set maximum */ + +	/* TMOUT[31:8] (DATA_TIMEOUT) */ +	if (!tmp || tmp > 0xFFFFFF) +		tmout |= (0xFFFFFF << 8); +	else +		tmout |= (tmp & 0xFFFFFF) << 8; + +	mci_writel(host, TMOUT, tmout); +	dev_dbg(host->dev, "timeout_ns: %u => TMOUT[31:8]: %#08x", +		timeout_ns, tmout >> 8); +} +  static void __dw_mci_start_request(struct dw_mci *host,  				   struct dw_mci_slot *slot,  				   struct mmc_command *cmd) @@ -1303,7 +1335,7 @@ static void __dw_mci_start_request(struct dw_mci *host,  	data = cmd->data;  	if (data) { -		mci_writel(host, TMOUT, 0xFFFFFFFF); +		dw_mci_set_data_timeout(host, data->timeout_ns);  		mci_writel(host, BYTCNT, data->blksz*data->blocks);  		mci_writel(host, BLKSIZ, data->blksz);  	} @@ -1967,12 +1999,16 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data)  static void dw_mci_set_drto(struct dw_mci *host)  { +	const struct dw_mci_drv_data *drv_data = host->drv_data;  	unsigned int drto_clks;  	unsigned int drto_div;  	unsigned int drto_ms;  	unsigned long irqflags; -	drto_clks = mci_readl(host, TMOUT) >> 8; +	if (drv_data && drv_data->get_drto_clks) +		drto_clks = drv_data->get_drto_clks(host); +	else +		drto_clks = mci_readl(host, TMOUT) >> 8;  	drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2;  	if (drto_div == 0)  		drto_div = 1; @@ -1980,6 +2016,8 @@ static void dw_mci_set_drto(struct dw_mci *host)  	drto_ms = DIV_ROUND_UP_ULL((u64)MSEC_PER_SEC * drto_clks * drto_div,  				   host->bus_hz); +	dev_dbg(host->dev, "drto_ms: %u\n", drto_ms); +  	/* add a bit spare time */  	drto_ms += 10; @@ -2724,11 +2762,20 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & DW_MCI_DATA_ERROR_FLAGS) {  			spin_lock(&host->irq_lock); +			if (host->quirks & DW_MMC_QUIRK_EXTENDED_TMOUT) +				del_timer(&host->dto_timer); +  			/* if there is an error report DATA_ERROR */  			mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS);  			host->data_status = pending;  			smp_wmb(); /* drain writebuffer */  			set_bit(EVENT_DATA_ERROR, &host->pending_events); + +			if (host->quirks & DW_MMC_QUIRK_EXTENDED_TMOUT) +				/* In case of error, we cannot expect a DTO */ +				set_bit(EVENT_DATA_COMPLETE, +					&host->pending_events); +  			tasklet_schedule(&host->tasklet);  			spin_unlock(&host->irq_lock); @@ -2828,6 +2875,9 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)  	if (host->pdata->pm_caps)  		mmc->pm_caps = host->pdata->pm_caps; +	if (drv_data) +		mmc->caps |= drv_data->common_caps; +  	if (host->dev->of_node) {  		ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");  		if (ctrl_id < 0) diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index ce05d81477d9..7f1e38621d13 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -118,6 +118,7 @@ struct dw_mci_dma_slave {   * @part_buf: Simple buffer for partial fifo reads/writes.   * @push_data: Pointer to FIFO push function.   * @pull_data: Pointer to FIFO pull function. + * @quirks: Set of quirks that apply to specific versions of the IP.   * @vqmmc_enabled: Status of vqmmc, should be true or false.   * @irq_flags: The flags to be passed to request_irq.   * @irq: The irq value to be passed to request_irq. @@ -223,6 +224,7 @@ struct dw_mci {  	void (*push_data)(struct dw_mci *host, void *buf, int cnt);  	void (*pull_data)(struct dw_mci *host, void *buf, int cnt); +	u32			quirks;  	bool			vqmmc_enabled;  	unsigned long		irq_flags; /* IRQ flags */  	int			irq; @@ -274,6 +276,9 @@ struct dw_mci_board {  	struct dma_pdata *data;  }; +/* Support for longer data read timeout */ +#define DW_MMC_QUIRK_EXTENDED_TMOUT            BIT(0) +  #define DW_MMC_240A		0x240a  #define DW_MMC_280A		0x280a @@ -550,10 +555,14 @@ struct dw_mci_slot {   * dw_mci driver data - dw-mshc implementation specific driver data.   * @caps: mmc subsystem specified capabilities of the controller(s).   * @num_caps: number of capabilities specified by @caps. + * @common_caps: mmc subsystem specified capabilities applicable to all of + *	the controllers   * @init: early implementation specific initialization.   * @set_ios: handle bus specific extensions.   * @parse_dt: parse implementation specific device tree properties.   * @execute_tuning: implementation specific tuning procedure. + * @set_data_timeout: implementation specific timeout. + * @get_drto_clks: implementation specific cycle count for data read timeout.   *   * Provide controller implementation specific extensions. The usage of this   * data structure is fully optional and usage of each member in this structure @@ -562,6 +571,7 @@ struct dw_mci_slot {  struct dw_mci_drv_data {  	unsigned long	*caps;  	u32		num_caps; +	u32		common_caps;  	int		(*init)(struct dw_mci *host);  	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);  	int		(*parse_dt)(struct dw_mci *host); @@ -570,5 +580,8 @@ struct dw_mci_drv_data {  						struct mmc_ios *ios);  	int		(*switch_voltage)(struct mmc_host *mmc,  					  struct mmc_ios *ios); +	void		(*set_data_timeout)(struct dw_mci *host, +					  unsigned int timeout_ns); +	u32		(*get_drto_clks)(struct dw_mci *host);  };  #endif /* _DW_MMC_H_ */ diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 80a2c270d502..7ab1b38a7be5 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -217,11 +217,23 @@ static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host)  		return;  	dma_release_channel(host->dma_tx); -	dma_release_channel(host->dma_rx); +	if (host->dma_rx) +		dma_release_channel(host->dma_rx);  }  static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)  { +	struct device *dev = mmc_dev(host->mmc); + +	host->dma_tx = dma_request_chan(dev, "tx-rx"); +	if (!IS_ERR(host->dma_tx)) +		return 0; + +	if (PTR_ERR(host->dma_tx) != -ENODEV) { +		dev_err(dev, "Failed to get dma tx-rx channel\n"); +		return PTR_ERR(host->dma_tx); +	} +  	host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx");  	if (IS_ERR(host->dma_tx)) {  		dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); @@ -241,7 +253,10 @@ static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)  static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host,  						       struct mmc_data *data)  { -	return (data->flags & MMC_DATA_READ) ? host->dma_rx : host->dma_tx; +	if ((data->flags & MMC_DATA_READ) && host->dma_rx) +		return host->dma_rx; +	else +		return host->dma_tx;  }  static void jz4740_mmc_dma_unmap(struct jz4740_mmc_host *host, @@ -1103,18 +1118,18 @@ static int jz4740_mmc_remove(struct platform_device *pdev)  	return 0;  } -static int __maybe_unused jz4740_mmc_suspend(struct device *dev) +static int jz4740_mmc_suspend(struct device *dev)  {  	return pinctrl_pm_select_sleep_state(dev);  } -static int __maybe_unused jz4740_mmc_resume(struct device *dev) +static int jz4740_mmc_resume(struct device *dev)  {  	return pinctrl_select_default_state(dev);  } -static SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, -	jz4740_mmc_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend, +				jz4740_mmc_resume);  static struct platform_driver jz4740_mmc_driver = {  	.probe = jz4740_mmc_probe, @@ -1123,7 +1138,7 @@ static struct platform_driver jz4740_mmc_driver = {  		.name = "jz4740-mmc",  		.probe_type = PROBE_PREFER_ASYNCHRONOUS,  		.of_match_table = of_match_ptr(jz4740_mmc_of_match), -		.pm = pm_ptr(&jz4740_mmc_pm_ops), +		.pm = pm_sleep_ptr(&jz4740_mmc_pm_ops),  	},  }; diff --git a/drivers/mmc/host/meson-mx-sdhc-clkc.c b/drivers/mmc/host/meson-mx-sdhc-clkc.c index e1f29b279123..19200b7079a6 100644 --- a/drivers/mmc/host/meson-mx-sdhc-clkc.c +++ b/drivers/mmc/host/meson-mx-sdhc-clkc.c @@ -12,8 +12,6 @@  #include "meson-mx-sdhc.h" -#define MESON_SDHC_NUM_BUILTIN_CLKS	6 -  struct meson_mx_sdhc_clkc {  	struct clk_mux			src_sel;  	struct clk_divider		div; diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c index 8fdd0bbbfa21..28aa78aa08f3 100644 --- a/drivers/mmc/host/meson-mx-sdhc-mmc.c +++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c @@ -854,6 +854,11 @@ static int meson_mx_sdhc_probe(struct platform_device *pdev)  		goto err_disable_pclk;  	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		ret = irq; +		goto err_disable_pclk; +	} +  	ret = devm_request_threaded_irq(dev, irq, meson_mx_sdhc_irq,  					meson_mx_sdhc_irq_thread, IRQF_ONESHOT,  					NULL, host); diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c index d4a48916bfb6..3a19a05ef55a 100644 --- a/drivers/mmc/host/meson-mx-sdio.c +++ b/drivers/mmc/host/meson-mx-sdio.c @@ -662,6 +662,11 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)  	}  	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		ret = irq; +		goto error_free_mmc; +	} +  	ret = devm_request_threaded_irq(host->controller_dev, irq,  					meson_mx_mmc_irq,  					meson_mx_mmc_irq_thread, IRQF_ONESHOT, diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index b431cdd27353..a576181e9db0 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -547,7 +547,7 @@ mmc_spi_command_send(struct mmc_spi_host *host,  static void  mmc_spi_setup_data_message(  	struct mmc_spi_host	*host, -	int			multiple, +	bool			multiple,  	enum dma_data_direction	direction)  {  	struct spi_transfer	*t; @@ -859,14 +859,14 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,  	struct spi_device	*spi = host->spi;  	struct device		*dma_dev = host->dma_dev;  	struct spi_transfer	*t; -	enum dma_data_direction	direction; +	enum dma_data_direction	direction = mmc_get_dma_dir(data);  	struct scatterlist	*sg;  	unsigned		n_sg; -	int			multiple = (data->blocks > 1); +	bool			multiple = (data->blocks > 1); +	const char		*write_or_read = (direction == DMA_TO_DEVICE) ? "write" : "read";  	u32			clock_rate;  	unsigned long		timeout; -	direction = mmc_get_dma_dir(data);  	mmc_spi_setup_data_message(host, multiple, direction);  	t = &host->t; @@ -921,9 +921,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,  		while (length) {  			t->len = min(length, blk_size); -			dev_dbg(&host->spi->dev, "    %s block, %d bytes\n", -				(direction == DMA_TO_DEVICE) ? "write" : "read", -				t->len); +			dev_dbg(&spi->dev, "    %s block, %d bytes\n", write_or_read, t->len);  			if (direction == DMA_TO_DEVICE)  				status = mmc_spi_writeblock(host, t, timeout); @@ -948,9 +946,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,  		if (status < 0) {  			data->error = status; -			dev_dbg(&spi->dev, "%s status %d\n", -				(direction == DMA_TO_DEVICE) ? "write" : "read", -				status); +			dev_dbg(&spi->dev, "%s status %d\n", write_or_read, status);  			break;  		}  	} diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index c9cacd4d5b22..45b8608c935c 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -280,7 +280,7 @@ static struct variant_data variant_stm32_sdmmc = {  static struct variant_data variant_stm32_sdmmcv2 = {  	.fifosize		= 16 * 4,  	.fifohalfsize		= 8 * 4, -	.f_max			= 208000000, +	.f_max			= 267000000,  	.stm32_clkdiv		= true,  	.cmdreg_cpsm_enable	= MCI_CPSM_STM32_ENABLE,  	.cmdreg_lrsp_crc	= MCI_CPSM_STM32_LRSP_CRC, @@ -2435,6 +2435,11 @@ static const struct amba_id mmci_ids[] = {  		.mask	= 0xf0ffffff,  		.data	= &variant_stm32_sdmmcv2,  	}, +	{ +		.id     = 0x20253180, +		.mask	= 0xf0ffffff, +		.data	= &variant_stm32_sdmmcv2, +	},  	/* Qualcomm variants */  	{  		.id     = 0x00051180, diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c index a75d3dd34d18..9c13f2c31365 100644 --- a/drivers/mmc/host/mmci_stm32_sdmmc.c +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c @@ -241,11 +241,12 @@ static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired)  	/*  	 * SDMMC_FBCK is selected when an external Delay Block is needed -	 * with SDR104. +	 * with SDR104 or HS200.  	 */  	if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) {  		clk |= MCI_STM32_CLK_BUSSPEED; -		if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) { +		if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104 || +		    host->mmc->ios.timing == MMC_TIMING_MMC_HS200) {  			clk &= ~MCI_STM32_CLK_SEL_MSK;  			clk |= MCI_STM32_CLK_SELFBCK;  		} diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 632775217d35..65037e1d7723 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -5,6 +5,7 @@   */  #include <linux/module.h> +#include <linux/bitops.h>  #include <linux/clk.h>  #include <linux/delay.h>  #include <linux/dma-mapping.h> @@ -98,226 +99,226 @@  /*--------------------------------------------------------------------------*/  /* MSDC_CFG mask */ -#define MSDC_CFG_MODE           (0x1 << 0)	/* RW */ -#define MSDC_CFG_CKPDN          (0x1 << 1)	/* RW */ -#define MSDC_CFG_RST            (0x1 << 2)	/* RW */ -#define MSDC_CFG_PIO            (0x1 << 3)	/* RW */ -#define MSDC_CFG_CKDRVEN        (0x1 << 4)	/* RW */ -#define MSDC_CFG_BV18SDT        (0x1 << 5)	/* RW */ -#define MSDC_CFG_BV18PSS        (0x1 << 6)	/* R  */ -#define MSDC_CFG_CKSTB          (0x1 << 7)	/* R  */ -#define MSDC_CFG_CKDIV          (0xff << 8)	/* RW */ -#define MSDC_CFG_CKMOD          (0x3 << 16)	/* RW */ -#define MSDC_CFG_HS400_CK_MODE  (0x1 << 18)	/* RW */ -#define MSDC_CFG_HS400_CK_MODE_EXTRA  (0x1 << 22)	/* RW */ -#define MSDC_CFG_CKDIV_EXTRA    (0xfff << 8)	/* RW */ -#define MSDC_CFG_CKMOD_EXTRA    (0x3 << 20)	/* RW */ +#define MSDC_CFG_MODE           BIT(0)	/* RW */ +#define MSDC_CFG_CKPDN          BIT(1)	/* RW */ +#define MSDC_CFG_RST            BIT(2)	/* RW */ +#define MSDC_CFG_PIO            BIT(3)	/* RW */ +#define MSDC_CFG_CKDRVEN        BIT(4)	/* RW */ +#define MSDC_CFG_BV18SDT        BIT(5)	/* RW */ +#define MSDC_CFG_BV18PSS        BIT(6)	/* R  */ +#define MSDC_CFG_CKSTB          BIT(7)	/* R  */ +#define MSDC_CFG_CKDIV          GENMASK(15, 8)	/* RW */ +#define MSDC_CFG_CKMOD          GENMASK(17, 16)	/* RW */ +#define MSDC_CFG_HS400_CK_MODE  BIT(18)	/* RW */ +#define MSDC_CFG_HS400_CK_MODE_EXTRA  BIT(22)	/* RW */ +#define MSDC_CFG_CKDIV_EXTRA    GENMASK(19, 8)	/* RW */ +#define MSDC_CFG_CKMOD_EXTRA    GENMASK(21, 20)	/* RW */  /* MSDC_IOCON mask */ -#define MSDC_IOCON_SDR104CKS    (0x1 << 0)	/* RW */ -#define MSDC_IOCON_RSPL         (0x1 << 1)	/* RW */ -#define MSDC_IOCON_DSPL         (0x1 << 2)	/* RW */ -#define MSDC_IOCON_DDLSEL       (0x1 << 3)	/* RW */ -#define MSDC_IOCON_DDR50CKD     (0x1 << 4)	/* RW */ -#define MSDC_IOCON_DSPLSEL      (0x1 << 5)	/* RW */ -#define MSDC_IOCON_W_DSPL       (0x1 << 8)	/* RW */ -#define MSDC_IOCON_D0SPL        (0x1 << 16)	/* RW */ -#define MSDC_IOCON_D1SPL        (0x1 << 17)	/* RW */ -#define MSDC_IOCON_D2SPL        (0x1 << 18)	/* RW */ -#define MSDC_IOCON_D3SPL        (0x1 << 19)	/* RW */ -#define MSDC_IOCON_D4SPL        (0x1 << 20)	/* RW */ -#define MSDC_IOCON_D5SPL        (0x1 << 21)	/* RW */ -#define MSDC_IOCON_D6SPL        (0x1 << 22)	/* RW */ -#define MSDC_IOCON_D7SPL        (0x1 << 23)	/* RW */ -#define MSDC_IOCON_RISCSZ       (0x3 << 24)	/* RW */ +#define MSDC_IOCON_SDR104CKS    BIT(0)	/* RW */ +#define MSDC_IOCON_RSPL         BIT(1)	/* RW */ +#define MSDC_IOCON_DSPL         BIT(2)	/* RW */ +#define MSDC_IOCON_DDLSEL       BIT(3)	/* RW */ +#define MSDC_IOCON_DDR50CKD     BIT(4)	/* RW */ +#define MSDC_IOCON_DSPLSEL      BIT(5)	/* RW */ +#define MSDC_IOCON_W_DSPL       BIT(8)	/* RW */ +#define MSDC_IOCON_D0SPL        BIT(16)	/* RW */ +#define MSDC_IOCON_D1SPL        BIT(17)	/* RW */ +#define MSDC_IOCON_D2SPL        BIT(18)	/* RW */ +#define MSDC_IOCON_D3SPL        BIT(19)	/* RW */ +#define MSDC_IOCON_D4SPL        BIT(20)	/* RW */ +#define MSDC_IOCON_D5SPL        BIT(21)	/* RW */ +#define MSDC_IOCON_D6SPL        BIT(22)	/* RW */ +#define MSDC_IOCON_D7SPL        BIT(23)	/* RW */ +#define MSDC_IOCON_RISCSZ       GENMASK(25, 24)	/* RW */  /* MSDC_PS mask */ -#define MSDC_PS_CDEN            (0x1 << 0)	/* RW */ -#define MSDC_PS_CDSTS           (0x1 << 1)	/* R  */ -#define MSDC_PS_CDDEBOUNCE      (0xf << 12)	/* RW */ -#define MSDC_PS_DAT             (0xff << 16)	/* R  */ -#define MSDC_PS_DATA1           (0x1 << 17)	/* R  */ -#define MSDC_PS_CMD             (0x1 << 24)	/* R  */ -#define MSDC_PS_WP              (0x1 << 31)	/* R  */ +#define MSDC_PS_CDEN            BIT(0)	/* RW */ +#define MSDC_PS_CDSTS           BIT(1)	/* R  */ +#define MSDC_PS_CDDEBOUNCE      GENMASK(15, 12)	/* RW */ +#define MSDC_PS_DAT             GENMASK(23, 16)	/* R  */ +#define MSDC_PS_DATA1           BIT(17)	/* R  */ +#define MSDC_PS_CMD             BIT(24)	/* R  */ +#define MSDC_PS_WP              BIT(31)	/* R  */  /* MSDC_INT mask */ -#define MSDC_INT_MMCIRQ         (0x1 << 0)	/* W1C */ -#define MSDC_INT_CDSC           (0x1 << 1)	/* W1C */ -#define MSDC_INT_ACMDRDY        (0x1 << 3)	/* W1C */ -#define MSDC_INT_ACMDTMO        (0x1 << 4)	/* W1C */ -#define MSDC_INT_ACMDCRCERR     (0x1 << 5)	/* W1C */ -#define MSDC_INT_DMAQ_EMPTY     (0x1 << 6)	/* W1C */ -#define MSDC_INT_SDIOIRQ        (0x1 << 7)	/* W1C */ -#define MSDC_INT_CMDRDY         (0x1 << 8)	/* W1C */ -#define MSDC_INT_CMDTMO         (0x1 << 9)	/* W1C */ -#define MSDC_INT_RSPCRCERR      (0x1 << 10)	/* W1C */ -#define MSDC_INT_CSTA           (0x1 << 11)	/* R */ -#define MSDC_INT_XFER_COMPL     (0x1 << 12)	/* W1C */ -#define MSDC_INT_DXFER_DONE     (0x1 << 13)	/* W1C */ -#define MSDC_INT_DATTMO         (0x1 << 14)	/* W1C */ -#define MSDC_INT_DATCRCERR      (0x1 << 15)	/* W1C */ -#define MSDC_INT_ACMD19_DONE    (0x1 << 16)	/* W1C */ -#define MSDC_INT_DMA_BDCSERR    (0x1 << 17)	/* W1C */ -#define MSDC_INT_DMA_GPDCSERR   (0x1 << 18)	/* W1C */ -#define MSDC_INT_DMA_PROTECT    (0x1 << 19)	/* W1C */ -#define MSDC_INT_CMDQ           (0x1 << 28)	/* W1C */ +#define MSDC_INT_MMCIRQ         BIT(0)	/* W1C */ +#define MSDC_INT_CDSC           BIT(1)	/* W1C */ +#define MSDC_INT_ACMDRDY        BIT(3)	/* W1C */ +#define MSDC_INT_ACMDTMO        BIT(4)	/* W1C */ +#define MSDC_INT_ACMDCRCERR     BIT(5)	/* W1C */ +#define MSDC_INT_DMAQ_EMPTY     BIT(6)	/* W1C */ +#define MSDC_INT_SDIOIRQ        BIT(7)	/* W1C */ +#define MSDC_INT_CMDRDY         BIT(8)	/* W1C */ +#define MSDC_INT_CMDTMO         BIT(9)	/* W1C */ +#define MSDC_INT_RSPCRCERR      BIT(10)	/* W1C */ +#define MSDC_INT_CSTA           BIT(11)	/* R */ +#define MSDC_INT_XFER_COMPL     BIT(12)	/* W1C */ +#define MSDC_INT_DXFER_DONE     BIT(13)	/* W1C */ +#define MSDC_INT_DATTMO         BIT(14)	/* W1C */ +#define MSDC_INT_DATCRCERR      BIT(15)	/* W1C */ +#define MSDC_INT_ACMD19_DONE    BIT(16)	/* W1C */ +#define MSDC_INT_DMA_BDCSERR    BIT(17)	/* W1C */ +#define MSDC_INT_DMA_GPDCSERR   BIT(18)	/* W1C */ +#define MSDC_INT_DMA_PROTECT    BIT(19)	/* W1C */ +#define MSDC_INT_CMDQ           BIT(28)	/* W1C */  /* MSDC_INTEN mask */ -#define MSDC_INTEN_MMCIRQ       (0x1 << 0)	/* RW */ -#define MSDC_INTEN_CDSC         (0x1 << 1)	/* RW */ -#define MSDC_INTEN_ACMDRDY      (0x1 << 3)	/* RW */ -#define MSDC_INTEN_ACMDTMO      (0x1 << 4)	/* RW */ -#define MSDC_INTEN_ACMDCRCERR   (0x1 << 5)	/* RW */ -#define MSDC_INTEN_DMAQ_EMPTY   (0x1 << 6)	/* RW */ -#define MSDC_INTEN_SDIOIRQ      (0x1 << 7)	/* RW */ -#define MSDC_INTEN_CMDRDY       (0x1 << 8)	/* RW */ -#define MSDC_INTEN_CMDTMO       (0x1 << 9)	/* RW */ -#define MSDC_INTEN_RSPCRCERR    (0x1 << 10)	/* RW */ -#define MSDC_INTEN_CSTA         (0x1 << 11)	/* RW */ -#define MSDC_INTEN_XFER_COMPL   (0x1 << 12)	/* RW */ -#define MSDC_INTEN_DXFER_DONE   (0x1 << 13)	/* RW */ -#define MSDC_INTEN_DATTMO       (0x1 << 14)	/* RW */ -#define MSDC_INTEN_DATCRCERR    (0x1 << 15)	/* RW */ -#define MSDC_INTEN_ACMD19_DONE  (0x1 << 16)	/* RW */ -#define MSDC_INTEN_DMA_BDCSERR  (0x1 << 17)	/* RW */ -#define MSDC_INTEN_DMA_GPDCSERR (0x1 << 18)	/* RW */ -#define MSDC_INTEN_DMA_PROTECT  (0x1 << 19)	/* RW */ +#define MSDC_INTEN_MMCIRQ       BIT(0)	/* RW */ +#define MSDC_INTEN_CDSC         BIT(1)	/* RW */ +#define MSDC_INTEN_ACMDRDY      BIT(3)	/* RW */ +#define MSDC_INTEN_ACMDTMO      BIT(4)	/* RW */ +#define MSDC_INTEN_ACMDCRCERR   BIT(5)	/* RW */ +#define MSDC_INTEN_DMAQ_EMPTY   BIT(6)	/* RW */ +#define MSDC_INTEN_SDIOIRQ      BIT(7)	/* RW */ +#define MSDC_INTEN_CMDRDY       BIT(8)	/* RW */ +#define MSDC_INTEN_CMDTMO       BIT(9)	/* RW */ +#define MSDC_INTEN_RSPCRCERR    BIT(10)	/* RW */ +#define MSDC_INTEN_CSTA         BIT(11)	/* RW */ +#define MSDC_INTEN_XFER_COMPL   BIT(12)	/* RW */ +#define MSDC_INTEN_DXFER_DONE   BIT(13)	/* RW */ +#define MSDC_INTEN_DATTMO       BIT(14)	/* RW */ +#define MSDC_INTEN_DATCRCERR    BIT(15)	/* RW */ +#define MSDC_INTEN_ACMD19_DONE  BIT(16)	/* RW */ +#define MSDC_INTEN_DMA_BDCSERR  BIT(17)	/* RW */ +#define MSDC_INTEN_DMA_GPDCSERR BIT(18)	/* RW */ +#define MSDC_INTEN_DMA_PROTECT  BIT(19)	/* RW */  /* MSDC_FIFOCS mask */ -#define MSDC_FIFOCS_RXCNT       (0xff << 0)	/* R */ -#define MSDC_FIFOCS_TXCNT       (0xff << 16)	/* R */ -#define MSDC_FIFOCS_CLR         (0x1 << 31)	/* RW */ +#define MSDC_FIFOCS_RXCNT       GENMASK(7, 0)	/* R */ +#define MSDC_FIFOCS_TXCNT       GENMASK(23, 16)	/* R */ +#define MSDC_FIFOCS_CLR         BIT(31)	/* RW */  /* SDC_CFG mask */ -#define SDC_CFG_SDIOINTWKUP     (0x1 << 0)	/* RW */ -#define SDC_CFG_INSWKUP         (0x1 << 1)	/* RW */ -#define SDC_CFG_WRDTOC          (0x1fff  << 2)  /* RW */ -#define SDC_CFG_BUSWIDTH        (0x3 << 16)	/* RW */ -#define SDC_CFG_SDIO            (0x1 << 19)	/* RW */ -#define SDC_CFG_SDIOIDE         (0x1 << 20)	/* RW */ -#define SDC_CFG_INTATGAP        (0x1 << 21)	/* RW */ -#define SDC_CFG_DTOC            (0xff << 24)	/* RW */ +#define SDC_CFG_SDIOINTWKUP     BIT(0)	/* RW */ +#define SDC_CFG_INSWKUP         BIT(1)	/* RW */ +#define SDC_CFG_WRDTOC          GENMASK(14, 2)  /* RW */ +#define SDC_CFG_BUSWIDTH        GENMASK(17, 16)	/* RW */ +#define SDC_CFG_SDIO            BIT(19)	/* RW */ +#define SDC_CFG_SDIOIDE         BIT(20)	/* RW */ +#define SDC_CFG_INTATGAP        BIT(21)	/* RW */ +#define SDC_CFG_DTOC            GENMASK(31, 24)	/* RW */  /* SDC_STS mask */ -#define SDC_STS_SDCBUSY         (0x1 << 0)	/* RW */ -#define SDC_STS_CMDBUSY         (0x1 << 1)	/* RW */ -#define SDC_STS_SWR_COMPL       (0x1 << 31)	/* RW */ +#define SDC_STS_SDCBUSY         BIT(0)	/* RW */ +#define SDC_STS_CMDBUSY         BIT(1)	/* RW */ +#define SDC_STS_SWR_COMPL       BIT(31)	/* RW */ -#define SDC_DAT1_IRQ_TRIGGER	(0x1 << 19)	/* RW */ +#define SDC_DAT1_IRQ_TRIGGER	BIT(19)	/* RW */  /* SDC_ADV_CFG0 mask */ -#define SDC_RX_ENHANCE_EN	(0x1 << 20)	/* RW */ +#define SDC_RX_ENHANCE_EN	BIT(20)	/* RW */  /* DMA_SA_H4BIT mask */ -#define DMA_ADDR_HIGH_4BIT      (0xf << 0)      /* RW */ +#define DMA_ADDR_HIGH_4BIT      GENMASK(3, 0)	/* RW */  /* MSDC_DMA_CTRL mask */ -#define MSDC_DMA_CTRL_START     (0x1 << 0)	/* W */ -#define MSDC_DMA_CTRL_STOP      (0x1 << 1)	/* W */ -#define MSDC_DMA_CTRL_RESUME    (0x1 << 2)	/* W */ -#define MSDC_DMA_CTRL_MODE      (0x1 << 8)	/* RW */ -#define MSDC_DMA_CTRL_LASTBUF   (0x1 << 10)	/* RW */ -#define MSDC_DMA_CTRL_BRUSTSZ   (0x7 << 12)	/* RW */ +#define MSDC_DMA_CTRL_START     BIT(0)	/* W */ +#define MSDC_DMA_CTRL_STOP      BIT(1)	/* W */ +#define MSDC_DMA_CTRL_RESUME    BIT(2)	/* W */ +#define MSDC_DMA_CTRL_MODE      BIT(8)	/* RW */ +#define MSDC_DMA_CTRL_LASTBUF   BIT(10)	/* RW */ +#define MSDC_DMA_CTRL_BRUSTSZ   GENMASK(14, 12)	/* RW */  /* MSDC_DMA_CFG mask */ -#define MSDC_DMA_CFG_STS        (0x1 << 0)	/* R */ -#define MSDC_DMA_CFG_DECSEN     (0x1 << 1)	/* RW */ -#define MSDC_DMA_CFG_AHBHPROT2  (0x2 << 8)	/* RW */ -#define MSDC_DMA_CFG_ACTIVEEN   (0x2 << 12)	/* RW */ -#define MSDC_DMA_CFG_CS12B16B   (0x1 << 16)	/* RW */ +#define MSDC_DMA_CFG_STS        BIT(0)	/* R */ +#define MSDC_DMA_CFG_DECSEN     BIT(1)	/* RW */ +#define MSDC_DMA_CFG_AHBHPROT2  BIT(9)	/* RW */ +#define MSDC_DMA_CFG_ACTIVEEN   BIT(13)	/* RW */ +#define MSDC_DMA_CFG_CS12B16B   BIT(16)	/* RW */  /* MSDC_PATCH_BIT mask */ -#define MSDC_PATCH_BIT_ODDSUPP    (0x1 <<  1)	/* RW */ -#define MSDC_INT_DAT_LATCH_CK_SEL (0x7 <<  7) -#define MSDC_CKGEN_MSDC_DLY_SEL   (0x1f << 10) -#define MSDC_PATCH_BIT_IODSSEL    (0x1 << 16)	/* RW */ -#define MSDC_PATCH_BIT_IOINTSEL   (0x1 << 17)	/* RW */ -#define MSDC_PATCH_BIT_BUSYDLY    (0xf << 18)	/* RW */ -#define MSDC_PATCH_BIT_WDOD       (0xf << 22)	/* RW */ -#define MSDC_PATCH_BIT_IDRTSEL    (0x1 << 26)	/* RW */ -#define MSDC_PATCH_BIT_CMDFSEL    (0x1 << 27)	/* RW */ -#define MSDC_PATCH_BIT_INTDLSEL   (0x1 << 28)	/* RW */ -#define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */ -#define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */ - -#define MSDC_PATCH_BIT1_CMDTA     (0x7 << 3)    /* RW */ -#define MSDC_PB1_BUSY_CHECK_SEL   (0x1 << 7)    /* RW */ -#define MSDC_PATCH_BIT1_STOP_DLY  (0xf << 8)    /* RW */ - -#define MSDC_PATCH_BIT2_CFGRESP   (0x1 << 15)   /* RW */ -#define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28)   /* RW */ -#define MSDC_PB2_SUPPORT_64G      (0x1 << 1)    /* RW */ -#define MSDC_PB2_RESPWAIT         (0x3 << 2)    /* RW */ -#define MSDC_PB2_RESPSTSENSEL     (0x7 << 16)   /* RW */ -#define MSDC_PB2_CRCSTSENSEL      (0x7 << 29)   /* RW */ - -#define MSDC_PAD_TUNE_DATWRDLY	  (0x1f <<  0)	/* RW */ -#define MSDC_PAD_TUNE_DATRRDLY	  (0x1f <<  8)	/* RW */ -#define MSDC_PAD_TUNE_CMDRDLY	  (0x1f << 16)  /* RW */ -#define MSDC_PAD_TUNE_CMDRRDLY	  (0x1f << 22)	/* RW */ -#define MSDC_PAD_TUNE_CLKTDLY	  (0x1f << 27)  /* RW */ -#define MSDC_PAD_TUNE_RXDLYSEL	  (0x1 << 15)   /* RW */ -#define MSDC_PAD_TUNE_RD_SEL	  (0x1 << 13)   /* RW */ -#define MSDC_PAD_TUNE_CMD_SEL	  (0x1 << 21)   /* RW */ - -#define PAD_DS_TUNE_DLY_SEL       (0x1 << 0)	/* RW */ -#define PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */ -#define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */ -#define PAD_DS_TUNE_DLY3	  (0x1f << 12)  /* RW */ - -#define PAD_CMD_TUNE_RX_DLY3	  (0x1f << 1)  /* RW */ +#define MSDC_PATCH_BIT_ODDSUPP    BIT(1)	/* RW */ +#define MSDC_INT_DAT_LATCH_CK_SEL GENMASK(9, 7) +#define MSDC_CKGEN_MSDC_DLY_SEL   GENMASK(14, 10) +#define MSDC_PATCH_BIT_IODSSEL    BIT(16)	/* RW */ +#define MSDC_PATCH_BIT_IOINTSEL   BIT(17)	/* RW */ +#define MSDC_PATCH_BIT_BUSYDLY    GENMASK(21, 18)	/* RW */ +#define MSDC_PATCH_BIT_WDOD       GENMASK(25, 22)	/* RW */ +#define MSDC_PATCH_BIT_IDRTSEL    BIT(26)	/* RW */ +#define MSDC_PATCH_BIT_CMDFSEL    BIT(27)	/* RW */ +#define MSDC_PATCH_BIT_INTDLSEL   BIT(28)	/* RW */ +#define MSDC_PATCH_BIT_SPCPUSH    BIT(29)	/* RW */ +#define MSDC_PATCH_BIT_DECRCTMO   BIT(30)	/* RW */ + +#define MSDC_PATCH_BIT1_CMDTA     GENMASK(5, 3)    /* RW */ +#define MSDC_PB1_BUSY_CHECK_SEL   BIT(7)    /* RW */ +#define MSDC_PATCH_BIT1_STOP_DLY  GENMASK(11, 8)    /* RW */ + +#define MSDC_PATCH_BIT2_CFGRESP   BIT(15)   /* RW */ +#define MSDC_PATCH_BIT2_CFGCRCSTS BIT(28)   /* RW */ +#define MSDC_PB2_SUPPORT_64G      BIT(1)    /* RW */ +#define MSDC_PB2_RESPWAIT         GENMASK(3, 2)   /* RW */ +#define MSDC_PB2_RESPSTSENSEL     GENMASK(18, 16) /* RW */ +#define MSDC_PB2_CRCSTSENSEL      GENMASK(31, 29) /* RW */ + +#define MSDC_PAD_TUNE_DATWRDLY	  GENMASK(4, 0)		/* RW */ +#define MSDC_PAD_TUNE_DATRRDLY	  GENMASK(12, 8)	/* RW */ +#define MSDC_PAD_TUNE_CMDRDLY	  GENMASK(20, 16)	/* RW */ +#define MSDC_PAD_TUNE_CMDRRDLY	  GENMASK(26, 22)	/* RW */ +#define MSDC_PAD_TUNE_CLKTDLY	  GENMASK(31, 27)	/* RW */ +#define MSDC_PAD_TUNE_RXDLYSEL	  BIT(15)   /* RW */ +#define MSDC_PAD_TUNE_RD_SEL	  BIT(13)   /* RW */ +#define MSDC_PAD_TUNE_CMD_SEL	  BIT(21)   /* RW */ + +#define PAD_DS_TUNE_DLY_SEL       BIT(0)	  /* RW */ +#define PAD_DS_TUNE_DLY1	  GENMASK(6, 2)   /* RW */ +#define PAD_DS_TUNE_DLY2	  GENMASK(11, 7)  /* RW */ +#define PAD_DS_TUNE_DLY3	  GENMASK(16, 12) /* RW */ + +#define PAD_CMD_TUNE_RX_DLY3	  GENMASK(5, 1)   /* RW */  /* EMMC51_CFG0 mask */ -#define CMDQ_RDAT_CNT		  (0x3ff << 12)	/* RW */ +#define CMDQ_RDAT_CNT		  GENMASK(21, 12) /* RW */ -#define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)   /* RW */ -#define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)   /* RW */ -#define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)   /* RW */ -#define EMMC50_CFG_CMD_RESP_SEL   (0x1 << 9)   /* RW */ +#define EMMC50_CFG_PADCMD_LATCHCK BIT(0)   /* RW */ +#define EMMC50_CFG_CRCSTS_EDGE    BIT(3)   /* RW */ +#define EMMC50_CFG_CFCSTS_SEL     BIT(4)   /* RW */ +#define EMMC50_CFG_CMD_RESP_SEL   BIT(9)   /* RW */  /* EMMC50_CFG1 mask */ -#define EMMC50_CFG1_DS_CFG        (0x1 << 28)  /* RW */ +#define EMMC50_CFG1_DS_CFG        BIT(28)  /* RW */ -#define EMMC50_CFG3_OUTS_WR       (0x1f << 0)  /* RW */ +#define EMMC50_CFG3_OUTS_WR       GENMASK(4, 0)  /* RW */ -#define SDC_FIFO_CFG_WRVALIDSEL   (0x1 << 24)  /* RW */ -#define SDC_FIFO_CFG_RDVALIDSEL   (0x1 << 25)  /* RW */ +#define SDC_FIFO_CFG_WRVALIDSEL   BIT(24)  /* RW */ +#define SDC_FIFO_CFG_RDVALIDSEL   BIT(25)  /* RW */  /* CQHCI_SETTING */ -#define CQHCI_RD_CMD_WND_SEL	  (0x1 << 14) /* RW */ -#define CQHCI_WR_CMD_WND_SEL	  (0x1 << 15) /* RW */ +#define CQHCI_RD_CMD_WND_SEL	  BIT(14) /* RW */ +#define CQHCI_WR_CMD_WND_SEL	  BIT(15) /* RW */  /* EMMC_TOP_CONTROL mask */ -#define PAD_RXDLY_SEL           (0x1 << 0)      /* RW */ -#define DELAY_EN                (0x1 << 1)      /* RW */ -#define PAD_DAT_RD_RXDLY2       (0x1f << 2)     /* RW */ -#define PAD_DAT_RD_RXDLY        (0x1f << 7)     /* RW */ -#define PAD_DAT_RD_RXDLY2_SEL   (0x1 << 12)     /* RW */ -#define PAD_DAT_RD_RXDLY_SEL    (0x1 << 13)     /* RW */ -#define DATA_K_VALUE_SEL        (0x1 << 14)     /* RW */ -#define SDC_RX_ENH_EN           (0x1 << 15)     /* TW */ +#define PAD_RXDLY_SEL           BIT(0)      /* RW */ +#define DELAY_EN                BIT(1)      /* RW */ +#define PAD_DAT_RD_RXDLY2       GENMASK(6, 2)     /* RW */ +#define PAD_DAT_RD_RXDLY        GENMASK(11, 7)    /* RW */ +#define PAD_DAT_RD_RXDLY2_SEL   BIT(12)     /* RW */ +#define PAD_DAT_RD_RXDLY_SEL    BIT(13)     /* RW */ +#define DATA_K_VALUE_SEL        BIT(14)     /* RW */ +#define SDC_RX_ENH_EN           BIT(15)     /* TW */  /* EMMC_TOP_CMD mask */ -#define PAD_CMD_RXDLY2          (0x1f << 0)     /* RW */ -#define PAD_CMD_RXDLY           (0x1f << 5)     /* RW */ -#define PAD_CMD_RD_RXDLY2_SEL   (0x1 << 10)     /* RW */ -#define PAD_CMD_RD_RXDLY_SEL    (0x1 << 11)     /* RW */ -#define PAD_CMD_TX_DLY          (0x1f << 12)    /* RW */ +#define PAD_CMD_RXDLY2          GENMASK(4, 0)	/* RW */ +#define PAD_CMD_RXDLY           GENMASK(9, 5)	/* RW */ +#define PAD_CMD_RD_RXDLY2_SEL   BIT(10)		/* RW */ +#define PAD_CMD_RD_RXDLY_SEL    BIT(11)		/* RW */ +#define PAD_CMD_TX_DLY          GENMASK(16, 12)	/* RW */  /* EMMC50_PAD_DS_TUNE mask */ -#define PAD_DS_DLY_SEL		(0x1 << 16)	/* RW */ -#define PAD_DS_DLY1		(0x1f << 10)	/* RW */ -#define PAD_DS_DLY3		(0x1f << 0)	/* RW */ +#define PAD_DS_DLY_SEL		BIT(16)	/* RW */ +#define PAD_DS_DLY1		GENMASK(14, 10)	/* RW */ +#define PAD_DS_DLY3		GENMASK(4, 0)	/* RW */ -#define REQ_CMD_EIO  (0x1 << 0) -#define REQ_CMD_TMO  (0x1 << 1) -#define REQ_DAT_ERR  (0x1 << 2) -#define REQ_STOP_EIO (0x1 << 3) -#define REQ_STOP_TMO (0x1 << 4) -#define REQ_CMD_BUSY (0x1 << 5) +#define REQ_CMD_EIO  BIT(0) +#define REQ_CMD_TMO  BIT(1) +#define REQ_DAT_ERR  BIT(2) +#define REQ_STOP_EIO BIT(3) +#define REQ_STOP_TMO BIT(4) +#define REQ_CMD_BUSY BIT(5) -#define MSDC_PREPARE_FLAG (0x1 << 0) -#define MSDC_ASYNC_FLAG (0x1 << 1) -#define MSDC_MMAP_FLAG (0x1 << 2) +#define MSDC_PREPARE_FLAG BIT(0) +#define MSDC_ASYNC_FLAG BIT(1) +#define MSDC_MMAP_FLAG BIT(2)  #define MTK_MMC_AUTOSUSPEND_DELAY	50  #define CMD_TIMEOUT         (HZ/10 * 5)	/* 100ms x5 */ @@ -331,17 +332,17 @@  /*--------------------------------------------------------------------------*/  struct mt_gpdma_desc {  	u32 gpd_info; -#define GPDMA_DESC_HWO		(0x1 << 0) -#define GPDMA_DESC_BDP		(0x1 << 1) -#define GPDMA_DESC_CHECKSUM	(0xff << 8) /* bit8 ~ bit15 */ -#define GPDMA_DESC_INT		(0x1 << 16) -#define GPDMA_DESC_NEXT_H4	(0xf << 24) -#define GPDMA_DESC_PTR_H4	(0xf << 28) +#define GPDMA_DESC_HWO		BIT(0) +#define GPDMA_DESC_BDP		BIT(1) +#define GPDMA_DESC_CHECKSUM	GENMASK(15, 8) +#define GPDMA_DESC_INT		BIT(16) +#define GPDMA_DESC_NEXT_H4	GENMASK(27, 24) +#define GPDMA_DESC_PTR_H4	GENMASK(31, 28)  	u32 next;  	u32 ptr;  	u32 gpd_data_len; -#define GPDMA_DESC_BUFLEN	(0xffff) /* bit0 ~ bit15 */ -#define GPDMA_DESC_EXTLEN	(0xff << 16) /* bit16 ~ bit23 */ +#define GPDMA_DESC_BUFLEN	GENMASK(15, 0) +#define GPDMA_DESC_EXTLEN	GENMASK(23, 16)  	u32 arg;  	u32 blknum;  	u32 cmd; @@ -349,17 +350,17 @@ struct mt_gpdma_desc {  struct mt_bdma_desc {  	u32 bd_info; -#define BDMA_DESC_EOL		(0x1 << 0) -#define BDMA_DESC_CHECKSUM	(0xff << 8) /* bit8 ~ bit15 */ -#define BDMA_DESC_BLKPAD	(0x1 << 17) -#define BDMA_DESC_DWPAD		(0x1 << 18) -#define BDMA_DESC_NEXT_H4	(0xf << 24) -#define BDMA_DESC_PTR_H4	(0xf << 28) +#define BDMA_DESC_EOL		BIT(0) +#define BDMA_DESC_CHECKSUM	GENMASK(15, 8) +#define BDMA_DESC_BLKPAD	BIT(17) +#define BDMA_DESC_DWPAD		BIT(18) +#define BDMA_DESC_NEXT_H4	GENMASK(27, 24) +#define BDMA_DESC_PTR_H4	GENMASK(31, 28)  	u32 next;  	u32 ptr;  	u32 bd_data_len; -#define BDMA_DESC_BUFLEN	(0xffff) /* bit0 ~ bit15 */ -#define BDMA_DESC_BUFLEN_EXT	(0xffffff) /* bit0 ~ bit23 */ +#define BDMA_DESC_BUFLEN	GENMASK(15, 0) +#define BDMA_DESC_BUFLEN_EXT	GENMASK(23, 0)  };  struct msdc_dma { @@ -636,12 +637,11 @@ static void msdc_reset_hw(struct msdc_host *host)  	u32 val;  	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); -	while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST) -		cpu_relax(); +	readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);  	sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); -	while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR) -		cpu_relax(); +	readl_poll_timeout(host->base + MSDC_FIFOCS, val, +			   !(val & MSDC_FIFOCS_CLR), 0, 0);  	val = readl(host->base + MSDC_INT);  	writel(val, host->base + MSDC_INT); @@ -725,7 +725,7 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,  	sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);  	dma_ctrl = readl_relaxed(host->base + MSDC_DMA_CTRL);  	dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); -	dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); +	dma_ctrl |= (MSDC_BURST_64B << 12 | BIT(8));  	writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL);  	if (host->dev_comp->support_64g)  		sdr_set_field(host->base + DMA_SA_H4BIT, DMA_ADDR_HIGH_4BIT, @@ -769,7 +769,7 @@ static u64 msdc_timeout_cal(struct msdc_host *host, u64 ns, u64 clks)  		do_div(timeout, clk_ns);  		timeout += clks;  		/* in 1048576 sclk cycle unit */ -		timeout = DIV_ROUND_UP(timeout, (0x1 << 20)); +		timeout = DIV_ROUND_UP(timeout, BIT(20));  		if (host->dev_comp->clk_div_bits == 8)  			sdr_get_field(host->base + MSDC_CFG,  				      MSDC_CFG_CKMOD, &mode); @@ -814,8 +814,9 @@ static void msdc_gate_clock(struct msdc_host *host)  	clk_disable_unprepare(host->h_clk);  } -static void msdc_ungate_clock(struct msdc_host *host) +static int msdc_ungate_clock(struct msdc_host *host)  { +	u32 val;  	int ret;  	clk_prepare_enable(host->h_clk); @@ -825,11 +826,11 @@ static void msdc_ungate_clock(struct msdc_host *host)  	ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);  	if (ret) {  		dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n"); -		return; +		return ret;  	} -	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) -		cpu_relax(); +	return readl_poll_timeout(host->base + MSDC_CFG, val, +				  (val & MSDC_CFG_CKSTB), 1, 20000);  }  static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) @@ -840,6 +841,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)  	u32 div;  	u32 sclk;  	u32 tune_reg = host->dev_comp->pad_tune_reg; +	u32 val;  	if (!hz) {  		dev_dbg(host->dev, "set mclk to 0\n"); @@ -899,14 +901,8 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)  		}  	}  	sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); -	/* -	 * As src_clk/HCLK use the same bit to gate/ungate, -	 * So if want to only gate src_clk, need gate its parent(mux). -	 */ -	if (host->src_clk_cg) -		clk_disable_unprepare(host->src_clk_cg); -	else -		clk_disable_unprepare(clk_get_parent(host->src_clk)); + +	clk_disable_unprepare(host->src_clk_cg);  	if (host->dev_comp->clk_div_bits == 8)  		sdr_set_field(host->base + MSDC_CFG,  			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV, @@ -915,13 +911,9 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)  		sdr_set_field(host->base + MSDC_CFG,  			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,  			      (mode << 12) | div); -	if (host->src_clk_cg) -		clk_prepare_enable(host->src_clk_cg); -	else -		clk_prepare_enable(clk_get_parent(host->src_clk)); -	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) -		cpu_relax(); +	clk_prepare_enable(host->src_clk_cg); +	readl_poll_timeout(host->base + MSDC_CFG, val, (val & MSDC_CFG_CKSTB), 0, 0);  	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);  	mmc->actual_clock = sclk;  	host->mclk = hz; @@ -1013,15 +1005,15 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,  	if ((opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int) -1) ||  	    opcode == MMC_STOP_TRANSMISSION) -		rawcmd |= (0x1 << 14); +		rawcmd |= BIT(14);  	else if (opcode == SD_SWITCH_VOLTAGE) -		rawcmd |= (0x1 << 30); +		rawcmd |= BIT(30);  	else if (opcode == SD_APP_SEND_SCR ||  		 opcode == SD_APP_SEND_NUM_WR_BLKS ||  		 (opcode == SD_SWITCH && mmc_cmd_type(cmd) == MMC_CMD_ADTC) ||  		 (opcode == SD_APP_SD_STATUS && mmc_cmd_type(cmd) == MMC_CMD_ADTC) ||  		 (opcode == MMC_SEND_EXT_CSD && mmc_cmd_type(cmd) == MMC_CMD_ADTC)) -		rawcmd |= (0x1 << 11); +		rawcmd |= BIT(11);  	if (cmd->data) {  		struct mmc_data *data = cmd->data; @@ -1029,16 +1021,16 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,  		if (mmc_op_multi(opcode)) {  			if (mmc_card_mmc(mmc->card) && mrq->sbc &&  			    !(mrq->sbc->arg & 0xFFFF0000)) -				rawcmd |= 0x2 << 28; /* AutoCMD23 */ +				rawcmd |= BIT(29); /* AutoCMD23 */  		}  		rawcmd |= ((data->blksz & 0xFFF) << 16);  		if (data->flags & MMC_DATA_WRITE) -			rawcmd |= (0x1 << 13); +			rawcmd |= BIT(13);  		if (data->blocks > 1) -			rawcmd |= (0x2 << 11); +			rawcmd |= BIT(12);  		else -			rawcmd |= (0x1 << 11); +			rawcmd |= BIT(11);  		/* Always use dma mode */  		sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_PIO); @@ -1231,13 +1223,13 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,  static inline bool msdc_cmd_is_ready(struct msdc_host *host,  		struct mmc_request *mrq, struct mmc_command *cmd)  { -	/* The max busy time we can endure is 20ms */ -	unsigned long tmo = jiffies + msecs_to_jiffies(20); +	u32 val; +	int ret; -	while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) && -			time_before(jiffies, tmo)) -		cpu_relax(); -	if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) { +	/* The max busy time we can endure is 20ms */ +	ret = readl_poll_timeout_atomic(host->base + SDC_STS, val, +					!(val & SDC_STS_CMDBUSY), 1, 20000); +	if (ret) {  		dev_err(host->dev, "CMD bus busy detected\n");  		host->error |= REQ_CMD_BUSY;  		msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); @@ -1245,12 +1237,10 @@ static inline bool msdc_cmd_is_ready(struct msdc_host *host,  	}  	if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) { -		tmo = jiffies + msecs_to_jiffies(20);  		/* R1B or with data, should check SDCBUSY */ -		while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) && -				time_before(jiffies, tmo)) -			cpu_relax(); -		if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) { +		ret = readl_poll_timeout_atomic(host->base + SDC_STS, val, +						!(val & SDC_STS_SDCBUSY), 1, 20000); +		if (ret) {  			dev_err(host->dev, "Controller busy detected\n");  			host->error |= REQ_CMD_BUSY;  			msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); @@ -1376,6 +1366,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,  	    (MSDC_INT_XFER_COMPL | MSDC_INT_DATCRCERR | MSDC_INT_DATTMO  	     | MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR  	     | MSDC_INT_DMA_PROTECT); +	u32 val; +	int ret;  	spin_lock_irqsave(&host->lock, flags);  	done = !host->data; @@ -1392,8 +1384,14 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,  				readl(host->base + MSDC_DMA_CFG));  		sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP,  				1); -		while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) -			cpu_relax(); + +		ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val, +						!(val & MSDC_DMA_CFG_STS), 1, 20000); +		if (ret) { +			dev_dbg(host->dev, "DMA stop timed out\n"); +			return false; +		} +  		sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask);  		dev_dbg(host->dev, "DMA stop\n"); @@ -1631,6 +1629,7 @@ static void msdc_init_hw(struct msdc_host *host)  {  	u32 val;  	u32 tune_reg = host->dev_comp->pad_tune_reg; +	struct mmc_host *mmc = mmc_from_priv(host);  	if (host->reset) {  		reset_control_assert(host->reset); @@ -1685,7 +1684,7 @@ static void msdc_init_hw(struct msdc_host *host)  	}  	if (host->dev_comp->busy_check) -		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7)); +		sdr_clr_bits(host->base + MSDC_PATCH_BIT1, BIT(7));  	if (host->dev_comp->async_fifo) {  		sdr_set_field(host->base + MSDC_PATCH_BIT2, @@ -1736,14 +1735,18 @@ static void msdc_init_hw(struct msdc_host *host)  				     MSDC_PAD_TUNE_RXDLYSEL);  	} -	/* Configure to enable SDIO mode. -	 * it's must otherwise sdio cmd5 failed -	 */ -	sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO); +	if (mmc->caps2 & MMC_CAP2_NO_SDIO) { +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIO); +		sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ); +		sdr_clr_bits(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER); +	} else { +		/* Configure to enable SDIO mode, otherwise SDIO CMD5 fails */ +		sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO); -	/* Config SDIO device detect interrupt function */ -	sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); -	sdr_set_bits(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER); +		/* Config SDIO device detect interrupt function */ +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); +		sdr_set_bits(host->base + SDC_ADV_CFG0, SDC_DAT1_IRQ_TRIGGER); +	}  	/* Configure to default data timeout */  	sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3); @@ -1865,7 +1868,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  static u32 test_delay_bit(u32 delay, u32 bit)  {  	bit %= PAD_DELAY_MAX; -	return delay & (1 << bit); +	return delay & BIT(bit);  }  static int get_delay_len(u32 delay, u32 start_bit) @@ -1970,9 +1973,9 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)  		for (j = 0; j < 3; j++) {  			mmc_send_tuning(mmc, opcode, &cmd_err);  			if (!cmd_err) { -				rise_delay |= (1 << i); +				rise_delay |= BIT(i);  			} else { -				rise_delay &= ~(1 << i); +				rise_delay &= ~BIT(i);  				break;  			}  		} @@ -1994,9 +1997,9 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)  		for (j = 0; j < 3; j++) {  			mmc_send_tuning(mmc, opcode, &cmd_err);  			if (!cmd_err) { -				fall_delay |= (1 << i); +				fall_delay |= BIT(i);  			} else { -				fall_delay &= ~(1 << i); +				fall_delay &= ~BIT(i);  				break;  			}  		} @@ -2024,7 +2027,7 @@ skip_fall:  			      MSDC_PAD_TUNE_CMDRRDLY, i);  		mmc_send_tuning(mmc, opcode, &cmd_err);  		if (!cmd_err) -			internal_delay |= (1 << i); +			internal_delay |= BIT(i);  	}  	dev_dbg(host->dev, "Final internal delay: 0x%x\n", internal_delay);  	internal_delay_phase = get_best_delay(host, internal_delay); @@ -2069,9 +2072,9 @@ static int hs400_tune_response(struct mmc_host *mmc, u32 opcode)  		for (j = 0; j < 3; j++) {  			mmc_send_tuning(mmc, opcode, &cmd_err);  			if (!cmd_err) { -				cmd_delay |= (1 << i); +				cmd_delay |= BIT(i);  			} else { -				cmd_delay &= ~(1 << i); +				cmd_delay &= ~BIT(i);  				break;  			}  		} @@ -2101,7 +2104,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)  		msdc_set_data_delay(host, i);  		ret = mmc_send_tuning(mmc, opcode, NULL);  		if (!ret) -			rise_delay |= (1 << i); +			rise_delay |= BIT(i);  	}  	final_rise_delay = get_best_delay(host, rise_delay);  	/* if rising edge has enough margin, then do not scan falling edge */ @@ -2115,7 +2118,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)  		msdc_set_data_delay(host, i);  		ret = mmc_send_tuning(mmc, opcode, NULL);  		if (!ret) -			fall_delay |= (1 << i); +			fall_delay |= BIT(i);  	}  	final_fall_delay = get_best_delay(host, fall_delay); @@ -2159,7 +2162,7 @@ static int msdc_tune_together(struct mmc_host *mmc, u32 opcode)  		msdc_set_data_delay(host, i);  		ret = mmc_send_tuning(mmc, opcode, NULL);  		if (!ret) -			rise_delay |= (1 << i); +			rise_delay |= BIT(i);  	}  	final_rise_delay = get_best_delay(host, rise_delay);  	/* if rising edge has enough margin, then do not scan falling edge */ @@ -2175,7 +2178,7 @@ static int msdc_tune_together(struct mmc_host *mmc, u32 opcode)  		msdc_set_data_delay(host, i);  		ret = mmc_send_tuning(mmc, opcode, NULL);  		if (!ret) -			fall_delay |= (1 << i); +			fall_delay |= BIT(i);  	}  	final_fall_delay = get_best_delay(host, fall_delay); @@ -2292,7 +2295,7 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card  				      PAD_DS_TUNE_DLY1, i);  		ret = mmc_get_ext_csd(card, &ext_csd);  		if (!ret) { -			result_dly1 |= (1 << i); +			result_dly1 |= BIT(i);  			kfree(ext_csd);  		}  	} @@ -2516,7 +2519,20 @@ static int msdc_of_clock_parse(struct platform_device *pdev,  	/*source clock control gate is optional clock*/  	host->src_clk_cg = devm_clk_get_optional(&pdev->dev, "source_cg");  	if (IS_ERR(host->src_clk_cg)) -		host->src_clk_cg = NULL; +		return PTR_ERR(host->src_clk_cg); + +	/* +	 * Fallback for legacy device-trees: src_clk and HCLK use the same +	 * bit to control gating but they are parented to a different mux, +	 * hence if our intention is to gate only the source, required +	 * during a clk mode switch to avoid hw hangs, we need to gate +	 * its parent (specified as a different clock only on new DTs). +	 */ +	if (!host->src_clk_cg) { +		host->src_clk_cg = clk_get_parent(host->src_clk); +		if (IS_ERR(host->src_clk_cg)) +			return PTR_ERR(host->src_clk_cg); +	}  	host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");  	if (IS_ERR(host->sys_clk_cg)) @@ -2674,7 +2690,11 @@ static int msdc_drv_probe(struct platform_device *pdev)  	spin_lock_init(&host->lock);  	platform_set_drvdata(pdev, mmc); -	msdc_ungate_clock(host); +	ret = msdc_ungate_clock(host); +	if (ret) { +		dev_err(&pdev->dev, "Cannot ungate clocks!\n"); +		goto release_mem; +	}  	msdc_init_hw(host);  	if (mmc->caps2 & MMC_CAP2_CQE) { @@ -2833,8 +2853,12 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)  {  	struct mmc_host *mmc = dev_get_drvdata(dev);  	struct msdc_host *host = mmc_priv(mmc); +	int ret; + +	ret = msdc_ungate_clock(host); +	if (ret) +		return ret; -	msdc_ungate_clock(host);  	msdc_restore_reg(host);  	return 0;  } diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 2fe6fcdbb1b3..40b6878bea6c 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -1183,7 +1183,6 @@ static int mxcmci_remove(struct platform_device *pdev)  	return 0;  } -#ifdef CONFIG_PM_SLEEP  static int mxcmci_suspend(struct device *dev)  {  	struct mmc_host *mmc = dev_get_drvdata(dev); @@ -1210,9 +1209,8 @@ static int mxcmci_resume(struct device *dev)  	return ret;  } -#endif -static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);  static struct platform_driver mxcmci_driver = {  	.probe		= mxcmci_probe, @@ -1220,7 +1218,7 @@ static struct platform_driver mxcmci_driver = {  	.driver		= {  		.name		= DRIVER_NAME,  		.probe_type	= PROBE_PREFER_ASYNCHRONOUS, -		.pm	= &mxcmci_pm_ops, +		.pm	= pm_sleep_ptr(&mxcmci_pm_ops),  		.of_match_table	= mxcmci_of_match,  	}  }; diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9dafcbf969d9..fca30add563e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1499,41 +1499,6 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	omap_hsmmc_set_bus_mode(host);  } -static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) -{ -	struct omap_hsmmc_host *host = mmc_priv(mmc); - -	if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { -		struct device_node *np = mmc_dev(mmc)->of_node; - -		/* -		 * REVISIT: should be moved to sdio core and made more -		 * general e.g. by expanding the DT bindings of child nodes -		 * to provide a mechanism to provide this information: -		 * Documentation/devicetree/bindings/mmc/mmc-card.yaml -		 */ - -		np = of_get_compatible_child(np, "ti,wl1251"); -		if (np) { -			/* -			 * We have TI wl1251 attached to MMC3. Pass this -			 * information to the SDIO core because it can't be -			 * probed by normal methods. -			 */ - -			dev_info(host->dev, "found wl1251\n"); -			card->quirks |= MMC_QUIRK_NONSTD_SDIO; -			card->cccr.wide_bus = 1; -			card->cis.vendor = 0x104c; -			card->cis.device = 0x9066; -			card->cis.blksize = 512; -			card->cis.max_dtr = 24000000; -			card->ocr = 0x80; -			of_node_put(np); -		} -	} -} -  static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable)  {  	struct omap_hsmmc_host *host = mmc_priv(mmc); @@ -1660,7 +1625,6 @@ static struct mmc_host_ops omap_hsmmc_ops = {  	.set_ios = omap_hsmmc_set_ios,  	.get_cd = mmc_gpio_get_cd,  	.get_ro = mmc_gpio_get_ro, -	.init_card = omap_hsmmc_init_card,  	.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,  }; diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index 0c45e82ff0de..66d308e73e17 100644 --- a/drivers/mmc/host/renesas_sdhi.h +++ b/drivers/mmc/host/renesas_sdhi.h @@ -18,6 +18,8 @@ struct renesas_sdhi_scc {  	u32 tap_hs400_4tap;	/* sampling clock position for HS400 (4 TAP) */  }; +#define SDHI_FLAG_NEED_CLKH_FALLBACK	BIT(0) +  struct renesas_sdhi_of_data {  	unsigned long tmio_flags;  	u32	      tmio_ocr_mask; @@ -31,6 +33,7 @@ struct renesas_sdhi_of_data {  	int taps_num;  	unsigned int max_blk_count;  	unsigned short max_segs; +	unsigned long sdhi_flags;  };  #define SDHI_CALIB_TABLE_MAX 32 @@ -57,6 +60,7 @@ struct tmio_mmc_dma {  struct renesas_sdhi {  	struct clk *clk; +	struct clk *clkh;  	struct clk *clk_cd;  	struct tmio_mmc_data mmc_data;  	struct tmio_mmc_dma dma_priv; diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index f5b2684ad805..084c61b2cbec 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -127,10 +127,12 @@ static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host)  }  static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, -					    unsigned int new_clock) +					    unsigned int wanted_clock)  {  	struct renesas_sdhi *priv = host_to_priv(host); +	struct clk *ref_clk = priv->clk;  	unsigned int freq, diff, best_freq = 0, diff_min = ~0; +	unsigned int new_clock, clkh_shift = 0;  	int i;  	/* @@ -141,6 +143,16 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,  	if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2) || mmc_doing_tune(host->mmc))  		return clk_get_rate(priv->clk); +	if (priv->clkh) { +		bool use_4tap = priv->quirks && priv->quirks->hs400_4taps; +		bool need_slow_clkh = (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) || +				      (host->mmc->ios.timing == MMC_TIMING_MMC_HS400); +		clkh_shift = use_4tap && need_slow_clkh ? 1 : 2; +		ref_clk = priv->clkh; +	} + +	new_clock = wanted_clock << clkh_shift; +  	/*  	 * We want the bus clock to be as close as possible to, but no  	 * greater than, new_clock.  As we can divide by 1 << i for @@ -148,11 +160,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,  	 * possible, but no greater than, new_clock << i.  	 */  	for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) { -		freq = clk_round_rate(priv->clk, new_clock << i); +		freq = clk_round_rate(ref_clk, new_clock << i);  		if (freq > (new_clock << i)) {  			/* Too fast; look for a slightly slower option */ -			freq = clk_round_rate(priv->clk, -					      (new_clock << i) / 4 * 3); +			freq = clk_round_rate(ref_clk, (new_clock << i) / 4 * 3);  			if (freq > (new_clock << i))  				continue;  		} @@ -164,7 +175,10 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,  		}  	} -	clk_set_rate(priv->clk, best_freq); +	clk_set_rate(ref_clk, best_freq); + +	if (priv->clkh) +		clk_set_rate(priv->clk, best_freq >> clkh_shift);  	return clk_get_rate(priv->clk);  } @@ -904,11 +918,12 @@ int renesas_sdhi_probe(struct platform_device *pdev,  	dma_priv = &priv->dma_priv;  	priv->clk = devm_clk_get(&pdev->dev, NULL); -	if (IS_ERR(priv->clk)) { -		ret = PTR_ERR(priv->clk); -		dev_err(&pdev->dev, "cannot get clock: %d\n", ret); -		return ret; -	} +	if (IS_ERR(priv->clk)) +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk), "cannot get clock"); + +	priv->clkh = devm_clk_get_optional(&pdev->dev, "clkh"); +	if (IS_ERR(priv->clkh)) +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clkh), "cannot get clkh");  	/*  	 * Some controllers provide a 2nd clock just to run the internal card @@ -921,9 +936,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,  	 * to the card detect circuit. That leaves us with if separate clocks  	 * are presented, we must treat them both as virtually 1 clock.  	 */ -	priv->clk_cd = devm_clk_get(&pdev->dev, "cd"); +	priv->clk_cd = devm_clk_get_optional(&pdev->dev, "cd");  	if (IS_ERR(priv->clk_cd)) -		priv->clk_cd = NULL; +		return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cd), "cannot get cd clock");  	priv->pinctrl = devm_pinctrl_get(&pdev->dev);  	if (!IS_ERR(priv->pinctrl)) { @@ -947,6 +962,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,  		mmc_data->max_segs = of_data->max_segs;  		dma_priv->dma_buswidth = of_data->dma_buswidth;  		host->bus_shift = of_data->bus_shift; +		/* Fallback for old DTs */ +		if (!priv->clkh && of_data->sdhi_flags & SDHI_FLAG_NEED_CLKH_FALLBACK) +			priv->clkh = clk_get_parent(clk_get_parent(priv->clk)); +  	}  	host->write16_hook	= renesas_sdhi_write16_hook; @@ -1044,7 +1063,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,  	     host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |  				 MMC_CAP2_HS400_1_8V))) {  		const struct renesas_sdhi_scc *taps = of_data->taps; -		bool use_4tap = priv->quirks && priv->quirks->hs400_4taps; +		bool use_4tap = quirks && quirks->hs400_4taps;  		bool hit = false;  		for (i = 0; i < of_data->taps_num; i++) { diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 7660f7ea74dd..9d2c600fd4ce 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -125,6 +125,22 @@ static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {  	/* DMAC can handle 32bit blk count but only 1 segment */  	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE,  	.max_segs	= 1, +	.sdhi_flags	= SDHI_FLAG_NEED_CLKH_FALLBACK, +}; + +static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_fallback = { +	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | +			  TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, +	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | +			  MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY, +	.capabilities2	= MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE, +	.bus_shift	= 2, +	.scc_offset	= 0x1000, +	.taps		= rcar_gen3_scc_taps, +	.taps_num	= ARRAY_SIZE(rcar_gen3_scc_taps), +	/* DMAC can handle 32bit blk count but only 1 segment */ +	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE, +	.max_segs	= 1,  };  static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { @@ -214,6 +230,10 @@ static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {  	.quirks = &sdhi_quirks_r8a77965,  }; +static const struct renesas_sdhi_of_data_with_quirks of_r8a77970_compatible = { +	.of_data = &of_data_rcar_gen3_no_fallback, +}; +  static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = {  	.of_data = &of_data_rcar_gen3,  	.quirks = &sdhi_quirks_nohs400, @@ -235,6 +255,7 @@ static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {  	{ .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },  	{ .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },  	{ .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, }, +	{ .compatible = "renesas,sdhi-r8a77970", .data = &of_r8a77970_compatible, },  	{ .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, },  	{ .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },  	{ .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index f1ef0d28b0dd..c0350e9c03f3 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -31,10 +31,8 @@  #include <linux/mmc/slot-gpio.h>  #ifdef CONFIG_X86 -#include <asm/cpu_device_id.h> -#include <asm/intel-family.h> +#include <linux/platform_data/x86/soc.h>  #include <asm/iosf_mbi.h> -#include <linux/pci.h>  #endif  #include "sdhci.h" @@ -240,26 +238,6 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {  #ifdef CONFIG_X86 -static bool sdhci_acpi_byt(void) -{ -	static const struct x86_cpu_id byt[] = { -		X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, NULL), -		{} -	}; - -	return x86_match_cpu(byt); -} - -static bool sdhci_acpi_cht(void) -{ -	static const struct x86_cpu_id cht[] = { -		X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, NULL), -		{} -	}; - -	return x86_match_cpu(cht); -} -  #define BYT_IOSF_SCCEP			0x63  #define BYT_IOSF_OCP_NETCTRL0		0x1078  #define BYT_IOSF_OCP_TIMEOUT_BASE	GENMASK(10, 8) @@ -268,7 +246,7 @@ static void sdhci_acpi_byt_setting(struct device *dev)  {  	u32 val = 0; -	if (!sdhci_acpi_byt()) +	if (!soc_intel_is_byt())  		return;  	if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, @@ -293,7 +271,7 @@ static void sdhci_acpi_byt_setting(struct device *dev)  static bool sdhci_acpi_byt_defer(struct device *dev)  { -	if (!sdhci_acpi_byt()) +	if (!soc_intel_is_byt())  		return false;  	if (!iosf_mbi_available()) @@ -304,43 +282,6 @@ static bool sdhci_acpi_byt_defer(struct device *dev)  	return false;  } -static bool sdhci_acpi_cht_pci_wifi(unsigned int vendor, unsigned int device, -				    unsigned int slot, unsigned int parent_slot) -{ -	struct pci_dev *dev, *parent, *from = NULL; - -	while (1) { -		dev = pci_get_device(vendor, device, from); -		pci_dev_put(from); -		if (!dev) -			break; -		parent = pci_upstream_bridge(dev); -		if (ACPI_COMPANION(&dev->dev) && PCI_SLOT(dev->devfn) == slot && -		    parent && PCI_SLOT(parent->devfn) == parent_slot && -		    !pci_upstream_bridge(parent)) { -			pci_dev_put(dev); -			return true; -		} -		from = dev; -	} - -	return false; -} - -/* - * GPDwin uses PCI wifi which conflicts with SDIO's use of - * acpi_device_fix_up_power() on child device nodes. Identifying GPDwin is - * problematic, but since SDIO is only used for wifi, the presence of the PCI - * wifi card in the expected slot with an ACPI companion node, is used to - * indicate that acpi_device_fix_up_power() should be avoided. - */ -static inline bool sdhci_acpi_no_fixup_child_power(struct acpi_device *adev) -{ -	return sdhci_acpi_cht() && -	       acpi_dev_hid_uid_match(adev, "80860F14", "2") && -	       sdhci_acpi_cht_pci_wifi(0x14e4, 0x43ec, 0, 28); -} -  #else  static inline void sdhci_acpi_byt_setting(struct device *dev) @@ -352,11 +293,6 @@ static inline bool sdhci_acpi_byt_defer(struct device *dev)  	return false;  } -static inline bool sdhci_acpi_no_fixup_child_power(struct acpi_device *adev) -{ -	return false; -} -  #endif  static int bxt_get_cd(struct mmc_host *mmc) @@ -861,11 +797,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)  	/* Power on the SDHCI controller and its children */  	acpi_device_fix_up_power(device); -	if (!sdhci_acpi_no_fixup_child_power(device)) { -		list_for_each_entry(child, &device->children, node) -			if (child->status.present && child->status.enabled) -				acpi_device_fix_up_power(child); -	} +	list_for_each_entry(child, &device->children, node) +		if (child->status.present && child->status.enabled) +			acpi_device_fix_up_power(child);  	if (sdhci_acpi_byt_defer(dev))  		return -EPROBE_DEFER; diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 764ee1b761d9..55981b0f0b10 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -305,6 +305,9 @@ static struct esdhc_soc_data usdhc_imx7ulp_data = {  			| ESDHC_FLAG_PMQOS | ESDHC_FLAG_HS400  			| ESDHC_FLAG_STATE_LOST_IN_LPMODE,  }; +static struct esdhc_soc_data usdhc_imxrt1050_data = { +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_HS200 | ESDHC_FLAG_ERR004536, +};  static struct esdhc_soc_data usdhc_imx8qxp_data = {  	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING @@ -355,6 +358,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {  	{ .compatible = "fsl,imx7ulp-usdhc", .data = &usdhc_imx7ulp_data, },  	{ .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },  	{ .compatible = "fsl,imx8mm-usdhc", .data = &usdhc_imx8mm_data, }, +	{ .compatible = "fsl,imxrt1050-usdhc", .data = &usdhc_imxrt1050_data, },  	{ .compatible = "nxp,s32g2-usdhc", .data = &usdhc_s32g2_data, },  	{ /* sentinel */ }  }; diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 6f9877546830..ed53276f6ad9 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1866,6 +1866,7 @@ static const struct pci_device_id pci_ids[] = {  	SDHCI_PCI_DEVICE(INTEL, JSL_SD,    intel_byt_sd),  	SDHCI_PCI_DEVICE(INTEL, LKF_EMMC,  intel_glk_emmc),  	SDHCI_PCI_DEVICE(INTEL, LKF_SD,    intel_byt_sd), +	SDHCI_PCI_DEVICE(INTEL, ADL_EMMC,  intel_glk_emmc),  	SDHCI_PCI_DEVICE(O2, 8120,     o2),  	SDHCI_PCI_DEVICE(O2, 8220,     o2),  	SDHCI_PCI_DEVICE(O2, 8221,     o2), diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 4fd99c1e82ba..97035d77c18c 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -12,6 +12,7 @@  #include <linux/pci.h>  #include <linux/mmc/mmc.h>  #include <linux/delay.h> +#include <linux/of.h>  #include "sdhci.h"  #include "sdhci-pci.h"  #include "cqhci.h" @@ -116,6 +117,8 @@  #define PCI_GLI_9755_PECONF   0x44  #define   PCI_GLI_9755_LFCLK    GENMASK(14, 12)  #define   PCI_GLI_9755_DMACLK   BIT(29) +#define   PCI_GLI_9755_INVERT_CD  BIT(30) +#define   PCI_GLI_9755_INVERT_WP  BIT(31)  #define PCI_GLI_9755_CFG2          0x48  #define   PCI_GLI_9755_CFG2_L1DLY    GENMASK(28, 24) @@ -570,6 +573,14 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot)  	gl9755_wt_on(pdev);  	pci_read_config_dword(pdev, PCI_GLI_9755_PECONF, &value); +	/* +	 * Apple ARM64 platforms using these chips may have +	 * inverted CD/WP detection. +	 */ +	if (of_property_read_bool(pdev->dev.of_node, "cd-inverted")) +		value |= PCI_GLI_9755_INVERT_CD; +	if (of_property_read_bool(pdev->dev.of_node, "wp-inverted")) +		value |= PCI_GLI_9755_INVERT_WP;  	value &= ~PCI_GLI_9755_LFCLK;  	value &= ~PCI_GLI_9755_DMACLK;  	pci_write_config_dword(pdev, PCI_GLI_9755_PECONF, value); @@ -891,7 +902,28 @@ static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)  	return 0;  } +#define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18) + +static u16 sdhci_gli_readw(struct sdhci_host *host, int reg) +{ +	u32 val = readl(host->ioaddr + (reg & ~3)); +	u16 word; + +	word = (val >> REG_OFFSET_IN_BITS(reg)) & 0xffff; +	return word; +} + +static u8 sdhci_gli_readb(struct sdhci_host *host, int reg) +{ +	u32 val = readl(host->ioaddr + (reg & ~3)); +	u8 byte = (val >> REG_OFFSET_IN_BITS(reg)) & 0xff; + +	return byte; +} +  static const struct sdhci_ops sdhci_gl9755_ops = { +	.read_w			= sdhci_gli_readw, +	.read_b			= sdhci_gli_readb,  	.set_clock		= sdhci_gl9755_set_clock,  	.enable_dma		= sdhci_pci_enable_dma,  	.set_bus_width		= sdhci_set_bus_width, @@ -911,6 +943,8 @@ const struct sdhci_pci_fixes sdhci_gl9755 = {  };  static const struct sdhci_ops sdhci_gl9750_ops = { +	.read_w			= sdhci_gli_readw, +	.read_b			= sdhci_gli_readb,  	.read_l                 = sdhci_gl9750_readl,  	.set_clock		= sdhci_gl9750_set_clock,  	.enable_dma		= sdhci_pci_enable_dma, diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index f045c1ee4667..92c20cb8074a 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c @@ -12,6 +12,7 @@  #include <linux/mmc/mmc.h>  #include <linux/delay.h>  #include <linux/iopoll.h> +#include <linux/bitfield.h>  #include "sdhci.h"  #include "sdhci-pci.h" @@ -43,12 +44,16 @@  #define O2_SD_CAP_REG0		0x334  #define O2_SD_UHS1_CAP_SETTING	0x33C  #define O2_SD_DELAY_CTRL	0x350 +#define O2_SD_OUTPUT_CLK_SOURCE_SWITCH	0x354  #define O2_SD_UHS2_L1_CTRL	0x35C  #define O2_SD_FUNC_REG3		0x3E0  #define O2_SD_FUNC_REG4		0x3E4  #define O2_SD_LED_ENABLE	BIT(6)  #define O2_SD_FREG0_LEDOFF	BIT(13) +#define O2_SD_SEL_DLL		BIT(16)  #define O2_SD_FREG4_ENABLE_CLK_SET	BIT(22) +#define O2_SD_PHASE_MASK	GENMASK(23, 20) +#define O2_SD_FIX_PHASE		FIELD_PREP(O2_SD_PHASE_MASK, 0x9)  #define O2_SD_VENDOR_SETTING	0x110  #define O2_SD_VENDOR_SETTING2	0x1C8 @@ -301,9 +306,13 @@ static int sdhci_o2_dll_recovery(struct sdhci_host *host)  static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)  {  	struct sdhci_host *host = mmc_priv(mmc); +	struct sdhci_pci_slot *slot = sdhci_priv(host); +	struct sdhci_pci_chip *chip = slot->chip;  	int current_bus_width = 0;  	u32 scratch32 = 0;  	u16 scratch = 0; +	u8  scratch_8 = 0; +	u32 reg_val;  	/*  	 * This handler only implements the eMMC tuning that is specific to @@ -322,6 +331,32 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)  	scratch |= O2_SD_PWR_FORCE_L0;  	sdhci_writew(host, scratch, O2_SD_MISC_CTRL); +	/* Stop clk */ +	reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL); +	reg_val &= ~SDHCI_CLOCK_CARD_EN; +	sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL); + +	/* UnLock WP */ +	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); +	scratch_8 &= 0x7f; +	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); + +	/* Set pcr 0x354[16] to choose dll clock, and set the default phase */ +	pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, ®_val); +	reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); +	reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE); +	pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, reg_val); + +	/* Lock WP */ +	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch_8); +	scratch_8 |= 0x80; +	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch_8); + +	/* Start clk */ +	reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL); +	reg_val |= SDHCI_CLOCK_CARD_EN; +	sdhci_writew(host, reg_val, SDHCI_CLOCK_CONTROL); +  	/* wait DLL lock, timeout value 5ms */  	if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host,  		scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000)) @@ -533,23 +568,32 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)  	if (clock == 0)  		return; -	if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) { -		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); - -		scratch &= 0x7f; -		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); +	/* UnLock WP */ +	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); +	scratch &= 0x7f; +	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); +	if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) {  		pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);  		if ((scratch_32 & 0xFFFF0000) != 0x2c280000)  			o2_pci_set_baseclk(chip, 0x2c280000); +	} else { +		pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32); -		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); - -		scratch |= 0x80; -		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); +		if ((scratch_32 & 0xFFFF0000) != 0x25100000) +			o2_pci_set_baseclk(chip, 0x25100000);  	} +	pci_read_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, &scratch_32); +	scratch_32 &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); +	pci_write_config_dword(chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, scratch_32); + +	/* Lock WP */ +	pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); +	scratch |= 0x80; +	pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch); +  	clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);  	sdhci_o2_enable_clk(host, clk);  } diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 5e3193278ff9..3661a224fb04 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -59,6 +59,7 @@  #define PCI_DEVICE_ID_INTEL_JSL_SD	0x4df8  #define PCI_DEVICE_ID_INTEL_LKF_EMMC	0x98c4  #define PCI_DEVICE_ID_INTEL_LKF_SD	0x98f8 +#define PCI_DEVICE_ID_INTEL_ADL_EMMC	0x54c4  #define PCI_DEVICE_ID_SYSKONNECT_8000	0x8000  #define PCI_DEVICE_ID_VIA_95D0		0x95d0 diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index e2affa52ef46..a5850d83908b 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -960,14 +960,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	case MMC_POWER_OFF:  		tmio_mmc_power_off(host);  		/* For R-Car Gen2+, we need to reset SDHI specific SCC */ -		if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) { -			host->reset(host); - -			if (host->native_hotplug) -				tmio_mmc_enable_mmc_irqs(host, -						TMIO_STAT_CARD_REMOVE | -						TMIO_STAT_CARD_INSERT); -		} +		if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) +			tmio_mmc_reset(host);  		host->set_clock(host, 0);  		break; @@ -1175,6 +1169,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)  	if (mmc_can_gpio_cd(mmc))  		_host->ops.get_cd = mmc_gpio_get_cd; +	/* must be set before tmio_mmc_reset() */  	_host->native_hotplug = !(mmc_can_gpio_cd(mmc) ||  				  mmc->caps & MMC_CAP_NEEDS_POLL ||  				  !mmc_card_is_removable(mmc)); @@ -1295,10 +1290,6 @@ int tmio_mmc_host_runtime_resume(struct device *dev)  	if (host->clk_cache)  		host->set_clock(host, host->clk_cache); -	if (host->native_hotplug) -		tmio_mmc_enable_mmc_irqs(host, -				TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); -  	tmio_mmc_enable_dma(host, true);  	return 0; |