Commit a020ed75 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] SPI: busnum == 0 needs to work

We need to be able to have a "SPI bus 0" matching chip numbering; but
that number was wrongly used to flag dynamic allocation of a bus number.

This patch resolves that issue; now negative numbers trigger dynamic alloc.

It also updates the how-to-write-a-controller-driver overview to mention
this stuff.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent ccf77cc4
...@@ -414,7 +414,33 @@ to get the driver-private data allocated for that device. ...@@ -414,7 +414,33 @@ to get the driver-private data allocated for that device.
The driver will initialize the fields of that spi_master, including the The driver will initialize the fields of that spi_master, including the
bus number (maybe the same as the platform device ID) and three methods bus number (maybe the same as the platform device ID) and three methods
used to interact with the SPI core and SPI protocol drivers. It will used to interact with the SPI core and SPI protocol drivers. It will
also initialize its own internal state. also initialize its own internal state. (See below about bus numbering
and those methods.)
After you initialize the spi_master, then use spi_register_master() to
publish it to the rest of the system. At that time, device nodes for
the controller and any predeclared spi devices will be made available,
and the driver model core will take care of binding them to drivers.
If you need to remove your SPI controller driver, spi_unregister_master()
will reverse the effect of spi_register_master().
BUS NUMBERING
Bus numbering is important, since that's how Linux identifies a given
SPI bus (shared SCK, MOSI, MISO). Valid bus numbers start at zero. On
SOC systems, the bus numbers should match the numbers defined by the chip
manufacturer. For example, hardware controller SPI2 would be bus number 2,
and spi_board_info for devices connected to it would use that number.
If you don't have such hardware-assigned bus number, and for some reason
you can't just assign them, then provide a negative bus number. That will
then be replaced by a dynamically assigned number. You'd then need to treat
this as a non-static configuration (see above).
SPI MASTER METHODS
master->setup(struct spi_device *spi) master->setup(struct spi_device *spi)
This sets up the device clock rate, SPI mode, and word sizes. This sets up the device clock rate, SPI mode, and word sizes.
...@@ -431,6 +457,9 @@ also initialize its own internal state. ...@@ -431,6 +457,9 @@ also initialize its own internal state.
state it dynamically associates with that device. If you do that, state it dynamically associates with that device. If you do that,
be sure to provide the cleanup() method to free that state. be sure to provide the cleanup() method to free that state.
SPI MESSAGE QUEUE
The bulk of the driver will be managing the I/O queue fed by transfer(). The bulk of the driver will be managing the I/O queue fed by transfer().
That queue could be purely conceptual. For example, a driver used only That queue could be purely conceptual. For example, a driver used only
...@@ -440,6 +469,9 @@ But the queue will probably be very real, using message->queue, PIO, ...@@ -440,6 +469,9 @@ But the queue will probably be very real, using message->queue, PIO,
often DMA (especially if the root filesystem is in SPI flash), and often DMA (especially if the root filesystem is in SPI flash), and
execution contexts like IRQ handlers, tasklets, or workqueues (such execution contexts like IRQ handlers, tasklets, or workqueues (such
as keventd). Your driver can be as fancy, or as simple, as you need. as keventd). Your driver can be as fancy, or as simple, as you need.
Such a transfer() method would normally just add the message to a
queue, and then start some asynchronous transfer engine (unless it's
already running).
THANKS TO THANKS TO
......
...@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); ...@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
int __init_or_module int __init_or_module
spi_register_master(struct spi_master *master) spi_register_master(struct spi_master *master)
{ {
static atomic_t dyn_bus_id = ATOMIC_INIT(0); static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
struct device *dev = master->cdev.dev; struct device *dev = master->cdev.dev;
int status = -ENODEV; int status = -ENODEV;
int dynamic = 0; int dynamic = 0;
...@@ -404,7 +404,7 @@ spi_register_master(struct spi_master *master) ...@@ -404,7 +404,7 @@ spi_register_master(struct spi_master *master)
return -ENODEV; return -ENODEV;
/* convention: dynamically assigned bus IDs count down from the max */ /* convention: dynamically assigned bus IDs count down from the max */
if (master->bus_num == 0) { if (master->bus_num < 0) {
master->bus_num = atomic_dec_return(&dyn_bus_id); master->bus_num = atomic_dec_return(&dyn_bus_id);
dynamic = 1; dynamic = 1;
} }
......
...@@ -172,13 +172,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -172,13 +172,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
struct spi_master { struct spi_master {
struct class_device cdev; struct class_device cdev;
/* other than zero (== assign one dynamically), bus_num is fully /* other than negative (== assign one dynamically), bus_num is fully
* board-specific. usually that simplifies to being SOC-specific. * board-specific. usually that simplifies to being SOC-specific.
* example: one SOC has three SPI controllers, numbered 1..3, * example: one SOC has three SPI controllers, numbered 0..2,
* and one board's schematics might show it using SPI-2. software * and one board's schematics might show it using SPI-2. software
* would normally use bus_num=2 for that controller. * would normally use bus_num=2 for that controller.
*/ */
u16 bus_num; s16 bus_num;
/* chipselects will be integral to many controllers; some others /* chipselects will be integral to many controllers; some others
* might use board-specific GPIOs. * might use board-specific GPIOs.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment