您的位置:首页 > 运维架构 > Linux

Linux下SPI驱动分析(3)

2011-03-05 15:01 369 查看
接下去看spi.c



特殊的板级相关设备添加方法    /* 神奇的分割线 */
190/*-------------------------------------------------------------------------*/
191
192/* SPI devices should normally not be created by SPI device drivers; that
193 * would make them board-specific.  Similarly with SPI master drivers.
194 * Device registration normally goes into like arch/.../mach.../board-YYY.c
195 * with other readonly (flashable) information about mainboard devices.
196 */
197
/* 板级相关信息链表 */
198struct boardinfo {
199        struct list_head        list;
200        struct spi_board_info   board_info;
201};
202
203static LIST_HEAD(board_list);
204static LIST_HEAD(spi_master_list);
206/*
207 * Used to protect add/del opertion for board_info list and
208 * spi_master list, and their matching process
209 */
/* 链表操作锁 */
210static DEFINE_MUTEX(board_lock);
211
212/**
213 * spi_alloc_device - Allocate a new SPI device
214 * @master: Controller to which device is connected
215 * Context: can sleep
216 *
217 * Allows a driver to allocate and initialize a spi_device without
218 * registering it immediately.  This allows a driver to directly
219 * fill the spi_device with device parameters before calling
220 * spi_add_device() on it.
221 *
222 * Caller is responsible to call spi_add_device() on the returned
223 * spi_device structure to add it to the SPI master.  If the caller
224 * needs to discard the spi_device without adding it, then it should
225 * call spi_dev_put() on it.
226 *
227 * Returns a pointer to the new device, or NULL.
228 */
/* 为申请SPI设备结构体空间而不注册设备,必须调用spi_add_device,如要丢弃这个设备
* 则必须调用spi_dev_put
*/
229struct spi_device *spi_alloc_device(struct spi_master *master)
230{
231        struct spi_device       *spi;
232        struct device           *dev = master->dev.parent;
233
/* 增加设备引用次数,相反操作spi_master_put */
234        if (!spi_master_get(master))
235                return NULL;
236
/* 申请内核空间内存 */
237        spi = kzalloc(sizeof *spi, GFP_KERNEL);
238        if (!spi) {
239                dev_err(dev, "cannot alloc spi_device/n");
240                spi_master_put(master);
241                return NULL;
242        }
243
/* SPI主机控制结构体 */
244        spi->master = master;
/* 设备 */
245        spi->dev.parent = dev;
/* 总线 */
246        spi->dev.bus = &spi_bus_type;
/* 删除方法 */
247        spi->dev.release = spidev_release;
/* 设备初始化
* 初始化kobject,dma池链表,设备互斥锁,自旋锁,设备对象的电源相关部分
* src/drivers/base/core.c
*/
248        device_initialize(&spi->dev);
/* 返回spi设备结构体指针 */
249        return spi;
250}
251EXPORT_SYMBOL_GPL(spi_alloc_device);
252
253/**
254 * spi_add_device - Add spi_device allocated with spi_alloc_device
255 * @spi: spi_device to register
256 *
257 * Companion function to spi_alloc_device.  Devices allocated with
258 * spi_alloc_device can be added onto the spi bus with this function.
259 *
260 * Returns 0 on success; negative errno on failure
261 */
/* 与spi_alloc_device配合使用,将设备结构体添加到SPI总线 */
262int spi_add_device(struct spi_device *spi)
263{
264        static DEFINE_MUTEX(spi_add_lock);
265        struct device *dev = spi->master->dev.parent;
266        struct device *d;
267        int status;
268
269        /* Chipselects are numbered 0..max; validate. */
/* 设备片选编号比SPI主控制器的片选大,出错 */
270        if (spi->chip_select >= spi->master->num_chipselect) {
271                dev_err(dev, "cs%d >= max %d/n",
272                        spi->chip_select,
273                        spi->master->num_chipselect);
274                return -EINVAL;
275        }
276
277        /* Set the bus ID string */
/* 设置设备名称,调用kobject的设置设备名称参数方法 */
278        dev_set_name(&spi->dev, "%s.%u", dev_name(&spi->master->dev),
279                        spi->chip_select);
280
281
282        /* We need to make sure there's no other device with this
283         * chipselect **BEFORE** we call setup(), else we'll trash
284         * its configuration.  Lock against concurrent add() calls.
285         */
/* 互斥锁,保证设置时,没有其他设备用这个片选,防止并发添加add() */
286        mutex_lock(&spi_add_lock);
287
/* 按照名称字符查找设备结构体,设备名称由dev_name查找kobject返回
* 能够找到说明设备已经在用
*/
288        d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
289        if (d != NULL) {
290                dev_err(dev, "chipselect %d already in use/n",
291                                spi->chip_select);
292                put_device(d);
293                status = -EBUSY;
294                goto done;
295        }
296
297        /* Drivers may modify this initial i/o setup, but will
298         * normally rely on the device being setup.  Devices
299         * using SPI_CS_HIGH can't coexist well otherwise...
300         */
/*
/* 设置SPI模式和时钟频率
* 驱动可以初始化IO,当设备被设置的时候
* 取消片选没有用
* 详细见后面驱动核心方法spi_setup解析
*/
301        status = spi_setup(spi);
302        if (status < 0) {
303                dev_err(dev, "can't setup %s, status %d/n",
304                                dev_name(&spi->dev), status);
305                goto done;
306        }
307
308        /* Device may be bound to an active driver when this returns */
/* 将设备添加到驱动层次结构,添加到kobject层次结构,添加到其他子系统 */
309        status = device_add(&spi->dev);
310        if (status < 0)
311                dev_err(dev, "can't add %s, status %d/n",
312                                dev_name(&spi->dev), status);
313        else
314                dev_dbg(dev, "registered child %s/n", dev_name(&spi->dev));
315
316done:
317        mutex_unlock(&spi_add_lock);
318        return status;
319}
320EXPORT_SYMBOL_GPL(spi_add_device);
321
322/**
323 * spi_new_device - instantiate one new SPI device
324 * @master: Controller to which device is connected
325 * @chip: Describes the SPI device
326 * Context: can sleep
327 *
328 * On typical mainboards, this is purely internal; and it's not needed
329 * after board init creates the hard-wired devices.  Some development
330 * platforms may not be able to use spi_register_board_info though, and
331 * this is exported so that for example a USB or parport based adapter
332 * driver could add devices (which it would learn about out-of-band).
333 *
334 * Returns the new device, or NULL.
335 */
/* 有些开发平台可能不能通过spi_register_board_info添加设备
* 这个用来让一些比如基于USB适配的驱动添加设备
*/
336struct spi_device *spi_new_device(struct spi_master *master,
337                                  struct spi_board_info *chip)
338{
339        struct spi_device       *proxy;
340        int                     status;
341
342        /* NOTE:  caller did any chip->bus_num checks necessary.
343         *
344         * Also, unless we change the return value convention to use
345         * error-or-pointer (not NULL-or-pointer), troubleshootability
346         * suggests syslogged diagnostics are best here (ugh).
347         */
348
/* 分配设备结构体内存空间,并初始化 */
349        proxy = spi_alloc_device(master);
350        if (!proxy)
351                return NULL;
352
353        WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
354
355        proxy->chip_select = chip->chip_select;
356        proxy->max_speed_hz = chip->max_speed_hz;
357        proxy->mode = chip->mode;
358        proxy->irq = chip->irq;
359        strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
360        proxy->dev.platform_data = (void *) chip->platform_data;
361        proxy->controller_data = chip->controller_data;
362        proxy->controller_state = NULL;
363
/* 添加设备 */
364        status = spi_add_device(proxy);
365        if (status < 0) {
366                spi_dev_put(proxy);
367                return NULL;
368        }
369
370        return proxy;
371}
372EXPORT_SYMBOL_GPL(spi_new_device);
373
/* 使用主控制类和板级信息匹配则添加一个新设备 */
374static void spi_match_master_to_boardinfo(struct spi_master *master,
375                                struct spi_board_info *bi)
376{
377        struct spi_device *dev;
378
379        if (master->bus_num != bi->bus_num)
380                return;
381
382        dev = spi_new_device(master, bi);
383        if (!dev)
384                dev_err(master->dev.parent, "can't create new device for %s/n",
385                        bi->modalias);
386}
387
388/**
389 * spi_register_board_info - register SPI devices for a given board
390 * @info: array of chip descriptors
391 * @n: how many descriptors are provided
392 * Context: can sleep
393 *
394 * Board-specific early init code calls this (probably during arch_initcall)
395 * with segments of the SPI device table.  Any device nodes are created later,
396 * after the relevant parent SPI controller (bus_num) is defined.  We keep
397 * this table of devices forever, so that reloading a controller driver will
398 * not make Linux forget about these hard-wired devices.
399 *
400 * Other code can also call this, e.g. a particular add-on board might provide
401 * SPI devices through its expansion connector, so code initializing that board
402 * would naturally declare its SPI devices.
403 *
404 * The board info passed can safely be __initdata ... but be careful of
405 * any embedded pointers (platform_data, etc), they're copied as-is.
406 */
/* 使用一系列板级描述信息初始化设备 */
407int __init
408spi_register_board_info(struct spi_board_info const *info, unsigned n)
409{
410        struct boardinfo *bi;
411        int i;
412
413        bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
414        if (!bi)
415                return -ENOMEM;
416
417        for (i = 0; i < n; i++, bi++, info++) {
418                struct spi_master *master;
419
420                memcpy(&bi->board_info, info, sizeof(*info));
421                mutex_lock(&board_lock);
/* 添加到板级描述符链表 */
422                list_add_tail(&bi->list, &board_list);
/* 将主机控制类链表所有的节点匹配板级信息的设备初始化 */
423                list_for_each_entry(master, &spi_master_list, list)
424                        spi_match_master_to_boardinfo(master, &bi->board_info);
425                mutex_unlock(&board_lock);
426        }
427
428        return 0;
429}
430
431/*-------------------------------------------------------------------------*/


------------------------------------------------

下回看SPI主机注册、删除方法,休息~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: