diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4416783..215cc4e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -28,6 +28,7 @@ #include #include #include +#include /* SPI devices should normally not be created by SPI device drivers; that * would make them board-specific. Similarly with SPI master drivers. @@ -83,6 +84,7 @@ /* 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 */ @@ -102,6 +104,27 @@ } 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 @@ -145,7 +168,7 @@ unsigned n; for (n = bi->n_board_info; n > 0; n--, chip++) { - debug("%s %d %d\n", __FUNCTION__, chip->bus_num, master->bus_num); + printf("%s %d %d\n", __FUNCTION__, chip->bus_num, master->bus_num); if (chip->bus_num != master->bus_num) continue; /* NOTE: this relies on spi_new_device to @@ -156,6 +179,8 @@ } } +static LIST_HEAD(spi_master_list); + /** * spi_register_master - register SPI master controller * @master: initialized master, originally from spi_alloc_master() @@ -188,6 +213,8 @@ 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; @@ -245,6 +272,10 @@ 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; } diff --git a/include/spi/spi.h b/include/spi/spi.h index 569cdcd..1773ca2 100644 --- a/include/spi/spi.h +++ b/include/spi/spi.h @@ -17,6 +17,7 @@ u8 mode; u8 bits_per_word; void *platform_data; + struct device_node *device_node; }; /** @@ -163,6 +164,8 @@ /* called on release() to free memory provided by spi_master */ void (*cleanup)(struct spi_device *spi); + + struct list_head list; }; /*---------------------------------------------------------------------------*/ @@ -434,4 +437,7 @@ drv->bus = &spi_bus; return register_driver(drv); } + +void spi_of_register_slaves(struct spi_master *master, struct device_node *node); + #endif /* __INCLUDE_SPI_H */