linux设备模型之spi子系统

linux设备模型之spi子系统

===============================
本文系本站原创,欢迎转载!
转载请注明出处:http://www.cnblogs.com/gdt-a20

===============================

      相比于前面介绍的i2c子系统,spi子系统相对简单,和i2c的结构也很相似,这里主要介绍一下平台无关部分的代码。先概括的说一下,spi总线或者说是spi控制器用结构体struct spi_master来表述,而一般不会明显的主动实现这个结构而是借助板级的一些信息结构,利用spi的模型填充,存在板级信息的一条链表board_list,上面挂接着板级spi设备的描述信息,其挂接的结构是struct boardinfo,这个结构内部嵌入了具体的板级spi设备所需信息结构struct spi_board_info,对于要操控的spi设备,用struct spidev_data来描述,内嵌了具体设备信息结构struct spi_device,并通过struct spi_device->device_entry成员挂接到全局spi设备链表device_list,结构struct spi_device就是根据前面board_list上所挂的信息填充的,而driver端比较简单,用struct spi_driver来描述,一会儿会看到该结构和标准的platform非常相似,总括的说下一般编写流程:对于soc,spi控制器一般注册成platform,当driver匹配后,会根据platform_device等信息构造出spi_master,一般发生在driver的probe函数,并且注册该master,在master的注册过程中会去遍历board_list找到bus号相同的spi设备信息,并实例化它,好了先就说这么多,下面先看一下具体的数据结构。

一、spi相关的数据结构

      先看一下spi设备的板级信息填充的结构:

     

复制代码
 1 struct boardinfo {
 2     struct list_head    list;              //用于挂接到链表头board_list上              
 3     unsigned        n_board_info;      //设备信息号,spi_board_info成员的编号
 4     struct spi_board_info    board_info[0];     //内嵌的spi_board_info结构
 5 };
 6 //其中内嵌的描述spi设备的具体信息的结构struct spi_board_info为:
 7 struct spi_board_info {
 8     /* the device name and module name are coupled, like platform_bus;
 9      * "modalias" is normally the driver name.
10      *
11      * platform_data goes to spi_device.dev.platform_data,
12      * controller_data goes to spi_device.controller_data,
13      * irq is copied too
14 */
15     char        modalias[SPI_NAME_SIZE];     //名字
16     const void    *platform_data;              //如同注释写的指向spi_device.dev.platform_data
17     void        *controller_data;            //指向spi_device.controller_data
18     int        irq;                         //中断号
19     /* slower signaling on noisy or low voltage boards */
20     u32        max_speed_hz;                //时钟速率
21     /* bus_num is board specific and matches the bus_num of some
22      * spi_master that will probably be registered later.
23      *
24      * chip_select reflects how this chip is wired to that master;
25      * it's less than num_chipselect.
26 */
27     u16        bus_num;                     //所在的spi总线编号
28     u16        chip_select;                   
29     /* mode becomes spi_device.mode, and is essential for chips
30      * where the default of SPI_CS_HIGH = 0 is wrong.
31 */
32     u8        mode;                        //模式
33     /* ... may need additional spi_device chip config data here.
34      * avoid stuff protocol drivers can set; but include stuff
35      * needed to behave without being bound to a driver:
36      *  - quirks like clock rate mattering when not selected
37 */
38 }; 
复制代码

 

     利用boardinfo->list成员会将自身挂接到全局的board_list链表上。

     再来看一下spi控制器的表述结构:

 

