#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/ktime.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/sizes.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/leds.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>
#include "sdhci.h"
#define DRIVER_NAME …
#define DBG(f, x...) …
#define SDHCI_DUMP(f, x...) …
#define MAX_TUNING_LOOP …
static unsigned int debug_quirks = …;
static unsigned int debug_quirks2;
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd);
void sdhci_dumpregs(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_do_enable_v4_mode(struct sdhci_host *host)
{ … }
void sdhci_enable_v4_mode(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
static inline bool sdhci_data_line_cmd(struct mmc_command *cmd)
{ … }
static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
{ … }
static void sdhci_enable_card_detection(struct sdhci_host *host)
{ … }
static void sdhci_disable_card_detection(struct sdhci_host *host)
{ … }
static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
{ … }
static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
{ … }
void sdhci_reset(struct sdhci_host *host, u8 mask)
{ … }
EXPORT_SYMBOL_GPL(…);
static bool sdhci_do_reset(struct sdhci_host *host, u8 mask)
{ … }
static void sdhci_reset_for_all(struct sdhci_host *host)
{ … }
enum sdhci_reset_reason { … };
static void sdhci_reset_for_reason(struct sdhci_host *host, enum sdhci_reset_reason reason)
{ … }
#define sdhci_reset_for(h, r) …
static void sdhci_set_default_irqs(struct sdhci_host *host)
{ … }
static void sdhci_config_dma(struct sdhci_host *host)
{ … }
static void sdhci_init(struct sdhci_host *host, int soft)
{ … }
static void sdhci_reinit(struct sdhci_host *host)
{ … }
static void __sdhci_led_activate(struct sdhci_host *host)
{ … }
static void __sdhci_led_deactivate(struct sdhci_host *host)
{ … }
#if IS_REACHABLE(CONFIG_LEDS_CLASS)
static void sdhci_led_control(struct led_classdev *led,
enum led_brightness brightness)
{ … }
static int sdhci_led_register(struct sdhci_host *host)
{ … }
static void sdhci_led_unregister(struct sdhci_host *host)
{ … }
static inline void sdhci_led_activate(struct sdhci_host *host)
{ … }
static inline void sdhci_led_deactivate(struct sdhci_host *host)
{ … }
#else
static inline int sdhci_led_register(struct sdhci_host *host)
{
return 0;
}
static inline void sdhci_led_unregister(struct sdhci_host *host)
{
}
static inline void sdhci_led_activate(struct sdhci_host *host)
{
__sdhci_led_activate(host);
}
static inline void sdhci_led_deactivate(struct sdhci_host *host)
{
__sdhci_led_deactivate(host);
}
#endif
static void sdhci_mod_timer(struct sdhci_host *host, struct mmc_request *mrq,
unsigned long timeout)
{ … }
static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq)
{ … }
static inline bool sdhci_has_requests(struct sdhci_host *host)
{ … }
static void sdhci_read_block_pio(struct sdhci_host *host)
{ … }
static void sdhci_write_block_pio(struct sdhci_host *host)
{ … }
static void sdhci_transfer_pio(struct sdhci_host *host)
{ … }
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
struct mmc_data *data, int cookie)
{ … }
static char *sdhci_kmap_atomic(struct scatterlist *sg)
{ … }
static void sdhci_kunmap_atomic(void *buffer)
{ … }
void sdhci_adma_write_desc(struct sdhci_host *host, void **desc,
dma_addr_t addr, int len, unsigned int cmd)
{ … }
EXPORT_SYMBOL_GPL(…);
static inline void __sdhci_adma_write_desc(struct sdhci_host *host,
void **desc, dma_addr_t addr,
int len, unsigned int cmd)
{ … }
static void sdhci_adma_mark_end(void *desc)
{ … }
static void sdhci_adma_table_pre(struct sdhci_host *host,
struct mmc_data *data, int sg_count)
{ … }
static void sdhci_adma_table_post(struct sdhci_host *host,
struct mmc_data *data)
{ … }
static void sdhci_set_adma_addr(struct sdhci_host *host, dma_addr_t addr)
{ … }
static dma_addr_t sdhci_sdma_address(struct sdhci_host *host)
{ … }
static void sdhci_set_sdma_addr(struct sdhci_host *host, dma_addr_t addr)
{ … }
static unsigned int sdhci_target_timeout(struct sdhci_host *host,
struct mmc_command *cmd,
struct mmc_data *data)
{ … }
static void sdhci_calc_sw_timeout(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
bool *too_big)
{ … }
static void sdhci_set_transfer_irqs(struct sdhci_host *host)
{ … }
void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable)
{ … }
EXPORT_SYMBOL_GPL(…);
void __sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
{ … }
static void sdhci_initialize_data(struct sdhci_host *host,
struct mmc_data *data)
{ … }
static inline void sdhci_set_block_info(struct sdhci_host *host,
struct mmc_data *data)
{ … }
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
{ … }
#if IS_ENABLED(CONFIG_MMC_SDHCI_EXTERNAL_DMA)
static int sdhci_external_dma_init(struct sdhci_host *host)
{ … }
static struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host,
struct mmc_data *data)
{ … }
static int sdhci_external_dma_setup(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
static void sdhci_external_dma_release(struct sdhci_host *host)
{ … }
static void __sdhci_external_dma_prepare_data(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
static void sdhci_external_dma_prepare_data(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
static void sdhci_external_dma_pre_transfer(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
#else
static inline int sdhci_external_dma_init(struct sdhci_host *host)
{
return -EOPNOTSUPP;
}
static inline void sdhci_external_dma_release(struct sdhci_host *host)
{
}
static inline void sdhci_external_dma_prepare_data(struct sdhci_host *host,
struct mmc_command *cmd)
{
WARN_ON_ONCE(1);
}
static inline void sdhci_external_dma_pre_transfer(struct sdhci_host *host,
struct mmc_command *cmd)
{
}
static inline struct dma_chan *sdhci_external_dma_channel(struct sdhci_host *host,
struct mmc_data *data)
{
return NULL;
}
#endif
void sdhci_switch_external_dma(struct sdhci_host *host, bool en)
{ … }
EXPORT_SYMBOL_GPL(…);
static inline bool sdhci_auto_cmd12(struct sdhci_host *host,
struct mmc_request *mrq)
{ … }
static inline bool sdhci_auto_cmd23(struct sdhci_host *host,
struct mmc_request *mrq)
{ … }
static inline bool sdhci_manual_cmd23(struct sdhci_host *host,
struct mmc_request *mrq)
{ … }
static inline void sdhci_auto_cmd_select(struct sdhci_host *host,
struct mmc_command *cmd,
u16 *mode)
{ … }
static void sdhci_set_transfer_mode(struct sdhci_host *host,
struct mmc_command *cmd)
{ … }
static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq)
{ … }
static void sdhci_set_mrq_done(struct sdhci_host *host, struct mmc_request *mrq)
{ … }
static void __sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq)
{ … }
static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq)
{ … }
static void __sdhci_finish_data(struct sdhci_host *host, bool sw_data_timeout)
{ … }
static void sdhci_finish_data(struct sdhci_host *host)
{ … }
static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
{ … }
static bool sdhci_present_error(struct sdhci_host *host,
struct mmc_command *cmd, bool present)
{ … }
static bool sdhci_send_command_retry(struct sdhci_host *host,
struct mmc_command *cmd,
unsigned long flags)
__releases(host->lock)
__acquires(host->lock)
{ … }
static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
{ … }
static void sdhci_finish_command(struct sdhci_host *host)
{ … }
static u16 sdhci_get_preset_value(struct sdhci_host *host)
{ … }
u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
unsigned int *actual_clock)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{ … }
void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_set_power_and_bus_voltage(struct sdhci_host *host,
unsigned char mode,
unsigned short vdd)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_set_bus_width(struct sdhci_host *host, int width)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
{ … }
EXPORT_SYMBOL_GPL(…);
static bool sdhci_timing_has_preset(unsigned char timing)
{ … }
static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing)
{ … }
static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios)
{ … }
void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{ … }
EXPORT_SYMBOL_GPL(…);
static int sdhci_get_cd(struct mmc_host *mmc)
{ … }
int sdhci_get_cd_nogpio(struct mmc_host *mmc)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_get_ro(struct mmc_host *mmc)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_hw_reset(struct mmc_host *mmc)
{ … }
static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
{ … }
void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_ack_sdio_irq(struct mmc_host *mmc)
{ … }
int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
struct mmc_ios *ios)
{ … }
EXPORT_SYMBOL_GPL(…);
static int sdhci_card_busy(struct mmc_host *mmc)
{ … }
static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
{ … }
void sdhci_start_tuning(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_end_tuning(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_reset_tuning(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
{ … }
EXPORT_SYMBOL_GPL(…);
int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
{ … }
static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
int err)
{ … }
static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq)
{ … }
static void sdhci_error_out_mrqs(struct sdhci_host *host, int err)
{ … }
static void sdhci_card_event(struct mmc_host *mmc)
{ … }
static const struct mmc_host_ops sdhci_ops = …;
static bool sdhci_request_done(struct sdhci_host *host)
{ … }
static void sdhci_complete_work(struct work_struct *work)
{ … }
static void sdhci_timeout_timer(struct timer_list *t)
{ … }
static void sdhci_timeout_data_timer(struct timer_list *t)
{ … }
static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
{ … }
static void sdhci_adma_show_error(struct sdhci_host *host)
{ … }
static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{ … }
static inline bool sdhci_defer_done(struct sdhci_host *host,
struct mmc_request *mrq)
{ … }
static irqreturn_t sdhci_irq(int irq, void *dev_id)
{ … }
static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
{ … }
#ifdef CONFIG_PM
static bool sdhci_cd_irq_can_wakeup(struct sdhci_host *host)
{ … }
static bool sdhci_enable_irq_wakeups(struct sdhci_host *host)
{ … }
static void sdhci_disable_irq_wakeups(struct sdhci_host *host)
{ … }
int sdhci_suspend_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_resume_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_runtime_suspend_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
{ … }
EXPORT_SYMBOL_GPL(…);
#endif
void sdhci_cqe_enable(struct mmc_host *mmc)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_cqe_disable(struct mmc_host *mmc, bool recovery)
{ … }
EXPORT_SYMBOL_GPL(…);
bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
int *data_error)
{ … }
EXPORT_SYMBOL_GPL(…);
struct sdhci_host *sdhci_alloc_host(struct device *dev,
size_t priv_size)
{ … }
EXPORT_SYMBOL_GPL(…);
static int sdhci_set_dma_mask(struct sdhci_host *host)
{ … }
void __sdhci_read_caps(struct sdhci_host *host, const u16 *ver,
const u32 *caps, const u32 *caps1)
{ … }
EXPORT_SYMBOL_GPL(…);
static void sdhci_allocate_bounce_buffer(struct sdhci_host *host)
{ … }
static inline bool sdhci_can_64bit_dma(struct sdhci_host *host)
{ … }
int sdhci_setup_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_cleanup_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
int __sdhci_add_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
int sdhci_add_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_remove_host(struct sdhci_host *host, int dead)
{ … }
EXPORT_SYMBOL_GPL(…);
void sdhci_free_host(struct sdhci_host *host)
{ … }
EXPORT_SYMBOL_GPL(…);
static int __init sdhci_drv_init(void)
{ … }
static void __exit sdhci_drv_exit(void)
{ … }
module_init(…) …;
module_exit(sdhci_drv_exit);
module_param(debug_quirks, uint, 0444);
module_param(debug_quirks2, uint, 0444);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_PARM_DESC(…) …;
MODULE_PARM_DESC(…) …;