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 + -
显示快捷键?