复制代码
 1 struct spi_master {
 2     struct device    dev;                //内嵌的标准dev结构
 3     /* other than negative (== assign one dynamically), bus_num is fully
 4      * board-specific.  usually that simplifies to being SOC-specific.
 5      * example:  one SOC has three SPI controllers, numbered 0..2,
 6      * and one board's schematics might show it using SPI-2.  software
 7      * would normally use bus_num=2 for that controller.
 8 */
 9     s16            bus_num;                  //标识的总线号
10     /* chipselects will be integral to many controllers; some others
11      * might use board-specific GPIOs.
12 */
13     u16            num_chipselect;
14     /* some SPI controllers pose alignment requirements on DMAable
15      * buffers; let protocol drivers know about these requirements.
16 */
17     u16            dma_alignment;           //dma对其要求
18     /* spi_device.mode flags understood by this controller driver */
19     u16            mode_bits;               //代表操作的spi_device.mode
20     /* other constraints relevant to this driver */
21     u16            flags;                   //另外的一些标志
22 #define SPI_MASTER_HALF_DUPLEX    BIT(0)        /* can't do full duplex */
23 #define SPI_MASTER_NO_RX    BIT(1)        /* can't do buffer read */
24 #define SPI_MASTER_NO_TX    BIT(2)        /* can't do buffer write */
25     /* lock and mutex for SPI bus locking */
26     spinlock_t        bus_lock_spinlock;
27     struct mutex        bus_lock_mutex;
28     /* flag indicating that the SPI bus is locked for exclusive use */
29     bool            bus_lock_flag;
30     /* Setup mode and clock, etc (spi driver may call many times).
31      *
32      * IMPORTANT:  this may be called when transfers to another
33      * device are active.  DO NOT UPDATE SHARED REGISTERS in ways
34      * which could break those transfers.
35 */
36     int            (*setup)(struct spi_device *spi);   //设置模式
37     /* bidirectional bulk transfers
38      *
39      * + The transfer() method may not sleep; its main role is
40      *   just to add the message to the queue.
41      * + For now there's no remove-from-queue operation, or
42      *   any other request management
43      * + To a given spi_device, message queueing is pure fifo
44      *
45      * + The master's main job is to process its message queue,
46      *   selecting a chip then transferring data
47      * + If there are multiple spi_device children, the i/o queue
48      *   arbitration algorithm is unspecified (round robin, fifo,
49      *   priority, reservations, preemption, etc)
50      *
51      * + Chipselect stays active during the entire message
52      *   (unless modified by spi_transfer.cs_change != 0).
53      * + The message transfers use clock and SPI mode parameters
54      *   previously established by setup() for this device
55 */
56     int            (*transfer)(struct spi_device *spi,    //传输函数
57                         struct spi_message *mesg);
58     /* called on release() to free memory provided by spi_master */
59     void            (*cleanup)(struct spi_device *spi);
60 };
复制代码

 

   而对于要操控的spi总线上的设备,其表述结构为:

复制代码
 1 struct spi_device {
 2     struct device        dev;               //内嵌标准device结构体
 3     struct spi_master    *master;         //spi主控制器
 4     u32            max_speed_hz;              //时钟速率
 5     u8            chip_select;               //设备编号
 6     u8            mode;                      //模式
 7 #define    SPI_CPHA    0x01            /* clock phase */
 8 #define    SPI_CPOL    0x02            /* clock polarity */
 9 #define    SPI_MODE_0    (0|0)            /* (original MicroWire) */
10 #define    SPI_MODE_1    (0|SPI_CPHA)
11 #define    SPI_MODE_2    (SPI_CPOL|0)
12 #define    SPI_MODE_3    (SPI_CPOL|SPI_CPHA)
13 #define    SPI_CS_HIGH    0x04            /* chipselect active high? */
14 #define    SPI_LSB_FIRST    0x08            /* per-word bits-on-wire */
15 #define    SPI_3WIRE    0x10            /* SI/SO signals shared */
16 #define    SPI_LOOP    0x20            /* loopback mode */
17 #define    SPI_NO_CS    0x40            /* 1 dev/bus, no chipselect */
18 #define    SPI_READY    0x80            /* slave pulls low to pause */
19     u8            bits_per_word;
20     int            irq;                        //中断号
21     void            *controller_state;        //控制状态
22     void            *controller_data;         //私有数据
23     char            modalias[SPI_NAME_SIZE];  //名字
24     /*
25      * likely need more hooks for more protocol options affecting how
26      * the controller talks to each chip, like:
27      *  - memory packing (12 bit samples into low bits, others zeroed)
28      *  - priority
29      *  - drop chipselect after each word
30      *  - chipselect delays
31      *  - ...
32 */
33 };
复制代码

 

再看一下对于spi设备结构更高层次的表述结构:

复制代码
 1 struct spidev_data {
 2     dev_t            devt;
 3     spinlock_t        spi_lock;
 4     struct spi_device    *spi;            //指向spi设备结构
 5     struct list_head    device_entry;    //spi设备链表device_list挂接点   
 6     /* buffer is NULL unless this device is open (users > 0) */
 7     struct mutex        buf_lock;
 8     unsigned        users;
 9     u8            *buffer;
10 };
复制代码

 

