xref: /linux/drivers/mmc/core/core.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2aaac1b47SPierre Ossman /*
3aaac1b47SPierre Ossman  *  linux/drivers/mmc/core/core.h
4aaac1b47SPierre Ossman  *
5aaac1b47SPierre Ossman  *  Copyright (C) 2003 Russell King, All Rights Reserved.
6da7fbe58SPierre Ossman  *  Copyright 2007 Pierre Ossman
7aaac1b47SPierre Ossman  */
8da7fbe58SPierre Ossman #ifndef _MMC_CORE_CORE_H
9da7fbe58SPierre Ossman #define _MMC_CORE_CORE_H
10aaac1b47SPierre Ossman 
11da7fbe58SPierre Ossman #include <linux/delay.h>
12066185d6SUlf Hansson #include <linux/sched.h>
13066185d6SUlf Hansson 
14066185d6SUlf Hansson struct mmc_host;
15066185d6SUlf Hansson struct mmc_card;
1655244c56SUlf Hansson struct mmc_request;
17aaac1b47SPierre Ossman 
18da7fbe58SPierre Ossman #define MMC_CMD_RETRIES        3
19da7fbe58SPierre Ossman 
207ea239d9SPierre Ossman struct mmc_bus_ops {
217ea239d9SPierre Ossman 	void (*remove)(struct mmc_host *);
227ea239d9SPierre Ossman 	void (*detect)(struct mmc_host *);
23810caddbSUlf Hansson 	int (*pre_suspend)(struct mmc_host *);
2495cdfb72SNicolas Pitre 	int (*suspend)(struct mmc_host *);
2595cdfb72SNicolas Pitre 	int (*resume)(struct mmc_host *);
2612d01d0bSUlf Hansson 	int (*runtime_suspend)(struct mmc_host *);
2712d01d0bSUlf Hansson 	int (*runtime_resume)(struct mmc_host *);
28d3049504SAdrian Hunter 	int (*alive)(struct mmc_host *);
296b086bdeSUlf Hansson 	int (*shutdown)(struct mmc_host *);
303a3db603SUlf Hansson 	int (*hw_reset)(struct mmc_host *);
311433269cSUlf Hansson 	int (*sw_reset)(struct mmc_host *);
3297fce126SAvri Altman 	bool (*cache_enabled)(struct mmc_host *);
338ae11edeSUlf Hansson 	int (*flush_cache)(struct mmc_host *);
347ea239d9SPierre Ossman };
357ea239d9SPierre Ossman 
367ea239d9SPierre Ossman void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
377ea239d9SPierre Ossman void mmc_detach_bus(struct mmc_host *host);
387ea239d9SPierre Ossman 
3925185f3fSSascha Hauer struct device_node *mmc_of_find_child_device(struct mmc_host *host,
4025185f3fSSascha Hauer 		unsigned func_num);
4125185f3fSSascha Hauer 
42dfe86cbaSAdrian Hunter void mmc_init_erase(struct mmc_card *card);
43dfe86cbaSAdrian Hunter 
44da7fbe58SPierre Ossman void mmc_set_chip_select(struct mmc_host *host, int mode);
457ea239d9SPierre Ossman void mmc_set_clock(struct mmc_host *host, unsigned int hz);
467ea239d9SPierre Ossman void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
477ea239d9SPierre Ossman void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
487ea239d9SPierre Ossman u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
492ed573b6SUlf Hansson int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr);
503f496afbSAdrian Hunter int mmc_host_set_uhs_voltage(struct mmc_host *host);
514e74b6b3SUlf Hansson int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
52508c9864SUlf Hansson void mmc_set_initial_signal_voltage(struct mmc_host *host);
537ea239d9SPierre Ossman void mmc_set_timing(struct mmc_host *host, unsigned int timing);
54d6d50a15SArindam Nath void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
55e23350b3SAdrian Hunter int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
56e23350b3SAdrian Hunter 			      int card_drv_type, int *drv_type);
574a065193SUlf Hansson void mmc_power_up(struct mmc_host *host, u32 ocr);
587f7e4129SUlf Hansson void mmc_power_off(struct mmc_host *host);
594a065193SUlf Hansson void mmc_power_cycle(struct mmc_host *host, u32 ocr);
602d079c43SJohan Rudholm void mmc_set_initial_state(struct mmc_host *host);
61de13d5a4SUlf Hansson u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
627ea239d9SPierre Ossman 
mmc_delay(unsigned int ms)63da7fbe58SPierre Ossman static inline void mmc_delay(unsigned int ms)
64da7fbe58SPierre Ossman {
6596455380SWolfram Sang 	if (ms <= 20)
6696455380SWolfram Sang 		usleep_range(ms * 1000, ms * 1250);
6796455380SWolfram Sang 	else
68da7fbe58SPierre Ossman 		msleep(ms);
69da7fbe58SPierre Ossman }
70da7fbe58SPierre Ossman 
71b93931a6SPierre Ossman void mmc_rescan(struct work_struct *work);
72b93931a6SPierre Ossman void mmc_start_host(struct mmc_host *host);
7366c915d0SUlf Hansson void __mmc_stop_host(struct mmc_host *host);
74b93931a6SPierre Ossman void mmc_stop_host(struct mmc_host *host);
75b93931a6SPierre Ossman 
762ac55d5eSUlf Hansson void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
772ac55d5eSUlf Hansson 			bool cd_irq);
78d3049504SAdrian Hunter int _mmc_detect_card_removed(struct mmc_host *host);
7955244c56SUlf Hansson int mmc_detect_card_removed(struct mmc_host *host);
80d3049504SAdrian Hunter 
81807e8e40SAndy Ross int mmc_attach_mmc(struct mmc_host *host);
82807e8e40SAndy Ross int mmc_attach_sd(struct mmc_host *host);
83807e8e40SAndy Ross int mmc_attach_sdio(struct mmc_host *host);
8498b843beSAdrian Bunk 
85bd68e083SBen Hutchings /* Module parameters */
8690ab5ee9SRusty Russell extern bool use_spi_crc;
87af517150SDavid Brownell 
886edd8ee6SHaavard Skinnemoen /* Debugfs information for hosts and cards */
89*5c5301a1SYe Bin #ifdef CONFIG_DEBUG_FS
906edd8ee6SHaavard Skinnemoen void mmc_add_host_debugfs(struct mmc_host *host);
916edd8ee6SHaavard Skinnemoen void mmc_remove_host_debugfs(struct mmc_host *host);
926edd8ee6SHaavard Skinnemoen 
93f4b7f927SHaavard Skinnemoen void mmc_add_card_debugfs(struct mmc_card *card);
94f4b7f927SHaavard Skinnemoen void mmc_remove_card_debugfs(struct mmc_card *card);
95*5c5301a1SYe Bin #else
mmc_add_host_debugfs(struct mmc_host * host)96*5c5301a1SYe Bin static inline void mmc_add_host_debugfs(struct mmc_host *host)
97*5c5301a1SYe Bin {
98*5c5301a1SYe Bin }
mmc_remove_host_debugfs(struct mmc_host * host)99*5c5301a1SYe Bin static inline void mmc_remove_host_debugfs(struct mmc_host *host)
100*5c5301a1SYe Bin {
101*5c5301a1SYe Bin }
mmc_add_card_debugfs(struct mmc_card * card)102*5c5301a1SYe Bin static inline void mmc_add_card_debugfs(struct mmc_card *card)
103*5c5301a1SYe Bin {
104*5c5301a1SYe Bin }
mmc_remove_card_debugfs(struct mmc_card * card)105*5c5301a1SYe Bin static inline void mmc_remove_card_debugfs(struct mmc_card *card)
106*5c5301a1SYe Bin {
107*5c5301a1SYe Bin }
108*5c5301a1SYe Bin #endif
109f4b7f927SHaavard Skinnemoen 
11063e415c6SAdrian Hunter int mmc_execute_tuning(struct mmc_card *card);
1116376f69dSAdrian Hunter int mmc_hs200_to_hs400(struct mmc_card *card);
1126376f69dSAdrian Hunter int mmc_hs400_to_hs200(struct mmc_card *card);
11363e415c6SAdrian Hunter 
11455244c56SUlf Hansson void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq);
11555244c56SUlf Hansson bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
116da7fbe58SPierre Ossman 
117cb39f61eSAdrian Hunter int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq);
118cb39f61eSAdrian Hunter 
11955244c56SUlf Hansson int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
12055244c56SUlf Hansson 		unsigned int arg);
12155244c56SUlf Hansson int mmc_can_erase(struct mmc_card *card);
12255244c56SUlf Hansson int mmc_can_trim(struct mmc_card *card);
12355244c56SUlf Hansson int mmc_can_discard(struct mmc_card *card);
12455244c56SUlf Hansson int mmc_can_sanitize(struct mmc_card *card);
12555244c56SUlf Hansson int mmc_can_secure_erase_trim(struct mmc_card *card);
12655244c56SUlf Hansson int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,
12755244c56SUlf Hansson 			unsigned int nr);
12855244c56SUlf Hansson unsigned int mmc_calc_max_discard(struct mmc_card *card);
12955244c56SUlf Hansson 
13055244c56SUlf Hansson int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
13155244c56SUlf Hansson 
1326c0cedd1SAdrian Hunter int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
1336c0cedd1SAdrian Hunter 		     atomic_t *abort);
13455244c56SUlf Hansson void mmc_release_host(struct mmc_host *host);
1356c0cedd1SAdrian Hunter void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
1366c0cedd1SAdrian Hunter void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
13755244c56SUlf Hansson 
138dc913385SDmitry Osipenko int mmc_card_alternative_gpt_sector(struct mmc_card *card, sector_t *sector);
139dc913385SDmitry Osipenko 
14055244c56SUlf Hansson /**
14155244c56SUlf Hansson  *	mmc_claim_host - exclusively claim a host
14255244c56SUlf Hansson  *	@host: mmc host to claim
14355244c56SUlf Hansson  *
14455244c56SUlf Hansson  *	Claim a host for a set of operations.
14555244c56SUlf Hansson  */
mmc_claim_host(struct mmc_host * host)14655244c56SUlf Hansson static inline void mmc_claim_host(struct mmc_host *host)
14755244c56SUlf Hansson {
1486c0cedd1SAdrian Hunter 	__mmc_claim_host(host, NULL, NULL);
14955244c56SUlf Hansson }
15055244c56SUlf Hansson 
15172a5af55SAdrian Hunter int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq);
15272a5af55SAdrian Hunter void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq);
15372a5af55SAdrian Hunter int mmc_cqe_recovery(struct mmc_host *host);
15472a5af55SAdrian Hunter 
155afab1bb8SAdrian Hunter /**
156afab1bb8SAdrian Hunter  *	mmc_pre_req - Prepare for a new request
157afab1bb8SAdrian Hunter  *	@host: MMC host to prepare command
158afab1bb8SAdrian Hunter  *	@mrq: MMC request to prepare for
159afab1bb8SAdrian Hunter  *
160afab1bb8SAdrian Hunter  *	mmc_pre_req() is called in prior to mmc_start_req() to let
161afab1bb8SAdrian Hunter  *	host prepare for the new request. Preparation of a request may be
162afab1bb8SAdrian Hunter  *	performed while another request is running on the host.
163afab1bb8SAdrian Hunter  */
mmc_pre_req(struct mmc_host * host,struct mmc_request * mrq)164afab1bb8SAdrian Hunter static inline void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq)
165afab1bb8SAdrian Hunter {
166afab1bb8SAdrian Hunter 	if (host->ops->pre_req)
167afab1bb8SAdrian Hunter 		host->ops->pre_req(host, mrq);
168afab1bb8SAdrian Hunter }
169afab1bb8SAdrian Hunter 
170afab1bb8SAdrian Hunter /**
171afab1bb8SAdrian Hunter  *	mmc_post_req - Post process a completed request
172afab1bb8SAdrian Hunter  *	@host: MMC host to post process command
173afab1bb8SAdrian Hunter  *	@mrq: MMC request to post process for
174afab1bb8SAdrian Hunter  *	@err: Error, if non zero, clean up any resources made in pre_req
175afab1bb8SAdrian Hunter  *
176afab1bb8SAdrian Hunter  *	Let the host post process a completed request. Post processing of
177afab1bb8SAdrian Hunter  *	a request may be performed while another request is running.
178afab1bb8SAdrian Hunter  */
mmc_post_req(struct mmc_host * host,struct mmc_request * mrq,int err)179afab1bb8SAdrian Hunter static inline void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
180afab1bb8SAdrian Hunter 				int err)
181afab1bb8SAdrian Hunter {
182afab1bb8SAdrian Hunter 	if (host->ops->post_req)
183afab1bb8SAdrian Hunter 		host->ops->post_req(host, mrq, err);
184afab1bb8SAdrian Hunter }
185afab1bb8SAdrian Hunter 
mmc_cache_enabled(struct mmc_host * host)18697fce126SAvri Altman static inline bool mmc_cache_enabled(struct mmc_host *host)
18797fce126SAvri Altman {
18897fce126SAvri Altman 	if (host->bus_ops->cache_enabled)
18997fce126SAvri Altman 		return host->bus_ops->cache_enabled(host);
19097fce126SAvri Altman 
19197fce126SAvri Altman 	return false;
19297fce126SAvri Altman }
19397fce126SAvri Altman 
mmc_flush_cache(struct mmc_host * host)1948ae11edeSUlf Hansson static inline int mmc_flush_cache(struct mmc_host *host)
1958ae11edeSUlf Hansson {
1968ae11edeSUlf Hansson 	if (host->bus_ops->flush_cache)
1978ae11edeSUlf Hansson 		return host->bus_ops->flush_cache(host);
1988ae11edeSUlf Hansson 
1998ae11edeSUlf Hansson 	return 0;
2008ae11edeSUlf Hansson }
2018ae11edeSUlf Hansson 
20255244c56SUlf Hansson #endif
203