| 1 |
|
| 2 | |
| 3 | * linux/drivers/mmc/core/core.h
|
| 4 | *
|
| 5 | * Copyright (C) 2003 Russell King, All Rights Reserved.
|
| 6 | * Copyright 2007 Pierre Ossman
|
| 7 |
|
| 8 | #ifndef _MMC_CORE_CORE_H
|
| 9 | #define _MMC_CORE_CORE_H
|
| 10 |
|
| 11 | #include <linux/delay.h>
|
| 12 | #include <linux/sched.h>
|
| 13 |
|
| 14 | struct mmc_host;
|
| 15 | struct mmc_card;
|
| 16 | struct mmc_request;
|
| 17 |
|
| 18 | #define MMC_CMD_RETRIES 3
|
| 19 |
|
| 20 | struct mmc_bus_ops {
|
| 21 | void (*remove)(struct mmc_host *);
|
| 22 | void (*detect)(struct mmc_host *);
|
| 23 | int (*pre_suspend)(struct mmc_host *);
|
| 24 | int (*suspend)(struct mmc_host *);
|
| 25 | int (*resume)(struct mmc_host *);
|
| 26 | int (*runtime_suspend)(struct mmc_host *);
|
| 27 | int (*runtime_resume)(struct mmc_host *);
|
| 28 | int (*alive)(struct mmc_host *);
|
| 29 | int (*shutdown)(struct mmc_host *);
|
| 30 | int (*hw_reset)(struct mmc_host *);
|
| 31 | int (*sw_reset)(struct mmc_host *);
|
| 32 | bool (*cache_enabled)(struct mmc_host *);
|
| 33 | int (*flush_cache)(struct mmc_host *);
|
| 34 | int (*handle_undervoltage)(struct mmc_host *host);
|
| 35 | };
|
| 36 |
|
| 37 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
|
| 38 | void mmc_detach_bus(struct mmc_host *host);
|
| 39 |
|
| 40 | struct device_node *mmc_of_find_child_device(struct mmc_host *host,
|
| 41 | unsigned func_num);
|
| 42 |
|
| 43 | void mmc_init_erase(struct mmc_card *card);
|
| 44 |
|
| 45 | void mmc_set_chip_select(struct mmc_host *host, int mode);
|
| 46 | void mmc_set_clock(struct mmc_host *host, unsigned int hz);
|
| 47 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
|
| 48 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
|
| 49 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
|
| 50 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr);
|
| 51 | int mmc_host_set_uhs_voltage(struct mmc_host *host);
|
| 52 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
|
| 53 | void mmc_set_initial_signal_voltage(struct mmc_host *host);
|
| 54 | void mmc_set_timing(struct mmc_host *host, unsigned int timing);
|
| 55 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
|
| 56 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr,
|
| 57 | int card_drv_type, int *drv_type);
|
| 58 | void mmc_power_up(struct mmc_host *host, u32 ocr);
|
| 59 | void mmc_power_off(struct mmc_host *host);
|
| 60 | void mmc_power_cycle(struct mmc_host *host, u32 ocr);
|
| 61 | void mmc_set_initial_state(struct mmc_host *host);
|
| 62 | u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
|
| 63 | int mmc_handle_undervoltage(struct mmc_host *host);
|
| 64 | void mmc_regulator_register_undervoltage_notifier(struct mmc_host *host);
|
| 65 | void mmc_regulator_unregister_undervoltage_notifier(struct mmc_host *host);
|
| 66 | void mmc_undervoltage_workfn(struct work_struct *work);
|
| 67 |
|
| 68 | static inline void mmc_delay(unsigned int ms)
|
| 69 | {
|
| 70 | if (ms <= 20)
|
| 71 | usleep_range(ms * 1000, ms * 1250);
|
| 72 | else
|
| 73 | msleep(ms);
|
| 74 | }
|
| 75 |
|
| 76 | void mmc_rescan(struct work_struct *work);
|
| 77 | void mmc_start_host(struct mmc_host *host);
|
| 78 | void __mmc_stop_host(struct mmc_host *host);
|
| 79 | void mmc_stop_host(struct mmc_host *host);
|
| 80 |
|
| 81 | void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
|
| 82 | bool cd_irq);
|
| 83 | int _mmc_detect_card_removed(struct mmc_host *host);
|
| 84 | int mmc_detect_card_removed(struct mmc_host *host);
|
| 85 |
|
| 86 | int mmc_attach_mmc(struct mmc_host *host);
|
| 87 | int mmc_attach_sd(struct mmc_host *host);
|
| 88 | int mmc_attach_sdio(struct mmc_host *host);
|
| 89 | int mmc_attach_sd_uhs2(struct mmc_host *host);
|
| 90 |
|
| 91 |
|
| 92 | extern bool use_spi_crc;
|
| 93 |
|
| 94 |
|
| 95 | #ifdef CONFIG_DEBUG_FS
|
| 96 | void mmc_add_host_debugfs(struct mmc_host *host);
|
| 97 | void mmc_remove_host_debugfs(struct mmc_host *host);
|
| 98 |
|
| 99 | void mmc_add_card_debugfs(struct mmc_card *card);
|
| 100 | void mmc_remove_card_debugfs(struct mmc_card *card);
|
| 101 | #else
|
| 102 | static inline void mmc_add_host_debugfs(struct mmc_host *host)
|
| 103 | {
|
| 104 | }
|
| 105 | static inline void mmc_remove_host_debugfs(struct mmc_host *host)
|
| 106 | {
|
| 107 | }
|
| 108 | static inline void mmc_add_card_debugfs(struct mmc_card *card)
|
| 109 | {
|
| 110 | }
|
| 111 | static inline void mmc_remove_card_debugfs(struct mmc_card *card)
|
| 112 | {
|
| 113 | }
|
| 114 | #endif
|
| 115 |
|
| 116 | int mmc_execute_tuning(struct mmc_card *card);
|
| 117 | int mmc_hs200_to_hs400(struct mmc_card *card);
|
| 118 | int mmc_hs400_to_hs200(struct mmc_card *card);
|
| 119 |
|
| 120 | void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq);
|
| 121 | bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
|
| 122 |
|
| 123 | int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq);
|
| 124 |
|
| 125 | int mmc_erase(struct mmc_card *card, sector_t from, unsigned int nr, unsigned int arg);
|
| 126 | bool mmc_card_can_erase(struct mmc_card *card);
|
| 127 | bool mmc_card_can_trim(struct mmc_card *card);
|
| 128 | bool mmc_card_can_discard(struct mmc_card *card);
|
| 129 | bool mmc_card_can_sanitize(struct mmc_card *card);
|
| 130 | bool mmc_card_can_secure_erase_trim(struct mmc_card *card);
|
| 131 | bool mmc_card_can_cmd23(struct mmc_card *card);
|
| 132 | int mmc_erase_group_aligned(struct mmc_card *card, sector_t from, unsigned int nr);
|
| 133 | unsigned int mmc_calc_max_discard(struct mmc_card *card);
|
| 134 |
|
| 135 | int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
|
| 136 |
|
| 137 | int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
|
| 138 | atomic_t *abort);
|
| 139 | void mmc_release_host(struct mmc_host *host);
|
| 140 | void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
|
| 141 | void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
|
| 142 |
|
| 143 | int mmc_card_alternative_gpt_sector(struct mmc_card *card, sector_t *sector);
|
| 144 |
|
| 145 | |
| 146 | * mmc_claim_host - exclusively claim a host
|
| 147 | * @host: mmc host to claim
|
| 148 | *
|
| 149 | * Claim a host for a set of operations.
|
| 150 |
|
| 151 | static inline void mmc_claim_host(struct mmc_host *host)
|
| 152 | {
|
| 153 | __mmc_claim_host(host, NULL, NULL);
|
| 154 | }
|
| 155 |
|
| 156 | int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq);
|
| 157 | void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq);
|
| 158 | int mmc_cqe_recovery(struct mmc_host *host);
|
| 159 |
|
| 160 | |
| 161 | * mmc_pre_req - Prepare for a new request
|
| 162 | * @host: MMC host to prepare command
|
| 163 | * @mrq: MMC request to prepare for
|
| 164 | *
|
| 165 | * mmc_pre_req() is called in prior to mmc_start_req() to let
|
| 166 | * host prepare for the new request. Preparation of a request may be
|
| 167 | * performed while another request is running on the host.
|
| 168 |
|
| 169 | static inline void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq)
|
| 170 | {
|
| 171 | if (host->ops->pre_req)
|
| 172 | host->ops->pre_req(host, mrq);
|
| 173 | }
|
| 174 |
|
| 175 | |
| 176 | * mmc_post_req - Post process a completed request
|
| 177 | * @host: MMC host to post process command
|
| 178 | * @mrq: MMC request to post process for
|
| 179 | * @err: Error, if non zero, clean up any resources made in pre_req
|
| 180 | *
|
| 181 | * Let the host post process a completed request. Post processing of
|
| 182 | * a request may be performed while another request is running.
|
| 183 |
|
| 184 | static inline void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
|
| 185 | int err)
|
| 186 | {
|
| 187 | if (host->ops->post_req)
|
| 188 | host->ops->post_req(host, mrq, err);
|
| 189 | }
|
| 190 |
|
| 191 | static inline bool mmc_cache_enabled(struct mmc_host *host)
|
| 192 | {
|
| 193 | if (host->bus_ops->cache_enabled)
|
| 194 | return host->bus_ops->cache_enabled(host);
|
| 195 |
|
| 196 | return false;
|
| 197 | }
|
| 198 |
|
| 199 | static inline int mmc_flush_cache(struct mmc_host *host)
|
| 200 | {
|
| 201 | if (host->bus_ops->flush_cache)
|
| 202 | return host->bus_ops->flush_cache(host);
|
| 203 |
|
| 204 | return 0;
|
| 205 | }
|
| 206 |
|
| 207 | static inline unsigned int mmc_sector_div(sector_t dividend, u32 divisor)
|
| 208 | {
|
| 209 | return div_u64(dividend, divisor);
|
| 210 | }
|
| 211 |
|
| 212 | static inline unsigned int mmc_sector_mod(sector_t dividend, u32 divisor)
|
| 213 | {
|
| 214 | return sector_div(dividend, divisor);
|
| 215 | }
|
| 216 |
|
| 217 | #endif
|