而driver端的表述结构struct spi_driver,具体如下:

复制代码
1 struct spi_driver {
2     const struct spi_device_id *id_table; //匹配的设备表
3     int            (*probe)(struct spi_device *spi);
4     int            (*remove)(struct spi_device *spi);
5     void            (*shutdown)(struct spi_device *spi);
6     int            (*suspend)(struct spi_device *spi, pm_message_t mesg);
7     int            (*resume)(struct spi_device *spi);
8     struct device_driver    driver;
9 };
复制代码

 

是不是很标准?哈,好了,关于相关的数据结构就先介绍这么多。

二、spi核心代码的初始化分析

复制代码
 1 static int __init spi_init(void)
 2 {
 3     int    status;
 4  
 5   //其中buf为static u8    *buf, 
 6 //SPI_BUFSIZ为#define    SPI_BUFSIZ    max(32,SMP_CACHE_BYTES)
 7     buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
 8     if (!buf) {
 9         status = -ENOMEM;
10         goto err0;
11     }
12   
13   //注册spi_bus
14     status = bus_register(&spi_bus_type);
15     if (status < 0)
16         goto err1;
17   
18   //在sys/class下产生spi_master这个节点,用于自动产生设备节点
19 //下面挂接的是控制器的节点
20     status = class_register(&spi_master_class);
21     if (status < 0)
22         goto err2;
23     return 0;
24 err2:
25     bus_unregister(&spi_bus_type);
26 err1:
27     kfree(buf);
28     buf = NULL;
29 err0:
30     return status;
31 }
32 //其中注册bus结构为
33 struct bus_type spi_bus_type = {
34     .name        = "spi",
35     .dev_attrs    = spi_dev_attrs,
36     .match        = spi_match_device,    //匹配函数
37     .uevent        = spi_uevent,
38     .suspend    = spi_suspend,
39     .resume        = spi_resume,
40 };
41 //类函数为
42 static struct class spi_master_class = {
43     .name        = "spi_master",
44     .owner        = THIS_MODULE,
45     .dev_release    = spi_master_release,
46 };
47 //顺便把driver与device的匹配函数也一起分析了吧,很简单
48 static int spi_match_device(struct device *dev, struct device_driver *drv)
49 {
50     const struct spi_device    *spi = to_spi_device(dev);
51     const struct spi_driver    *sdrv = to_spi_driver(drv);
52     /* Attempt an OF style match */
53     
54     //利用of表进行匹配
55     if (of_driver_match_device(dev, drv))
56         return 1;
57   
58         //利用id表进行匹配
59     if (sdrv->id_table)
60         return !!spi_match_id(sdrv->id_table, spi);
61   
62         //利用名字进行匹配
63     return strcmp(spi->modalias, drv->name) == 0;
64 } 
复制代码

 

      首先看一下spi总线的注册代码很简单,位于driver/spi/spi.c下:

    再看一下driver的注册,spi_register_driver函数:

复制代码
 1 int spi_register_driver(struct spi_driver *sdrv)
 2 {
 3     
 4     //很类似于platfor的注册,很简单,
 5 //就不具体介绍了
 6     sdrv->driver.bus = &spi_bus_type;
 7     if (sdrv->probe)
 8         sdrv->driver.probe = spi_drv_probe;
 9     if (sdrv->remove)
10         sdrv->driver.remove = spi_drv_remove;
11     if (sdrv->shutdown)
12         sdrv->driver.shutdown = spi_drv_shutdown;
13         
14     //注册标准的driver,此时会去匹配bus设备链表上
15 //支持的device,找到会调用相应函数
16     return driver_register(&sdrv->driver);
17 }
复制代码

 

还有个板级信息的添加函数:

复制代码
 1 int __init
 2 spi_register_board_info(struct spi_board_info const *info, unsigned n)
 3 {
 4     struct boardinfo    *bi;
 5     bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL);
 6     if (!bi)
 7         return -ENOMEM;
 8     bi->n_board_info = n;
 9     memcpy(bi->board_info, info, n * sizeof *info);
10     mutex_lock(&board_lock);
11     list_add_tail(&bi->list, &board_list);
12     mutex_unlock(&board_lock);
13     return 0;
14 }
复制代码

 

函数很简单,利用定义的spi_board_info信息,填充了boardinfo结构,并挂到board_list链表。

最后来看一下一个重量级函数,master的注册函数:

复制代码
  1 int spi_register_master(struct spi_master *master)
  2 {
  3     static atomic_t        dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
  4     struct device        *dev = master->dev.parent;
  5     int            status = -ENODEV;
  6     int            dynamic = 0;
  7   //内嵌的标准设备结构必须初始化好
  8     if (!dev)
  9         return -ENODEV;
 10     /* even if it's just one always-selected device, there must
 11      * be at least one chipselect
 12 */
 13      
 14     //支持的设备数量为0,出错返回
 15     if (master->num_chipselect == 0)
 16         return -EINVAL;
 17     /* convention:  dynamically assigned bus IDs count down from the max */
 18     
 19     if (master->bus_num < 0) {
 20         /* FIXME switch to an IDR based scheme, something like
 21          * I2C now uses, so we can't run out of "dynamic" IDs
 22 */
 23       //控制器编号(总线编号)不能小于0
 24         master->bus_num = atomic_dec_return(&dyn_bus_id);
 25         dynamic = 1;
 26     }
 27     spin_lock_init(&master->bus_lock_spinlock);
 28     mutex_init(&master->bus_lock_mutex);
 29     master->bus_lock_flag = 0;
 30     /* register the device, then userspace will see it.
 31      * registration fails if the bus ID is in use.
 32 */
 33      
 34     //设置master->dev的名字,形式为spi+bus_num,如:spi0
 35     dev_set_name(&master->dev, "spi%u", master->bus_num);
 36     
 37     //注册master内嵌的标准device结构
 38     status = device_add(&master->dev);
 39     if (status < 0)
 40         goto done;
 41     dev_dbg(dev, "registered master %s%s/n", dev_name(&master->dev),
 42             dynamic ? " (dynamic)" : "");
 43     /* populate children from any spi device tables */
 44     
 45     //重点哦,扫描并实例化spi设备
 46     scan_boardinfo(master);
 47     status = 0;
 48     /* Register devices from the device tree */
 49     of_register_spi_devices(master);
 50 done:
 51     return status;
 52 }
 53 //先来看scan_boardinfo这个分支
 54 static void scan_boardinfo(struct spi_master *master)
 55 {
 56     struct boardinfo    *bi;
 57     mutex_lock(&board_lock);
 58     
 59     //找到我们注册的spi相关的板级信息结构体
 60 //还记得board_list吧
 61     list_for_each_entry(bi, &board_list, list) {
 62         struct spi_board_info    *chip = bi->board_info;
 63         unsigned        n;
 64     
 65     //因为可能存在多个spi总线,因此spi信息结构也会有
 66 //多个,找到bus号匹配的就对了
 67         for (n = bi->n_board_info; n > 0; n--, chip++) {
 68             if (chip->bus_num != master->bus_num)
 69                 continue;
 70             /* NOTE: this relies on spi_new_device to
 71              * issue diagnostics when given bogus inputs
 72 */
 73             
 74             //找到了就要实例化它上面的设备了
 75             (void) spi_new_device(master, chip);
 76         }
 77     }
 78     mutex_unlock(&board_lock);
 79 }
 80 //跟进spi_new_device函数
 81 struct spi_device *spi_new_device(struct spi_master *master,
 82                   struct spi_board_info *chip)
 83 {
 84     struct spi_device    *proxy;
 85     int            status;
 86     /* NOTE:  caller did any chip->bus_num checks necessary.
 87      *
 88      * Also, unless we change the return value convention to use
 89      * error-or-pointer (not NULL-or-pointer), troubleshootability
 90      * suggests syslogged diagnostics are best here (ugh).
 91 */
 92   
 93   //为需要实例化的设备分配内存
 94 //同时会将bus成员制定为spi_bus_type,parent
 95 //指定为该master,层次关系
 96     proxy = spi_alloc_device(master);
 97     if (!proxy)
 98         return NULL;
 99     WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
100   //各个成员赋值,都是用我们注册的板级信息
101     proxy->chip_select = chip->chip_select;
102     proxy->max_speed_hz = chip->max_speed_hz;
103     proxy->mode = chip->mode;
104     proxy->irq = chip->irq;
105     strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
106     proxy->dev.platform_data = (void *) chip->platform_data;
107     proxy->controller_data = chip->controller_data;
108     proxy->controller_state = NULL;
109   
110   //把该设备添加到spi总线
111     status = spi_add_device(proxy);
112     if (status < 0) {
113         spi_dev_put(proxy);
114         return NULL;
115     }
116     return proxy;
117 }
118 //继续spi_add_device函数
119 int spi_add_device(struct spi_device *spi)
120 {
121     static DEFINE_MUTEX(spi_add_lock);
122     struct device *dev = spi->master->dev.parent;
123     struct device *d;
124     int status;
125     /* Chipselects are numbered 0..max; validate. */
126     
127     //spi设备的编号不能大于master定义的最大数目
128     if (spi->chip_select >= spi->master->num_chipselect) {
129         dev_err(dev, "cs%d >= max %d/n",
130             spi->chip_select,
131             spi->master->num_chipselect);
132         return -EINVAL;
133     }
134     /* Set the bus ID string */
135     //设备节点名字,形式:spi0.0
136     dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev),
137             spi->chip_select);
138 
139     /* We need to make sure there's no other device with this
140      * chipselect **BEFORE** we call setup(), else we'll trash
141      * its configuration.  Lock against concurrent add() calls.
142 */
143     mutex_lock(&spi_add_lock);
144   
145   //确保设备不会重复注册
146     d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
147     if (d != NULL) {
148         dev_err(dev, "chipselect %d already in use/n",
149                 spi->chip_select);
150         put_device(d);
151         status = -EBUSY;
152         goto done;
153     }
154     /* Drivers may modify this initial i/o setup, but will
155      * normally rely on the device being setup.  Devices
156      * using SPI_CS_HIGH can't coexist well otherwise...
157 */
158      
159     //设置spi模式和时钟速率
160 //会调用spi->master->setup函数设置
161     status = spi_setup(spi);
162     if (status < 0) {
163         dev_err(dev, "can't %s %s, status %d/n",
164                 "setup", dev_name(&spi->dev), status);
165         goto done;
166     }
167     /* Device may be bound to an active driver when this returns */
168     
169     //将该实例化的设备添加到总线
170     status = device_add(&spi->dev);
171     if (status < 0)
172         dev_err(dev, "can't %s %s, status %d/n",
173                 "add", dev_name(&spi->dev), status);
174     else
175         dev_dbg(dev, "registered child %s/n", dev_name(&spi->dev));
176 done:
177     mutex_unlock(&spi_add_lock);
178     return status;
179 }
180 //最后看下spi_setup函数
181 int spi_setup(struct spi_device *spi)
182 {
183     unsigned    bad_bits;
184     int        status;
185     /* help drivers fail *cleanly* when they need options
186      * that aren't supported with their current master
187 */
188     
189     //必须和当前的master设置的模式匹配
190     bad_bits = spi->mode & ~spi->master->mode_bits;
191     if (bad_bits) {
192         dev_dbg(&spi->dev, "setup: unsupported mode bits %x/n",
193             bad_bits);
194         return -EINVAL;
195     }
196     if (!spi->bits_per_word)
197         spi->bits_per_word = 8;
198         
199         //最后调用控制器平台相关的setup成员设置该spi设备
200     status = spi->master->setup(spi);
201     dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s"
202                 "%u bits/w, %u Hz max --> %d/n",
203             (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
204             (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
205             (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
206             (spi->mode & SPI_3WIRE) ? "3wire, " : "",
207             (spi->mode & SPI_LOOP) ? "loopback, " : "",
208             spi->bits_per_word, spi->max_speed_hz,
209             status);
210     return status;
211 }
212 //回头看下一开始下面的那个分支of_register_spi_devices
213 void of_register_spi_devices(struct spi_master *master)
214 {
215     struct spi_device *spi;
216     struct device_node *nc;
217     const __be32 *prop;
218     int rc;
219     int len;
220   //如果定义了of_node成员才会走该分支
221     if (!master->dev.of_node)
222         return;
223         
224   //从控制器master->dev.of_node中去获取注册SPI设备spi_device的信息,然
225 //后分配结构体spi_device并注册
226     for_each_child_of_node(master->dev.of_node, nc) {
227         /* Alloc an spi_device */
228         spi = spi_alloc_device(master);
229         if (!spi) {
230             dev_err(&master->dev, "spi_device alloc error for %s/n",
231                 nc->full_name);
232             spi_dev_put(spi);
233             continue;
234         }
235         /* Select device driver */
236         if (of_modalias_node(nc, spi->modalias,
237                      sizeof(spi->modalias)) < 0) {
238             dev_err(&master->dev, "cannot find modalias for %s/n",
239                 nc->full_name);
240             spi_dev_put(spi);
241             continue;
242         }
243         /* Device address */
244         prop = of_get_property(nc, "reg", &len);
245         if (!prop || len < sizeof(*prop)) {
246             dev_err(&master->dev, "%s has no 'reg' property/n",
247                 nc->full_name);
248             spi_dev_put(spi);
249             continue;
250         }
251         spi->chip_select = be32_to_cpup(prop);
252         /* Mode (clock phase/polarity/etc.) */
253         if (of_find_property(nc, "spi-cpha", NULL))
254             spi->mode |= SPI_CPHA;
255         if (of_find_property(nc, "spi-cpol", NULL))
256             spi->mode |= SPI_CPOL;
257         if (of_find_property(nc, "spi-cs-high", NULL))
258             spi->mode |= SPI_CS_HIGH;
259         /* Device speed */
260         prop = of_get_property(nc, "spi-max-frequency", &len);
261         if (!prop || len < sizeof(*prop)) {
262             dev_err(&master->dev, "%s has no 'spi-max-frequency' property/n",
263                 nc->full_name);
264             spi_dev_put(spi);
265             continue;
266         }
267         spi->max_speed_hz = be32_to_cpup(prop);
268         /* IRQ */
269         spi->irq = irq_of_parse_and_map(nc, 0);
270         /* Store a pointer to the node in the device structure */
271         of_node_get(nc);
272         spi->dev.of_node = nc;
273         /* Register the new device */
274         request_module(spi->modalias);
275         rc = spi_add_device(spi);
276         if (rc) {
277             dev_err(&master->dev, "spi_device register error %s/n",
278                 nc->full_name);
279             spi_dev_put(spi);
280         }
281     }
282 }
复制代码

 

 

三、spi设备文件的自动产生代码分析

      这部分代码相当于注册了一个spi实际driver,既是核心平台无关代码,又是个具体实例,我们来看下一下具体做了什么,也好学习一spi_driver的各部分具体都需要做些什么,代码位于driver/spi/spidev.c下:

复制代码
  1 static int __init spidev_init(void)
  2 {
  3     int status;
  4     /* Claim our 256 reserved device numbers.  Then register a class
  5      * that will key udev/mdev to add/remove /dev nodes.  Last, register
  6      * the driver which manages those device numbers.
  7 */
  8     BUILD_BUG_ON(N_SPI_MINORS > 256);
  9     
 10     //注册主设备号为153的spi字符设备,spidev_fops结构下面会介绍
 11 //暂且不表
 12     status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
 13     if (status < 0)
 14         return status;
 15   //在sys/class下产生spidev这个节点,udev会利用其在dev下产生spidev
 16 //这个设备节点
 17     spidev_class = class_create(THIS_MODULE, "spidev");
 18     if (IS_ERR(spidev_class)) {
 19         unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
 20         return PTR_ERR(spidev_class);
 21     }
 22         //注册spi驱动,该函数上面已经分析过    
 23     status = spi_register_driver(&spidev_spi_driver);
 24     if (status < 0) {
 25         class_destroy(spidev_class);
 26         unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
 27     }
 28     return status;
 29 }
 30 //先看一下spidev_spi_driver具体的结构
 31 static struct spi_driver spidev_spi_driver = {
 32     .driver = {
 33         .name =        "spidev",
 34         .owner =    THIS_MODULE,
 35     },
 36     .probe =    spidev_probe,
 37     .remove =    __devexit_p(spidev_remove),
 38     /* NOTE:  suspend/resume methods are not necessary here.
 39      * We don't do anything except pass the requests to/from
 40      * the underlying controller.  The refrigerator handles
 41      * most issues; the controller driver handles the rest.
 42 */
 43 };
 44 //利用bus的match函数匹配成功后将首先调用spidev_probe函数,我们具体看下该函数:
 45 static int __devinit spidev_probe(struct spi_device *spi)
 46 {
 47     struct spidev_data    *spidev;
 48     int            status;
 49     unsigned long        minor;
 50     /* Allocate driver data */
 51     
 52     //申请spidev_data所需内存,前面已经讲过该结构
 53     spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
 54     if (!spidev)
 55         return -ENOMEM;
 56     /* Initialize the driver data */
 57         //赋值
 58     spidev->spi = spi;
 59     spin_lock_init(&spidev->spi_lock);
 60     mutex_init(&spidev->buf_lock);
 61     INIT_LIST_HEAD(&spidev->device_entry);
 62     /* If we can allocate a minor number, hook up this device.
 63      * Reusing minors is fine so long as udev or mdev is working.
 64 */
 65     mutex_lock(&device_list_lock);
 66     
 67     //找到一个最小的次设备号
 68 //addr为内存区的起始地址,size为要查找的最大长度
 69 //返回第一个位为0的位号
 70     minor = find_first_zero_bit(minors, N_SPI_MINORS);
 71     if (minor < N_SPI_MINORS) {
 72         struct device *dev;
 73     
 74        //下面两句用于在sys/class/spidev下产生类似于
 75 //spidev%d.%d形式的节点,这样,udev等工具就可以
 76 //自动在dev下创建相应设备号的设备节点
 77         spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
 78         dev = device_create(spidev_class, &spi->dev, spidev->devt,
 79                     spidev, "spidev%d.%d",
 80                     spi->master->bus_num, spi->chip_select);
 81         status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
 82     } else {
 83         dev_dbg(&spi->dev, "no minor number available!/n");
 84         status = -ENODEV;
 85     }
 86     
 87     //如果成功标明刚才的次设备号已被占用
 88 //并且将该设备挂接到device_list链表
 89     if (status == 0) {
 90         set_bit(minor, minors);
 91         list_add(&spidev->device_entry, &device_list);
 92     }
 93     mutex_unlock(&device_list_lock);
 94        //设置spi->dev->p = spidev
 95     if (status == 0)
 96         spi_set_drvdata(spi, spidev);
 97     else
 98         kfree(spidev);
 99     return status;
100 }
复制代码

 

      当我们利用板级信息添加一个设备的时候,该driver如果匹配到这个设备,那么就会自动为其创建设备节点,封装spidev_data

信息,并且挂到全局设备链表device_list。

      最后看一下刚才注册的字符设备的统一操作集:

     

复制代码
  1 static const struct file_operations spidev_fops = {
  2     .owner =    THIS_MODULE,
  3     /* REVISIT switch to aio primitives, so that userspace
  4      * gets more complete API coverage.  It'll simplify things
  5      * too, except for the locking.
  6 */
  7     .write =    spidev_write,
  8     .read =        spidev_read,
  9     .unlocked_ioctl = spidev_ioctl,
 10     .open =        spidev_open,
 11     .release =    spidev_release,
 12 };
 13 //按应用的操作顺序先看下open函数
 14 static int spidev_open(struct inode *inode, struct file *filp)
 15 {
 16     struct spidev_data    *spidev;
 17     int            status = -ENXIO;
 18     mutex_lock(&device_list_lock);
 19   
 20   //遍历spi设备链表device_list,根据设备号找到spidev_data结构
 21     list_for_each_entry(spidev, &device_list, device_entry) {
 22         if (spidev->devt == inode->i_rdev) {
 23             status = 0;
 24             break;
 25         }
 26     }
 27     if (status == 0) {
 28         //buffer为空,为其申请内存
 29         if (!spidev->buffer) {
 30             spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
 31             if (!spidev->buffer) {
 32                 dev_dbg(&spidev->spi->dev, "open/ENOMEM/n");
 33                 status = -ENOMEM;
 34             }
 35         }
 36         
 37         //设备用户使用量+1
 38         if (status == 0) {
 39             spidev->users++;
 40             
 41             //传到filp的私有成员,在read,write的时候可以从其得到该结构
 42             filp->private_data = spidev;
 43             nonseekable_open(inode, filp);
 44         }
 45     } else
 46         pr_debug("spidev: nothing for minor %d/n", iminor(inode));
 47     mutex_unlock(&device_list_lock);
 48     return status;
 49 }
 50 //再看read函数
 51 static ssize_t
 52 spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
 53 {
 54     struct spidev_data    *spidev;
 55     ssize_t            status = 0;
 56     /* chipselect only toggles at start or end of operation */
 57     if (count > bufsiz)
 58         return -EMSGSIZE;
 59   
 60   //得到传递的结构
 61     spidev = filp->private_data;
 62     mutex_lock(&spidev->buf_lock);
 63     
 64     //调用具体的读函数
 65     status = spidev_sync_read(spidev, count);
 66     if (status > 0) {
 67         unsigned long    missing;
 68     //将得到的信息传递给用户
 69         missing = copy_to_user(buf, spidev->buffer, status);
 70         if (missing == status)
 71             status = -EFAULT;
 72         else
 73             status = status - missing;
 74     }
 75     mutex_unlock(&spidev->buf_lock);
 76     return status;
 77 }
 78 //跟进spidev_sync_read函数,下面的操作比较直白,简要分析下
 79 //只关注主流程
 80 static inline ssize_t
 81 spidev_sync_read(struct spidev_data *spidev, size_t len)
 82 {
 83     //临时传输操作结构
 84     struct spi_transfer    t = {
 85             .rx_buf        = spidev->buffer,
 86             .len        = len,
 87         };
 88         
 89     //传输所用的信息结构
 90     struct spi_message    m;
 91   //初始化该结构
 92     spi_message_init(&m);
 93     //加到请求队列尾
 94     spi_message_add_tail(&t, &m);
 95     //调用spidev_sync继续
 96     return spidev_sync(spidev, &m);
 97 }
 98 //继续spidev_sync函数
 99 static ssize_t
100 spidev_sync(struct spidev_data *spidev, struct spi_message *message)
101 {
102     DECLARE_COMPLETION_ONSTACK(done);
103     int status;
104     message->complete = spidev_complete;
105     //设置个完成量
106     message->context = &done;
107     spin_lock_irq(&spidev->spi_lock);
108     if (spidev->spi == NULL)
109         status = -ESHUTDOWN;
110     else
111         //继续调用spi_async函数
112         status = spi_async(spidev->spi, message);
113     spin_unlock_irq(&spidev->spi_lock);
114     if (status == 0) {
115         //等待完成
116         wait_for_completion(&done);
117         status = message->status;
118         if (status == 0)
119             status = message->actual_length;
120     }
121     return status;
122 }
123 //spi_async函数
124 int spi_async(struct spi_device *spi, struct spi_message *message)
125 {
126     struct spi_master *master = spi->master;
127     int ret;
128     unsigned long flags;
129     spin_lock_irqsave(&master->bus_lock_spinlock, flags);
130     if (master->bus_lock_flag)
131         ret = -EBUSY;
132     else
133         //好长...继续跟进
134         ret = __spi_async(spi, message);
135     spin_unlock_irqrestore(&master->bus_lock_spinlock, flags);
136     return ret;
137 }
138 //__spi_async函数
139 static int __spi_async(struct spi_device *spi, struct spi_message *message)
140 {
141     struct spi_master *master = spi->master;
142     /* Half-duplex links include original MicroWire, and ones with
143      * only one data pin like SPI_3WIRE (switches direction) or where
144      * either MOSI or MISO is missing.  They can also be caused by
145      * software limitations.
146 */
147     if ((master->flags & SPI_MASTER_HALF_DUPLEX)
148             || (spi->mode & SPI_3WIRE)) {
149         struct spi_transfer *xfer;
150         unsigned flags = master->flags;
151         list_for_each_entry(xfer, &message->transfers, transfer_list) {
152             if (xfer->rx_buf && xfer->tx_buf)
153                 return -EINVAL;
154             if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)
155                 return -EINVAL;
156             if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)
157                 return -EINVAL;
158         }
159     }
160     message->spi = spi;
161     message->status = -EINPROGRESS;
162     
163     //最后调用master->transfer具体的平台相关的结构
164     return master->transfer(spi, message);
165 }
复制代码

 

      read函数就分析到此,至于write函数就不具体分析了,流程是相似的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值