块设备驱动3--sd卡驱动2(linux-3.2.36的host.h分析)

来源:互联网 发布:顶级域名服务器 权威 编辑:程序博客网 时间:2024/06/09 15:33
/* *  linux/include/linux/mmc/host.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  Host driver specific definitions. */#ifndef LINUX_MMC_HOST_H#define LINUX_MMC_HOST_H#include <linux/leds.h>#include <linux/sched.h>#include <linux/fault-inject.h>#include <linux/mmc/core.h>#include <linux/mmc/pm.h>//struct mmc_ios主要是通过mmc_set_ios()调用host->ops->set_ios()//set_ios()由驱动提供,所以这些结构由host驱动处理,core只管用struct mmc_ios {unsigned intclock;/* clock rate */ //时钟速度unsigned shortvdd; //电压/* vdd stores the bit number of the selected voltage range from below. */unsigned charbus_mode;/* command output mode *///这是io口的类型,对于我这个电气自动化学生还是懂点的,不过不细说了#define MMC_BUSMODE_OPENDRAIN1 //开漏#define MMC_BUSMODE_PUSHPULL2 //推挽unsigned charchip_select;/* SPI chip select */#define MMC_CS_DONTCARE0 //不关心#define MMC_CS_HIGH1 //高速#define MMC_CS_LOW2 //低速/*        if (mmc_host_is_spi(host))                host->ios.chip_select = MMC_CS_HIGH;        else                host->ios.chip_select = MMC_CS_DONTCARE;*/unsigned charpower_mode;/* power supply mode */#define MMC_POWER_OFF0//关#define MMC_POWER_UP1//开#define MMC_POWER_ON2//也是开,s3c2440处理和up一样unsigned charbus_width;/* data bus width */ //数据总线宽度#define MMC_BUS_WIDTH_10 //1位#define MMC_BUS_WIDTH_42 //4位#define MMC_BUS_WIDTH_83 //8位unsigned chartiming;/* timing specification used */ //时序规范使用#define MMC_TIMING_LEGACY0 //旧的#define MMC_TIMING_MMC_HS1 //mmc#define MMC_TIMING_SD_HS2 //sd//UHS:超高速版。UHS-I: 超高速版1//UHS是一种速度标准。//下面是UHS-I的5种模式,在SDHCI标准中有个叫Host Control 2的寄存器//它的第0~2位就是选择UHS的模式#define MMC_TIMING_UHS_SDR12MMC_TIMING_LEGACY#define MMC_TIMING_UHS_SDR25MMC_TIMING_SD_HS#define MMC_TIMING_UHS_SDR503#define MMC_TIMING_UHS_SDR1044#define MMC_TIMING_UHS_DDR505#define MMC_SDR_MODE0#define MMC_1_2V_DDR_MODE1#define MMC_1_8V_DDR_MODE2unsigned charsignal_voltage;/* signalling voltage (1.8V or 3.3V) */ //上面说信号电压(1.8v 或 3.3v),没有提到1.2v//我看了SDHCI,还是Host Control 2的第3位 1: 1.8v 0: 3.3v//也没提到1.2v. 不过代码中提到eMMC卡可以支持1.2v或3.3v//eMMC:(Embedded Multi Media Card),这东西的封装是:小型的//BGA 封装。#define MMC_SIGNAL_VOLTAGE_3300#define MMC_SIGNAL_VOLTAGE_1801#define MMC_SIGNAL_VOLTAGE_1202unsigned chardrv_type;/* driver type (A, B, C, D) *///还是Host Control 2寄存器的4~5位选择,默认是B//UHS-I卡1.8v时才有效,3.3v无效//还有Preset Value Enable = 0时可以被主机设置//Preset Value Enable = 1时由Preset Value寄存器决定/*B:默认的驱动。50欧姆传输线阻抗。支持UHS104和UHS50卡。下面的都以B为参考。A:x1.5驱动(是50/1.5 = 33欧姆)。支持208MHzC:x0.75。支持208MHz的最弱驱动。D:x0.5。这个主要是速度不是要紧的,重要是低noise,低EMI。最大频率由主机设计确定。*/#define MMC_SET_DRIVER_TYPE_B0#define MMC_SET_DRIVER_TYPE_A1#define MMC_SET_DRIVER_TYPE_C2#define MMC_SET_DRIVER_TYPE_D3};//下面是写驱动要搞定的接口,如果你的硬件支持SDHCI。你可能看不到这个。//已在sdhci.c统一实现。struct mmc_host_ops {/* * Hosts that support power saving can use the 'enable' and 'disable' * methods to exit and enter power saving states. 'enable' is called * when the host is claimed and 'disable' is called (or scheduled with * a delay) when the host is released. The 'disable' is scheduled if * the disable delay set by 'mmc_set_disable_delay()' is non-zero, * otherwise 'disable' is called immediately. 'disable' may be * scheduled repeatedly, to permit ever greater power saving at the * expense of ever greater latency to re-enable. Rescheduling is * determined by the return value of the 'disable' method. A positive * value gives the delay in milliseconds. * * In the case where a host function (like set_ios) may be called * with or without the host claimed, enabling and disabling can be * done directly and will nest correctly. Call 'mmc_host_enable()' and * 'mmc_host_lazy_disable()' for this purpose, but note that these * functions must be paired. * * Alternatively, 'mmc_host_enable()' may be paired with * 'mmc_host_disable()' which calls 'disable' immediately.  In this * case the 'disable' method will be called with 'lazy' set to 0. * This is mainly useful for error paths. * * Because lazy disable may be called from a work queue, the 'disable' * method must claim the host when 'lazy' != 0, which will work * correctly because recursion is detected and handled. *//*上面解释了一大堆,自己看看。我说一下调用过程。at91_mci.c sd卡at91_mci_driver->at91_mci_suspend()->mmc_suspend_host()->host->bus_ops->suspend()(sd就是mmc_sd_suspend)->  /    __mmc_claim_host()->mmc_release_host()->mmc_host_lazy_disable()->mmc_host_do_disable()->host->ops->disable()    上面是disable的调用过程,enable从resume开始,不细说了!*/int (*enable)(struct mmc_host *host);int (*disable)(struct mmc_host *host, int lazy);/* * It is optional for the host to implement pre_req and post_req in * order to support double buffering of requests (prepare one * request while another request is active). * pre_req() must always be followed by a post_req(). * To undo a call made to pre_req(), call post_req() with * a nonzero err condition. *///为了双缓冲,一个准备,一个活动的,数据都是通过请求传输的void(*post_req)(struct mmc_host *host, struct mmc_request *req,    int err);void(*pre_req)(struct mmc_host *host, struct mmc_request *req,   bool is_first_req);void(*request)(struct mmc_host *host, struct mmc_request *req);/*看看程序的调用,先看request()mmc_set_signal_vlotage()主要send CMD11(切换电压)                cmd.opcode = SD_SWITCH_VOLTAGE;                cmd.arg = 0;                cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;                err = mmc_wait_for_cmd(host, &cmd, 0);                if (err)                        return err;在mmc_wait_for_cmd()中    mrq.cmd = cmd;        cmd->data = NULL;        mmc_wait_for_req(host, &mrq);    mmc_wait_for_req()原型:void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq){__mmc_start_req(host, mrq);*********************************************************************************__mmc_start_req()原型:static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq){init_completion(&mrq->completion);//初始化完成量mrq->done = mmc_wait_done;//函数指针done赋值(由mmc_request_done()调用)mmc_start_request(host, mrq);//这个不贴了,最终调用host->ops->request(),就是这里的request()}*********************************************************************************mmc_wait_for_req_done(host, mrq);//这个函数会等待一个完成量(由mmc_request_done()报告完成),//如果出现错误,会再一次调用host->ops->request()//mmc_request_done()一般在host->ops->request()中调用,}    request()肯定是少不了寄存器操作,这正是写驱动要做的事。    post_req和pre_req实现它们的驱动比较少    在core.c中是用mmc_post_req()和mmc_pre_req()调用    struct mmc_async_req *mmc_start_req(struct mmc_host *host,                                    struct mmc_async_req *areq, int *error)    代码给出的解释是start a non_blocking request,上面说的mmc_wait_for_cmd,肯定是阻塞在card/block调用了这个函数struct mmc_async_req *mmc_start_req(struct mmc_host *host,struct mmc_async_req *areq, int *error){int err = 0;struct mmc_async_req *data = host->areq;            if (areq)mmc_pre_req(host, areq->mrq, !host->areq);if (host->areq) {//当前有一个活动的异步reqmmc_wait_for_req_done(host, host->areq->mrq);err = host->areq->err_check(host->card, host->areq);if (err) {mmc_post_req(host, host->areq->mrq, 0);if (areq)mmc_post_req(host, areq->mrq, -EINVAL);host->areq = NULL;goto out;}}if (areq)__mmc_start_req(host, areq->mrq);if (host->areq)mmc_post_req(host, host->areq->mrq, 0);host->areq = areq; out:if (error)*error = err;return data;}上面的东西其实非常简单,我们先假设post_req pre_req没有。那么第一次调用时,host->areq为NULL,会直接调用__mmc_start_req(),下一次调用,如果没有处理完再mmc_wait_for_req_done()等待,其实就是把等待放到了下一次。如果你加上post_req pre_req。多的逻辑就是不管当前有没有活动请求,先准备,当前没有当然直接运行,如果有,等待完成。出错的话就mmc_post_req(host, areq->mrq, -EINVAL);取消新准备的req,因为它不能运行直到错误接触。*//* * Avoid calling these three functions too often or in a "fast path", * since underlaying controller might implement them in an expensive * and/or slow way. * * Also note that these functions might sleep, so don't call them * in the atomic contexts! 可能睡眠,不能在原子上下文运行。 * * Return values for the get_ro callback should be: *   0 for a read/write card 0代表可读写 *   1 for a read-only card 1代表只读(写保护) *   -ENOSYS when not supported (equal to NULL callback) *   or a negative errno value when something bad happened 在SDCHI中有个寄存器Present State,它的第19位代表是否写保护 对应的硬件是WP脚 * * Return values for the get_cd callback should be: *   0 for a absent card 无卡 *   1 for a present card 有卡 *   -ENOSYS when not supported (equal to NULL callback) *   or a negative errno value when something bad happened 同样是寄存器Present State,它的第18位代表卡是否存在     对应的硬件是nCD脚,检测这个还有可能注意去抖动,但是 我看了s3cmci并没有这么做。直接读脚(因为它不支持SDCHI)。 */void(*set_ios)(struct mmc_host *host, struct mmc_ios *ios);//看看上面的struct mmc_ios。你就知道可能要涉及哪些东西了。int(*get_ro)(struct mmc_host *host);int(*get_cd)(struct mmc_host *host);void(*enable_sdio_irq)(struct mmc_host *host, int enable);/* optional callback for HC quirks */void(*init_card)(struct mmc_host *host, struct mmc_card *card);int(*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);//电压切换int(*execute_tuning)(struct mmc_host *host);//执行调整,SDHCI就是发送CMD19//曾经看到一个文章说:MMC支持CMD14和CMD19进行主线测试,从而选择合适总线进行通信。SD则不支持。//但是SDHCI中说到了CMD19void(*enable_preset_value)(struct mmc_host *host, bool enable);//SDCHI中的Host Control 2 Register//第15位控制int(*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);//整个host目录就没有发现这个应用,不过SDHCI有A B C D,不知道为什么没有实现这个接口void(*hw_reset)(struct mmc_host *host);};struct mmc_card;struct device;struct mmc_async_req {/* active mmc request */struct mmc_request*mrq;/* * Check error status of completed mmc request. * Returns 0 if success otherwise non zero. */int (*err_check) (struct mmc_card *, struct mmc_async_req *);//这个check,在card目录下的block.c和mmc_test.c实现,不需要驱动实现。};struct mmc_host {struct device*parent;struct deviceclass_dev;//上面是建立设备关系用的intindex;//dev_set_name(&host->class_dev, "mmc%d", host->index);//看到上面这句,我想你应该知道index是干什么的了。const struct mmc_host_ops *ops;unsigned intf_min;unsigned intf_max;unsigned intf_init;//上面的f_*是频率的最小值,最大值,初始值u32ocr_avail;u32ocr_avail_sdio;/* SDIO-specific OCR */u32ocr_avail_sd;/* SD-specific OCR */u32ocr_avail_mmc;/* MMC-specific OCR *///上面是OCR寄存器值,记录了电压值,下面有宏定义struct notifier_blockpm_notify;//通知链//register_pm_notifier(&host->pm_notify);//这个电源管理提供的通知链#define MMC_VDD_165_1950x00000080/* VDD voltage 1.65 - 1.95 */#define MMC_VDD_20_210x00000100/* VDD voltage 2.0 ~ 2.1 */#define MMC_VDD_21_220x00000200/* VDD voltage 2.1 ~ 2.2 */#define MMC_VDD_22_230x00000400/* VDD voltage 2.2 ~ 2.3 */#define MMC_VDD_23_240x00000800/* VDD voltage 2.3 ~ 2.4 */#define MMC_VDD_24_250x00001000/* VDD voltage 2.4 ~ 2.5 */#define MMC_VDD_25_260x00002000/* VDD voltage 2.5 ~ 2.6 */#define MMC_VDD_26_270x00004000/* VDD voltage 2.6 ~ 2.7 */#define MMC_VDD_27_280x00008000/* VDD voltage 2.7 ~ 2.8 */#define MMC_VDD_28_290x00010000/* VDD voltage 2.8 ~ 2.9 */#define MMC_VDD_29_300x00020000/* VDD voltage 2.9 ~ 3.0 */#define MMC_VDD_30_310x00040000/* VDD voltage 3.0 ~ 3.1 */#define MMC_VDD_31_320x00080000/* VDD voltage 3.1 ~ 3.2 */#define MMC_VDD_32_330x00100000/* VDD voltage 3.2 ~ 3.3 */#define MMC_VDD_33_340x00200000/* VDD voltage 3.3 ~ 3.4 */#define MMC_VDD_34_350x00400000/* VDD voltage 3.4 ~ 3.5 */#define MMC_VDD_35_360x00800000/* VDD voltage 3.5 ~ 3.6 */unsigned longcaps;/* Host capabilities *///主机能力#define MMC_CAP_4_BIT_DATA(1 << 0)/* Can the host do 4 bit transfers */#define MMC_CAP_MMC_HIGHSPEED(1 << 1)/* Can do MMC high-speed timing */#define MMC_CAP_SD_HIGHSPEED(1 << 2)/* Can do SD high-speed timing */#define MMC_CAP_SDIO_IRQ(1 << 3)/* Can signal pending SDIO IRQs */#define MMC_CAP_SPI(1 << 4)/* Talks only SPI protocols */#define MMC_CAP_NEEDS_POLL(1 << 5)/* Needs polling for card-detection */ //轮询检测/*POLL其实是延时检测卡,当插入 SD卡之后,SD 主控制器上的探测引脚会产生一个中断,之后调用中断函数里的工作队列,然后执行工作队列里的 mmc_rescan 去扫描 SD 卡,为 SD 卡上电,发送地址,注册驱动等。考虑到插入 SD 卡需要一个短时间的过程(有个弹簧卡槽固定住 SD 卡)当然和SD主控制器的性能有关*/#define MMC_CAP_8_BIT_DATA(1 << 6)/* Can the host do 8 bit transfers */#define MMC_CAP_DISABLE(1 << 7)/* Can the host be disabled */#define MMC_CAP_NONREMOVABLE(1 << 8)/* Nonremovable e.g. eMMC *///不可移动,eMMC不可移动,eMMC是贴片式的#define MMC_CAP_WAIT_WHILE_BUSY(1 << 9)/* Waits while card is busy */#define MMC_CAP_ERASE(1 << 10)/* Allow erase/trim commands */#define MMC_CAP_1_8V_DDR(1 << 11)/* can support *//* DDR mode at 1.8V */#define MMC_CAP_1_2V_DDR(1 << 12)/* can support *//* DDR mode at 1.2V */#define MMC_CAP_POWER_OFF_CARD(1 << 13)/* Can power off after boot */ #define MMC_CAP_BUS_WIDTH_TEST(1 << 14)/* CMD14/CMD19 bus width ok *///mmc支持CMD14/CMD19#define MMC_CAP_UHS_SDR12(1 << 15)/* Host supports UHS SDR12 mode */#define MMC_CAP_UHS_SDR25(1 << 16)/* Host supports UHS SDR25 mode */#define MMC_CAP_UHS_SDR50(1 << 17)/* Host supports UHS SDR50 mode */#define MMC_CAP_UHS_SDR104(1 << 18)/* Host supports UHS SDR104 mode */#define MMC_CAP_UHS_DDR50(1 << 19)/* Host supports UHS DDR50 mode */#define MMC_CAP_SET_XPC_330(1 << 20)/* Host supports >150mA current at 3.3V */#define MMC_CAP_SET_XPC_300(1 << 21)/* Host supports >150mA current at 3.0V */#define MMC_CAP_SET_XPC_180(1 << 22)/* Host supports >150mA current at 1.8V */#define MMC_CAP_DRIVER_TYPE_A(1 << 23)/* Host supports Driver Type A */#define MMC_CAP_DRIVER_TYPE_C(1 << 24)/* Host supports Driver Type C */#define MMC_CAP_DRIVER_TYPE_D(1 << 25)/* Host supports Driver Type D */#define MMC_CAP_MAX_CURRENT_200(1 << 26)/* Host max current limit is 200mA */#define MMC_CAP_MAX_CURRENT_400(1 << 27)/* Host max current limit is 400mA */#define MMC_CAP_MAX_CURRENT_600(1 << 28)/* Host max current limit is 600mA */#define MMC_CAP_MAX_CURRENT_800(1 << 29)/* Host max current limit is 800mA */#define MMC_CAP_CMD23(1 << 30)/* CMD23 supported. */ //CMD23是为了停止多块读操作#define MMC_CAP_HW_RESET(1 << 31)/* Hardware reset */unsigned intcaps2;/* More host capabilities */#define MMC_CAP2_BOOTPART_NOACC(1 << 0)/* Boot partition no access */ //引导分区不能访问//eMMC有boot partition。SDHCI-PCI不能访问,不清楚为什么#define MMC_CAP2_CACHE_CTRL(1 << 1)/* Allow cache control */ //允许c、ache控制, core.c中的cache操作会判断这个#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)/* Notify poweroff supported */ //支持通知掉电#define MMC_CAP2_NO_MULTI_READ(1 << 3)/* Multiblock reads don't work */ //多块读取不起作用mmc_pm_flag_tpm_caps;/* supported pm features */unsigned int        power_notify_type;#define MMC_HOST_PW_NOTIFY_NONE0#define MMC_HOST_PW_NOTIFY_SHORT1#define MMC_HOST_PW_NOTIFY_LONG2//这上面short和long指的是时间,写EXT_CSD寄存器的等待时间//secureMMC有EXT_CSD寄存器/*EXT_CSD:Spec Ver 3.0 EXT_CSD的存在允许操作MMC的不同模式,一个特殊SWITCH命令被执行去切换不同的模式。然而当切换到不是标准的模式(Flash- or ROM-MMC 模式),classes 1,3,5,6,7,8,9,10的命令码不能用。这些命令码被特殊命令占用。这些特殊模式就是SecureMMC说的安全模式。*/#ifdef CONFIG_MMC_CLKGATEintclk_requests;/* internal reference counter */ //函数mmc_host_clk_hold()即检查设置clk不是非零,切让此值加一,防止其他的clk操作。unsigned intclk_delay;/* number of MCI clk hold cycles */boolclk_gated;/* clock gated */ //时钟门控struct work_structclk_gate_work; /* delayed clock gate */unsigned intclk_old;/* old clock value cache */spinlock_tclk_lock;/* lock for clk fields */struct mutexclk_gate_mutex;/* mutex for clock gating */#endif/* host specific block data */unsigned intmax_seg_size;/* see blk_queue_max_segment_size *///一个请求的段的最多有多少字节unsigned shortmax_segs;/* see blk_queue_max_segments *///一个队列段数量的最大值unsigned shortunused;unsigned intmax_req_size;/* maximum number of bytes in one req *///一个请求的最大字节数unsigned intmax_blk_size;/* maximum size of one mmc block *///一个mmc块的最大大小unsigned intmax_blk_count;/* maximum number of blocks in one req *///一个请求中块的大小unsigned intmax_discard_to;/* max. discard timeout in ms *///判断卡不能用的超时时间/* private data */spinlock_tlock;/* lock for claim and bus ops */struct mmc_iosios;/* current io bus settings */u32ocr;/* the current OCR setting *//* group bitfields together to minimize padding */unsigned intuse_spi_crc:1;unsigned intclaimed:1;/* host exclusively claimed *///__mmc_claim_host()使用的unsigned intbus_dead:1;/* bus has been released *///mmc_detach_bus()会使其为1#ifdef CONFIG_MMC_DEBUGunsigned intremoved:1;/* host is being removed */#endif/* Only used with MMC_CAP_DISABLE */intenabled;/* host is enabled */intrescan_disable;/* disable card detection *///在suspend时会使其为1,intnesting_cnt;/* "enable" nesting count */ //主机被使能的计数,防止重复enable和disableinten_dis_recurs;/* detect recursion *///在disable和enable之前都会把它赋值为1,结束为0。防止同事enable和disableunsigned intdisable_delay;/* disable delay in msecs */struct delayed_workdisable;/* disabling work */    //延时disable卡struct mmc_card*card;/* device attached to this host */wait_queue_head_twq;struct task_struct*claimer;/* task that has host claimed */ //主机声明的任务intclaim_cnt;/* "claim" nesting count */struct delayed_workdetect;//延时检测的任务const struct mmc_bus_ops *bus_ops;/* current bus driver *//*struct mmc_bus_ops {        int (*awake)(struct mmc_host *);//唤醒        int (*sleep)(struct mmc_host *);//睡眠        void (*remove)(struct mmc_host *);//sd卡拔出        void (*detect)(struct mmc_host *);//检测sd卡        int (*suspend)(struct mmc_host *);//挂起        int (*resume)(struct mmc_host *);//恢复        int (*power_save)(struct mmc_host *);//保存电源模式        int (*power_restore)(struct mmc_host *);//电源模式恢复};*/unsigned intbus_refs;/* reference counter */ //总线操作计数unsigned intsdio_irqs;//中断号struct task_struct*sdio_irq_thread;//sdio.c中会建立一个线程用反复调用__mmc_claim_host直到成功。atomic_tsdio_irq_thread_abort;mmc_pm_flag_tpm_flags;/* requested pm features */#ifdef CONFIG_LEDS_TRIGGERSstruct led_trigger*led;/* activity led */#endif#ifdef CONFIG_REGULATORboolregulator_enabled; /* regulator state */#endifstruct dentry*debugfs_root;//debugfs使用struct mmc_async_req*areq;/* active async req *///上面有说#ifdef CONFIG_FAIL_MMC_REQUESTstruct fault_attrfail_mmc_request;#endifunsigned longprivate[0] ____cacheline_aligned;};//分配一个struct mmc_host的,extra是你的私有数据长度//分配的大小是sizeof(struct mmc_host) + extraextern struct mmc_host *mmc_alloc_host(int extra, struct device *);//每一个struct mmc_host初始化之后要用mmc_add_host添加extern int mmc_add_host(struct mmc_host *);extern void mmc_remove_host(struct mmc_host *);extern void mmc_free_host(struct mmc_host *);//看上面的结构体,你可以看到private是放在最后的//所以就是我们在mmc_alloc_host中对应的extra所申请的空间static inline void *mmc_priv(struct mmc_host *host){return (void *)host->private;}#define mmc_host_is_spi(host)((host)->caps & MMC_CAP_SPI)#define mmc_dev(x)((x)->parent)#define mmc_classdev(x)(&(x)->class_dev)#define mmc_hostname(x)(dev_name(&(x)->class_dev))//驱动的suspend和resume一定会调用这些extern int mmc_suspend_host(struct mmc_host *);extern int mmc_resume_host(struct mmc_host *);/*下面两个对应这个struct mmc_bus_ops中        int (*power_save)(struct mmc_host *);//保存电源模式        int (*power_restore)(struct mmc_host *);//电源模式恢复*/extern int mmc_power_save_host(struct mmc_host *host);extern int mmc_power_restore_host(struct mmc_host *host);//mmc_detect_change对应struct delayed_workdetect;检测为了防抖动,做延时extern void mmc_detect_change(struct mmc_host *, unsigned long delay);//request结束extern void mmc_request_done(struct mmc_host *, struct mmc_request *);//关闭或开启cache,会控制EXT_CSD寄存器extern int mmc_cache_ctrl(struct mmc_host *, u8);/*sdio中断检测:SDIO spec中的话for SDIO, pin 8 is used for interrupt pin. s3cmci.c中                if (gpio_get_value(S3C2410_GPE(8)) == 0) {                        pr_debug("%s: signalling irq\n", __func__);                        mmc_signal_sdio_irq(host->mmc);                }//直接判断gpio口*/static inline void mmc_signal_sdio_irq(struct mmc_host *host){host->ops->enable_sdio_irq(host, 0);//这个驱动去实现wake_up_process(host->sdio_irq_thread);/*唤醒的线程名叫ksdioirqd对于不支持SDIO 中断的host,kerne会采用polling的方式来实现伪中断:不断的唤醒ksdioirqd来检查SDIO的CCCR的中断标志位。支持SDIO中断的host,则直接在SDIO中断产生的时候,由host的驱动来负责通知mmc子系统唤醒ksdioirqd来检查中断。*/}struct regulator;//通过ocr寄存器调节电压#ifdef CONFIG_REGULATORint mmc_regulator_get_ocrmask(struct regulator *supply);int mmc_regulator_set_ocr(struct mmc_host *mmc,struct regulator *supply,unsigned short vdd_bit);#elsestatic inline int mmc_regulator_get_ocrmask(struct regulator *supply){return 0;}static inline int mmc_regulator_set_ocr(struct mmc_host *mmc, struct regulator *supply, unsigned short vdd_bit){return 0;}#endif//下面一些根据名字看看吧,不说了int mmc_card_awake(struct mmc_host *host);int mmc_card_sleep(struct mmc_host *host);int mmc_card_can_sleep(struct mmc_host *host);int mmc_host_enable(struct mmc_host *host);int mmc_host_disable(struct mmc_host *host);int mmc_host_lazy_disable(struct mmc_host *host);int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *);static inline void mmc_set_disable_delay(struct mmc_host *host, unsigned int disable_delay){host->disable_delay = disable_delay;}/* Module parameter */extern int mmc_assume_removable;static inline int mmc_card_is_removable(struct mmc_host *host){return !(host->caps & MMC_CAP_NONREMOVABLE) && mmc_assume_removable;}static inline int mmc_card_keep_power(struct mmc_host *host){return host->pm_flags & MMC_PM_KEEP_POWER;}static inline int mmc_card_wake_sdio_irq(struct mmc_host *host){return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ;}static inline int mmc_host_cmd23(struct mmc_host *host){return host->caps & MMC_CAP_CMD23;}static inline int mmc_boot_partition_access(struct mmc_host *host){return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);}#endif /* LINUX_MMC_HOST_H */

0 0
原创粉丝点击