📄 spi.c
字号:
/*-------------------------------------------------------------------------*/static void spi_master_release(struct class_device *cdev){ struct spi_master *master; master = container_of(cdev, struct spi_master, cdev); kfree(master);}static struct class spi_master_class = { .name = "spi_master", .release = spi_master_release,};/** * spi_alloc_master - allocate SPI master controller * @dev: the controller, possibly using the platform_bus * @size: how much driver-private data to preallocate; the pointer to this * memory is in the class_data field of the returned class_device, * accessible with spi_master_get_devdata(). * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. It's how they allocate * an spi_master structure, prior to calling spi_add_master(). * * This must be called from context that can sleep. It returns the SPI * master structure on success, else NULL. * * The caller is responsible for assigning the bus number and initializing * the master's methods before calling spi_add_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. */struct spi_master * __init_or_modulespi_alloc_master(struct device *dev, unsigned size){ struct spi_master *master; if (!dev) return NULL; master = kzalloc(size + sizeof *master, SLAB_KERNEL); if (!master) return NULL; class_device_initialize(&master->cdev); master->cdev.class = &spi_master_class; master->cdev.dev = get_device(dev); spi_master_set_devdata(master, &master[1]); return master;}EXPORT_SYMBOL_GPL(spi_alloc_master);/** * spi_register_master - register SPI master controller * @master: initialized master, originally from spi_alloc_master() * * SPI master controllers connect to their drivers using some non-SPI bus, * such as the platform bus. The final stage of probe() in that code * includes calling spi_register_master() to hook up to this SPI bus glue. * * SPI controllers use board specific (often SOC specific) bus numbers, * and board-specific addressing for SPI devices combines those numbers * with chip select numbers. Since SPI does not directly support dynamic * device identification, boards need configuration tables telling which * chip is at which address. * * This must be called from context that can sleep. It returns zero on * success, else a negative error code (dropping the master's refcount). * After a successful return, the caller is responsible for calling * spi_unregister_master(). */int __init_or_modulespi_register_master(struct spi_master *master){ static atomic_t dyn_bus_id = ATOMIC_INIT(0); struct device *dev = master->cdev.dev; int status = -ENODEV; int dynamic = 0; if (!dev) return -ENODEV; /* convention: dynamically assigned bus IDs count down from the max */ if (master->bus_num == 0) { master->bus_num = atomic_dec_return(&dyn_bus_id); dynamic = 1; } /* register the device, then userspace will see it. * registration fails if the bus ID is in use. */ snprintf(master->cdev.class_id, sizeof master->cdev.class_id, "spi%u", master->bus_num); status = class_device_add(&master->cdev); if (status < 0) goto done; dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, dynamic ? " (dynamic)" : ""); /* populate children from any spi device tables */ scan_boardinfo(master); status = 0;done: return status;}EXPORT_SYMBOL_GPL(spi_register_master);static int __unregister(struct device *dev, void *unused){ /* note: before about 2.6.14-rc1 this would corrupt memory: */ spi_unregister_device(to_spi_device(dev)); return 0;}/** * spi_unregister_master - unregister SPI master controller * @master: the master being unregistered * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. * * This must be called from context that can sleep. */void spi_unregister_master(struct spi_master *master){ (void) device_for_each_child(master->cdev.dev, NULL, __unregister); class_device_unregister(&master->cdev); master->cdev.dev = NULL;}EXPORT_SYMBOL_GPL(spi_unregister_master);/** * spi_busnum_to_master - look up master associated with bus_num * @bus_num: the master's bus number * * This call may be used with devices that are registered after * arch init time. It returns a refcounted pointer to the relevant * spi_master (which the caller must release), or NULL if there is * no such master registered. */struct spi_master *spi_busnum_to_master(u16 bus_num){ if (bus_num) { char name[8]; struct kobject *bus; snprintf(name, sizeof name, "spi%u", bus_num); bus = kset_find_obj(&spi_master_class.subsys.kset, name); if (bus) return container_of(bus, struct spi_master, cdev.kobj); } return NULL;}EXPORT_SYMBOL_GPL(spi_busnum_to_master);/*-------------------------------------------------------------------------*/static void spi_complete(void *arg){ complete(arg);}/** * spi_sync - blocking/synchronous SPI data transfers * @spi: device with which data will be exchanged * @message: describes the data transfers * * This call may only be used from a context that may sleep. The sleep * is non-interruptible, and has no timeout. Low-overhead controller * drivers may DMA directly into and out of the message buffers. * * Note that the SPI device's chip select is active during the message, * and then is normally disabled between messages. Drivers for some * frequently-used devices may want to minimize costs of selecting a chip, * by leaving it selected in anticipation that the next message will go * to the same chip. (That may increase power usage.) * * Also, the caller is guaranteeing that the memory associated with the * message will not be freed before this call returns. * * The return value is a negative error code if the message could not be * submitted, else zero. When the value is zero, then message->status is * also defined: it's the completion code for the transfer, either zero * or a negative error code from the controller driver. */int spi_sync(struct spi_device *spi, struct spi_message *message){ DECLARE_COMPLETION(done); int status; message->complete = spi_complete; message->context = &done; status = spi_async(spi, message); if (status == 0) wait_for_completion(&done); message->context = NULL; return status;}EXPORT_SYMBOL_GPL(spi_sync);#define SPI_BUFSIZ (SMP_CACHE_BYTES)static u8 *buf;/** * spi_write_then_read - SPI synchronous write followed by read * @spi: device with which data will be exchanged * @txbuf: data to be written (need not be dma-safe) * @n_tx: size of txbuf, in bytes * @rxbuf: buffer into which data will be read * @n_rx: size of rxbuf, in bytes (need not be dma-safe) * * This performs a half duplex MicroWire style transaction with the * device, sending txbuf and then reading rxbuf. The return value * is zero for success, else a negative errno status code. * This call may only be used from a context that may sleep. * * Parameters to this routine are always copied using a small buffer; * performance-sensitive or bulk transfer code should instead use * spi_{async,sync}() calls with dma-safe buffers. */int spi_write_then_read(struct spi_device *spi, const u8 *txbuf, unsigned n_tx, u8 *rxbuf, unsigned n_rx){ static DECLARE_MUTEX(lock); int status; struct spi_message message; struct spi_transfer x[2]; u8 *local_buf; /* Use preallocated DMA-safe buffer. We can't avoid copying here, * (as a pure convenience thing), but we can keep heap costs * out of the hot path ... */ if ((n_tx + n_rx) > SPI_BUFSIZ) return -EINVAL; spi_message_init(&message); memset(x, 0, sizeof x); if (n_tx) { x[0].len = n_tx; spi_message_add_tail(&x[0], &message); } if (n_rx) { x[1].len = n_rx; spi_message_add_tail(&x[1], &message); } /* ... unless someone else is using the pre-allocated buffer */ if (down_trylock(&lock)) { local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); if (!local_buf) return -ENOMEM; } else local_buf = buf; memcpy(local_buf, txbuf, n_tx); x[0].tx_buf = local_buf; x[1].rx_buf = local_buf + n_tx; /* do the i/o */ status = spi_sync(spi, &message); if (status == 0) { memcpy(rxbuf, x[1].rx_buf, n_rx); status = message.status; } if (x[0].tx_buf == buf) up(&lock); else kfree(local_buf); return status;}EXPORT_SYMBOL_GPL(spi_write_then_read);/*-------------------------------------------------------------------------*/static int __init spi_init(void){ int status; buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL); if (!buf) { status = -ENOMEM; goto err0; } status = bus_register(&spi_bus_type); if (status < 0) goto err1; status = class_register(&spi_master_class); if (status < 0) goto err2; return 0;err2: bus_unregister(&spi_bus_type);err1: kfree(buf); buf = NULL;err0: return status;}/* board_info is normally registered in arch_initcall(), * but even essential drivers wait till later * * REVISIT only boardinfo really needs static linking. the rest (device and * driver registration) _could_ be dynamically linked (modular) ... costs * include needing to have boardinfo data structures be much more public. */subsys_initcall(spi_init);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -