spi.c
来自「linux 内核源代码」· C语言 代码 · 共 681 行 · 第 1/2 页
C
681 行
{ struct spi_master *master; master = container_of(dev, struct spi_master, dev); kfree(master);}static struct class spi_master_class = { .name = "spi_master", .owner = THIS_MODULE, .dev_release = spi_master_release,};/** * spi_alloc_master - allocate SPI master controller * @dev: the controller, possibly using the platform_bus * @size: how much zeroed driver-private data to allocate; the pointer to this * memory is in the driver_data field of the returned device, * accessible with spi_master_get_devdata(). * Context: can sleep * * 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_register_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_register_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. */struct spi_master *spi_alloc_master(struct device *dev, unsigned size){ struct spi_master *master; if (!dev) return NULL; master = kzalloc(size + sizeof *master, GFP_KERNEL); if (!master) return NULL; device_initialize(&master->dev); master->dev.class = &spi_master_class; master->dev.parent = 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() * Context: can sleep * * 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 spi_register_master(struct spi_master *master){ static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); struct device *dev = master->dev.parent; int status = -ENODEV; int dynamic = 0; if (!dev) return -ENODEV; /* even if it's just one always-selected device, there must * be at least one chipselect */ if (master->num_chipselect == 0) return -EINVAL; /* convention: dynamically assigned bus IDs count down from the max */ if (master->bus_num < 0) { /* FIXME switch to an IDR based scheme, something like * I2C now uses, so we can't run out of "dynamic" IDs */ 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->dev.bus_id, sizeof master->dev.bus_id, "spi%u", master->bus_num); status = device_add(&master->dev); if (status < 0) goto done; dev_dbg(dev, "registered master %s%s\n", master->dev.bus_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 *master_dev){ /* note: before about 2.6.14-rc1 this would corrupt memory: */ if (dev != master_dev) spi_unregister_device(to_spi_device(dev)); return 0;}/** * spi_unregister_master - unregister SPI master controller * @master: the master being unregistered * Context: can sleep * * 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){ int dummy; dummy = device_for_each_child(master->dev.parent, &master->dev, __unregister); device_unregister(&master->dev);}EXPORT_SYMBOL_GPL(spi_unregister_master);/** * spi_busnum_to_master - look up master associated with bus_num * @bus_num: the master's bus number * Context: can sleep * * 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){ struct device *dev; struct spi_master *master = NULL; struct spi_master *m; down(&spi_master_class.sem); list_for_each_entry(dev, &spi_master_class.children, node) { m = container_of(dev, struct spi_master, dev); if (m->bus_num == bus_num) { master = spi_master_get(m); break; } } up(&spi_master_class.sem); return master;}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 * Context: can sleep * * 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. * * It returns zero on success, else a negative error code. */int spi_sync(struct spi_device *spi, struct spi_message *message){ DECLARE_COMPLETION_ONSTACK(done); int status; message->complete = spi_complete; message->context = &done; status = spi_async(spi, message); if (status == 0) { wait_for_completion(&done); status = message->status; } message->context = NULL; return status;}EXPORT_SYMBOL_GPL(spi_sync);/* portable code must never pass more than 32 bytes */#define SPI_BUFSIZ max(32,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) * Context: can sleep * * 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; * portable code should never use this for more than 32 bytes. * 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 DEFINE_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 (!mutex_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); if (x[0].tx_buf == buf) mutex_unlock(&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, GFP_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 + =
减小字号Ctrl + -
显示快捷键?