diff options
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a7fe10cba0..44040e5f62 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -15,10 +15,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA * */ @@ -27,6 +23,8 @@ #include <xfuncs.h> #include <malloc.h> #include <errno.h> +#include <init.h> +#include <of.h> /* SPI devices should normally not be created by SPI device drivers; that * would make them board-specific. Similarly with SPI master drivers. @@ -77,10 +75,12 @@ struct spi_device *spi_new_device(struct spi_master *master, proxy->mode = chip->mode; proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8; proxy->dev.platform_data = chip->platform_data; + proxy->dev.bus = &spi_bus; strcpy(proxy->dev.name, chip->name); /* allocate a free id for this chip */ proxy->dev.id = DEVICE_ID_DYNAMIC; proxy->dev.type_data = proxy; + proxy->dev.device_node = chip->device_node; dev_add_child(master->dev, &proxy->dev); /* drivers may modify this initial i/o setup */ @@ -100,6 +100,27 @@ fail: } EXPORT_SYMBOL(spi_new_device); +#ifdef CONFIG_OFDEVICE +void spi_of_register_slaves(struct spi_master *master, struct device_node *node) +{ + struct device_node *n; + struct spi_board_info chip; + struct property *reg; + + device_node_for_nach_child(node, n) { + chip.name = n->name; + chip.bus_num = master->bus_num; + chip.max_speed_hz = 300000; /* FIXME */ + reg = of_find_property(n, "reg"); + if (!reg) + continue; + chip.chip_select = of_read_number(reg->value, 1); + chip.device_node = n; + spi_register_board_info(&chip, 1); + } +} +#endif + /** * spi_register_board_info - register SPI devices for a given board * @info: array of chip descriptors @@ -154,6 +175,8 @@ static void scan_boardinfo(struct spi_master *master) } } +static LIST_HEAD(spi_master_list); + /** * spi_register_master - register SPI master controller * @master: initialized master, originally from spi_alloc_master() @@ -186,6 +209,8 @@ int spi_register_master(struct spi_master *master) if (master->num_chipselect == 0) return -EINVAL; + list_add_tail(&master->list, &spi_master_list); + /* populate children from any spi device tables */ scan_boardinfo(master); status = 0; @@ -240,3 +265,35 @@ int spi_write_then_read(struct spi_device *spi, return status; } EXPORT_SYMBOL(spi_write_then_read); + +static int spi_match(struct device_d *dev, struct driver_d *drv) +{ + if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node && + drv->of_compatible) + return of_match(dev, drv); + + return strcmp(dev->name, drv->name) ? -1 : 0; +} + +static int spi_probe(struct device_d *dev) +{ + return dev->driver->probe(dev); +} + +static void spi_remove(struct device_d *dev) +{ + dev->driver->remove(dev); +} + +struct bus_type spi_bus = { + .name = "spi", + .match = spi_match, + .probe = spi_probe, + .remove = spi_remove, +}; + +static int spi_bus_init(void) +{ + return bus_register(&spi_bus); +} +pure_initcall(spi_bus_init); |