Loading drivers/spi/Kconfig +13 −1 Original line number Original line Diff line number Diff line Loading @@ -704,6 +704,18 @@ config SPI_TLE62X0 endif # SPI_MASTER endif # SPI_MASTER # (slave support would go here) # # SLAVE side ... listening to other SPI masters # config SPI_SLAVE bool "SPI slave protocol handlers" help If your system has a slave-capable SPI controller, you can enable slave protocol handlers. if SPI_SLAVE endif # SPI_SLAVE endif # SPI endif # SPI drivers/spi/Makefile +2 −0 Original line number Original line Diff line number Diff line Loading @@ -95,3 +95,5 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_QSD) += spi_qsd.o obj-$(CONFIG_SPI_QSD) += spi_qsd.o obj-$(CONFIG_SPI_QUP) += spi_qsd.o obj-$(CONFIG_SPI_QUP) += spi_qsd.o # SPI slave protocol handlers drivers/spi/spi.c +152 −24 Original line number Original line Diff line number Diff line Loading @@ -1427,15 +1427,6 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, u32 value; u32 value; int rc; int rc; /* Device address */ rc = of_property_read_u32(nc, "reg", &value); if (rc) { dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", nc->full_name, rc); return rc; } spi->chip_select = value; /* Mode (clock phase/polarity/etc.) */ /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) if (of_find_property(nc, "spi-cpha", NULL)) spi->mode |= SPI_CPHA; spi->mode |= SPI_CPHA; Loading Loading @@ -1485,6 +1476,24 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, } } } } if (spi_controller_is_slave(master)) { if (strcmp(nc->name, "slave")) { dev_err(&master->dev, "%s is not called 'slave'\n", nc->full_name); return -EINVAL; } return 0; } /* Device address */ rc = of_property_read_u32(nc, "reg", &value); if (rc) { dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", nc->full_name, rc); return rc; } spi->chip_select = value; /* Device speed */ /* Device speed */ rc = of_property_read_u32(nc, "spi-max-frequency", &value); rc = of_property_read_u32(nc, "spi-max-frequency", &value); if (rc) { if (rc) { Loading Loading @@ -1548,8 +1557,8 @@ err_out: * of_register_spi_devices() - Register child devices onto the SPI bus * of_register_spi_devices() - Register child devices onto the SPI bus * @master: Pointer to spi_master device * @master: Pointer to spi_master device * * * Registers an spi_device for each child node of master node which has a 'reg' * Registers an spi_device for each child node of controller node which * property. * represents a valid SPI slave. */ */ static void of_register_spi_devices(struct spi_master *master) static void of_register_spi_devices(struct spi_master *master) { { Loading Loading @@ -1681,28 +1690,129 @@ static struct class spi_master_class = { .dev_groups = spi_master_groups, .dev_groups = spi_master_groups, }; }; #ifdef CONFIG_SPI_SLAVE /** * spi_slave_abort - abort the ongoing transfer request on an SPI slave * controller * @spi: device used for the current transfer */ int spi_slave_abort(struct spi_device *spi) { struct spi_master *master = spi->master; if (spi_controller_is_slave(master) && master->slave_abort) return master->slave_abort(master); return -ENOTSUPP; } EXPORT_SYMBOL_GPL(spi_slave_abort); static int match_true(struct device *dev, void *data) { return 1; } static ssize_t spi_slave_show(struct device *dev, struct device_attribute *attr, char *buf) { struct spi_master *ctlr = container_of(dev, struct spi_master, dev); struct device *child; child = device_find_child(&ctlr->dev, NULL, match_true); return sprintf(buf, "%s\n", child ? to_spi_device(child)->modalias : NULL); } static ssize_t spi_slave_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct spi_master *ctlr = container_of(dev, struct spi_master, dev); struct spi_device *spi; struct device *child; char name[32]; int rc; rc = sscanf(buf, "%31s", name); if (rc != 1 || !name[0]) return -EINVAL; child = device_find_child(&ctlr->dev, NULL, match_true); if (child) { /* Remove registered slave */ device_unregister(child); put_device(child); } if (strcmp(name, "(null)")) { /* Register new slave */ spi = spi_alloc_device(ctlr); if (!spi) return -ENOMEM; strlcpy(spi->modalias, name, sizeof(spi->modalias)); rc = spi_add_device(spi); if (rc) { spi_dev_put(spi); return rc; } } return count; } static DEVICE_ATTR(slave, 0644, spi_slave_show, spi_slave_store); static struct attribute *spi_slave_attrs[] = { &dev_attr_slave.attr, NULL, }; static const struct attribute_group spi_slave_group = { .attrs = spi_slave_attrs, }; static const struct attribute_group *spi_slave_groups[] = { &spi_master_statistics_group, &spi_slave_group, NULL, }; static struct class spi_slave_class = { .name = "spi_slave", .owner = THIS_MODULE, .dev_release = spi_master_release, .dev_groups = spi_slave_groups, }; #else extern struct class spi_slave_class; /* dummy */ #endif /** /** * spi_alloc_master - allocate SPI master controller * __spi_alloc_controller - allocate an SPI master or slave controller * @dev: the controller, possibly using the platform_bus * @dev: the controller, possibly using the platform_bus * @size: how much zeroed driver-private data to allocate; the pointer to this * @size: how much zeroed driver-private data to allocate; the pointer to this * memory is in the driver_data field of the returned device, * memory is in the driver_data field of the returned device, * accessible with spi_master_get_devdata(). * accessible with spi_master_get_devdata(). * @slave: flag indicating whether to allocate an SPI master (false) or SPI * slave (true) controller * Context: can sleep * Context: can sleep * * * This call is used only by SPI master controller drivers, which are the * This call is used only by SPI controller drivers, which are the * only ones directly touching chip registers. It's how they allocate * only ones directly touching chip registers. It's how they allocate * an spi_master structure, prior to calling spi_register_master(). * an spi_master structure, prior to calling spi_register_master(). * * * This must be called from context that can sleep. * This must be called from context that can sleep. * * * The caller is responsible for assigning the bus number and initializing * The caller is responsible for assigning the bus number and initializing the * the master's methods before calling spi_register_master(); and (after errors * controller's methods before calling spi_register_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. * adding the device) calling spi_master_put() to prevent a memory leak. * * * Return: the SPI master structure on success, else NULL. * Return: the SPI controller structure on success, else NULL. */ */ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) struct spi_master *__spi_alloc_controller(struct device *dev, unsigned int size, bool slave) { { struct spi_master *master; struct spi_master *master; Loading @@ -1716,13 +1826,17 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) device_initialize(&master->dev); device_initialize(&master->dev); master->bus_num = -1; master->bus_num = -1; master->num_chipselect = 1; master->num_chipselect = 1; master->slave = slave; if (IS_ENABLED(CONFIG_SPI_SLAVE) && slave) master->dev.class = &spi_slave_class; else master->dev.class = &spi_master_class; master->dev.class = &spi_master_class; master->dev.parent = dev; master->dev.parent = dev; spi_master_set_devdata(master, &master[1]); spi_master_set_devdata(master, &master[1]); return master; return master; } } EXPORT_SYMBOL_GPL(spi_alloc_master); EXPORT_SYMBOL_GPL(__spi_alloc_controller); #ifdef CONFIG_OF #ifdef CONFIG_OF static int of_spi_register_master(struct spi_master *master) static int of_spi_register_master(struct spi_master *master) Loading Loading @@ -1798,9 +1912,11 @@ int spi_register_master(struct spi_master *master) if (!dev) if (!dev) return -ENODEV; return -ENODEV; if (!spi_controller_is_slave(master)) { status = of_spi_register_master(master); status = of_spi_register_master(master); if (status) if (status) return status; return status; } /* even if it's just one always-selected device, there must /* even if it's just one always-selected device, there must * be at least one chipselect * be at least one chipselect Loading Loading @@ -1836,8 +1952,9 @@ int spi_register_master(struct spi_master *master) status = device_add(&master->dev); status = device_add(&master->dev); if (status < 0) if (status < 0) goto done; goto done; dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), dev_dbg(dev, "registered %s %s%s\n", dynamic ? " (dynamic)" : ""); spi_controller_is_slave(master) ? "slave" : "master", dev_name(&master->dev), dynamic ? " (dynamic)" : ""); /* If we're using a queued driver, start the queue */ /* If we're using a queued driver, start the queue */ if (master->transfer) if (master->transfer) Loading Loading @@ -2625,6 +2742,9 @@ static struct spi_master *of_find_spi_master_by_node(struct device_node *node) dev = class_find_device(&spi_master_class, NULL, node, dev = class_find_device(&spi_master_class, NULL, node, __spi_of_master_match); __spi_of_master_match); if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) dev = class_find_device(&spi_slave_class, NULL, node, __spi_of_master_match); if (!dev) if (!dev) return NULL; return NULL; Loading Loading @@ -2697,11 +2817,19 @@ static int __init spi_init(void) if (status < 0) if (status < 0) goto err2; goto err2; if (IS_ENABLED(CONFIG_SPI_SLAVE)) { status = class_register(&spi_slave_class); if (status < 0) goto err3; } if (IS_ENABLED(CONFIG_OF_DYNAMIC)) if (IS_ENABLED(CONFIG_OF_DYNAMIC)) WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); return 0; return 0; err3: class_unregister(&spi_master_class); err2: err2: bus_unregister(&spi_bus_type); bus_unregister(&spi_bus_type); err1: err1: Loading include/linux/spi/spi.h +31 −4 Original line number Original line Diff line number Diff line Loading @@ -27,8 +27,8 @@ struct spi_master; struct spi_transfer; struct spi_transfer; /* /* * INTERFACES between SPI master-side drivers and SPI infrastructure. * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, * (There's no SPI slave support for Linux yet...) * and SPI infrastructure. */ */ extern struct bus_type spi_bus_type; extern struct bus_type spi_bus_type; Loading Loading @@ -303,6 +303,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @min_speed_hz: Lowest supported transfer speed * @min_speed_hz: Lowest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver * @flags: other constraints relevant to this driver * @slave: indicates that this is an SPI slave controller * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use Loading Loading @@ -361,6 +362,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @handle_err: the subsystem calls the driver to handle an error that occurs * @handle_err: the subsystem calls the driver to handle an error that occurs * in the generic implementation of transfer_one_message(). * in the generic implementation of transfer_one_message(). * @unprepare_message: undo any work done by prepare_message(). * @unprepare_message: undo any work done by prepare_message(). * @slave_abort: abort the ongoing transfer request on an SPI slave controller * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). * are not GPIOs (driven by the SPI controller itself). Loading Loading @@ -425,6 +427,9 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ /* flag indicating this is an SPI slave controller */ bool slave; /* lock and mutex for SPI bus locking */ /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; struct mutex bus_lock_mutex; Loading Loading @@ -507,6 +512,7 @@ struct spi_master { struct spi_message *message); struct spi_message *message); int (*unprepare_message)(struct spi_master *master, int (*unprepare_message)(struct spi_master *master, struct spi_message *message); struct spi_message *message); int (*slave_abort)(struct spi_master *spi); /* /* * These hooks are for drivers that use a generic implementation * These hooks are for drivers that use a generic implementation Loading Loading @@ -556,6 +562,11 @@ static inline void spi_master_put(struct spi_master *master) put_device(&master->dev); put_device(&master->dev); } } static inline bool spi_controller_is_slave(struct spi_master *ctlr) { return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave; } /* PM calls that need to be issued by the driver */ /* PM calls that need to be issued by the driver */ extern int spi_master_suspend(struct spi_master *master); extern int spi_master_suspend(struct spi_master *master); extern int spi_master_resume(struct spi_master *master); extern int spi_master_resume(struct spi_master *master); Loading @@ -566,8 +577,23 @@ extern void spi_finalize_current_message(struct spi_master *master); extern void spi_finalize_current_transfer(struct spi_master *master); extern void spi_finalize_current_transfer(struct spi_master *master); /* the spi driver core manages memory for the spi_master classdev */ /* the spi driver core manages memory for the spi_master classdev */ extern struct spi_master * extern struct spi_master *__spi_alloc_controller(struct device *host, spi_alloc_master(struct device *host, unsigned size); unsigned int size, bool slave); static inline struct spi_master *spi_alloc_master(struct device *host, unsigned int size) { return __spi_alloc_controller(host, size, false); } static inline struct spi_master *spi_alloc_slave(struct device *host, unsigned int size) { if (!IS_ENABLED(CONFIG_SPI_SLAVE)) return NULL; return __spi_alloc_controller(host, size, true); } extern int spi_register_master(struct spi_master *master); extern int spi_register_master(struct spi_master *master); extern int devm_spi_register_master(struct device *dev, extern int devm_spi_register_master(struct device *dev, Loading Loading @@ -831,6 +857,7 @@ extern int spi_setup(struct spi_device *spi); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, extern int spi_async_locked(struct spi_device *spi, struct spi_message *message); struct spi_message *message); extern int spi_slave_abort(struct spi_device *spi); /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Loading Loading
drivers/spi/Kconfig +13 −1 Original line number Original line Diff line number Diff line Loading @@ -704,6 +704,18 @@ config SPI_TLE62X0 endif # SPI_MASTER endif # SPI_MASTER # (slave support would go here) # # SLAVE side ... listening to other SPI masters # config SPI_SLAVE bool "SPI slave protocol handlers" help If your system has a slave-capable SPI controller, you can enable slave protocol handlers. if SPI_SLAVE endif # SPI_SLAVE endif # SPI endif # SPI
drivers/spi/Makefile +2 −0 Original line number Original line Diff line number Diff line Loading @@ -95,3 +95,5 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_QSD) += spi_qsd.o obj-$(CONFIG_SPI_QSD) += spi_qsd.o obj-$(CONFIG_SPI_QUP) += spi_qsd.o obj-$(CONFIG_SPI_QUP) += spi_qsd.o # SPI slave protocol handlers
drivers/spi/spi.c +152 −24 Original line number Original line Diff line number Diff line Loading @@ -1427,15 +1427,6 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, u32 value; u32 value; int rc; int rc; /* Device address */ rc = of_property_read_u32(nc, "reg", &value); if (rc) { dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", nc->full_name, rc); return rc; } spi->chip_select = value; /* Mode (clock phase/polarity/etc.) */ /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) if (of_find_property(nc, "spi-cpha", NULL)) spi->mode |= SPI_CPHA; spi->mode |= SPI_CPHA; Loading Loading @@ -1485,6 +1476,24 @@ static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi, } } } } if (spi_controller_is_slave(master)) { if (strcmp(nc->name, "slave")) { dev_err(&master->dev, "%s is not called 'slave'\n", nc->full_name); return -EINVAL; } return 0; } /* Device address */ rc = of_property_read_u32(nc, "reg", &value); if (rc) { dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n", nc->full_name, rc); return rc; } spi->chip_select = value; /* Device speed */ /* Device speed */ rc = of_property_read_u32(nc, "spi-max-frequency", &value); rc = of_property_read_u32(nc, "spi-max-frequency", &value); if (rc) { if (rc) { Loading Loading @@ -1548,8 +1557,8 @@ err_out: * of_register_spi_devices() - Register child devices onto the SPI bus * of_register_spi_devices() - Register child devices onto the SPI bus * @master: Pointer to spi_master device * @master: Pointer to spi_master device * * * Registers an spi_device for each child node of master node which has a 'reg' * Registers an spi_device for each child node of controller node which * property. * represents a valid SPI slave. */ */ static void of_register_spi_devices(struct spi_master *master) static void of_register_spi_devices(struct spi_master *master) { { Loading Loading @@ -1681,28 +1690,129 @@ static struct class spi_master_class = { .dev_groups = spi_master_groups, .dev_groups = spi_master_groups, }; }; #ifdef CONFIG_SPI_SLAVE /** * spi_slave_abort - abort the ongoing transfer request on an SPI slave * controller * @spi: device used for the current transfer */ int spi_slave_abort(struct spi_device *spi) { struct spi_master *master = spi->master; if (spi_controller_is_slave(master) && master->slave_abort) return master->slave_abort(master); return -ENOTSUPP; } EXPORT_SYMBOL_GPL(spi_slave_abort); static int match_true(struct device *dev, void *data) { return 1; } static ssize_t spi_slave_show(struct device *dev, struct device_attribute *attr, char *buf) { struct spi_master *ctlr = container_of(dev, struct spi_master, dev); struct device *child; child = device_find_child(&ctlr->dev, NULL, match_true); return sprintf(buf, "%s\n", child ? to_spi_device(child)->modalias : NULL); } static ssize_t spi_slave_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct spi_master *ctlr = container_of(dev, struct spi_master, dev); struct spi_device *spi; struct device *child; char name[32]; int rc; rc = sscanf(buf, "%31s", name); if (rc != 1 || !name[0]) return -EINVAL; child = device_find_child(&ctlr->dev, NULL, match_true); if (child) { /* Remove registered slave */ device_unregister(child); put_device(child); } if (strcmp(name, "(null)")) { /* Register new slave */ spi = spi_alloc_device(ctlr); if (!spi) return -ENOMEM; strlcpy(spi->modalias, name, sizeof(spi->modalias)); rc = spi_add_device(spi); if (rc) { spi_dev_put(spi); return rc; } } return count; } static DEVICE_ATTR(slave, 0644, spi_slave_show, spi_slave_store); static struct attribute *spi_slave_attrs[] = { &dev_attr_slave.attr, NULL, }; static const struct attribute_group spi_slave_group = { .attrs = spi_slave_attrs, }; static const struct attribute_group *spi_slave_groups[] = { &spi_master_statistics_group, &spi_slave_group, NULL, }; static struct class spi_slave_class = { .name = "spi_slave", .owner = THIS_MODULE, .dev_release = spi_master_release, .dev_groups = spi_slave_groups, }; #else extern struct class spi_slave_class; /* dummy */ #endif /** /** * spi_alloc_master - allocate SPI master controller * __spi_alloc_controller - allocate an SPI master or slave controller * @dev: the controller, possibly using the platform_bus * @dev: the controller, possibly using the platform_bus * @size: how much zeroed driver-private data to allocate; the pointer to this * @size: how much zeroed driver-private data to allocate; the pointer to this * memory is in the driver_data field of the returned device, * memory is in the driver_data field of the returned device, * accessible with spi_master_get_devdata(). * accessible with spi_master_get_devdata(). * @slave: flag indicating whether to allocate an SPI master (false) or SPI * slave (true) controller * Context: can sleep * Context: can sleep * * * This call is used only by SPI master controller drivers, which are the * This call is used only by SPI controller drivers, which are the * only ones directly touching chip registers. It's how they allocate * only ones directly touching chip registers. It's how they allocate * an spi_master structure, prior to calling spi_register_master(). * an spi_master structure, prior to calling spi_register_master(). * * * This must be called from context that can sleep. * This must be called from context that can sleep. * * * The caller is responsible for assigning the bus number and initializing * The caller is responsible for assigning the bus number and initializing the * the master's methods before calling spi_register_master(); and (after errors * controller's methods before calling spi_register_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. * adding the device) calling spi_master_put() to prevent a memory leak. * * * Return: the SPI master structure on success, else NULL. * Return: the SPI controller structure on success, else NULL. */ */ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) struct spi_master *__spi_alloc_controller(struct device *dev, unsigned int size, bool slave) { { struct spi_master *master; struct spi_master *master; Loading @@ -1716,13 +1826,17 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) device_initialize(&master->dev); device_initialize(&master->dev); master->bus_num = -1; master->bus_num = -1; master->num_chipselect = 1; master->num_chipselect = 1; master->slave = slave; if (IS_ENABLED(CONFIG_SPI_SLAVE) && slave) master->dev.class = &spi_slave_class; else master->dev.class = &spi_master_class; master->dev.class = &spi_master_class; master->dev.parent = dev; master->dev.parent = dev; spi_master_set_devdata(master, &master[1]); spi_master_set_devdata(master, &master[1]); return master; return master; } } EXPORT_SYMBOL_GPL(spi_alloc_master); EXPORT_SYMBOL_GPL(__spi_alloc_controller); #ifdef CONFIG_OF #ifdef CONFIG_OF static int of_spi_register_master(struct spi_master *master) static int of_spi_register_master(struct spi_master *master) Loading Loading @@ -1798,9 +1912,11 @@ int spi_register_master(struct spi_master *master) if (!dev) if (!dev) return -ENODEV; return -ENODEV; if (!spi_controller_is_slave(master)) { status = of_spi_register_master(master); status = of_spi_register_master(master); if (status) if (status) return status; return status; } /* even if it's just one always-selected device, there must /* even if it's just one always-selected device, there must * be at least one chipselect * be at least one chipselect Loading Loading @@ -1836,8 +1952,9 @@ int spi_register_master(struct spi_master *master) status = device_add(&master->dev); status = device_add(&master->dev); if (status < 0) if (status < 0) goto done; goto done; dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), dev_dbg(dev, "registered %s %s%s\n", dynamic ? " (dynamic)" : ""); spi_controller_is_slave(master) ? "slave" : "master", dev_name(&master->dev), dynamic ? " (dynamic)" : ""); /* If we're using a queued driver, start the queue */ /* If we're using a queued driver, start the queue */ if (master->transfer) if (master->transfer) Loading Loading @@ -2625,6 +2742,9 @@ static struct spi_master *of_find_spi_master_by_node(struct device_node *node) dev = class_find_device(&spi_master_class, NULL, node, dev = class_find_device(&spi_master_class, NULL, node, __spi_of_master_match); __spi_of_master_match); if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE)) dev = class_find_device(&spi_slave_class, NULL, node, __spi_of_master_match); if (!dev) if (!dev) return NULL; return NULL; Loading Loading @@ -2697,11 +2817,19 @@ static int __init spi_init(void) if (status < 0) if (status < 0) goto err2; goto err2; if (IS_ENABLED(CONFIG_SPI_SLAVE)) { status = class_register(&spi_slave_class); if (status < 0) goto err3; } if (IS_ENABLED(CONFIG_OF_DYNAMIC)) if (IS_ENABLED(CONFIG_OF_DYNAMIC)) WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); WARN_ON(of_reconfig_notifier_register(&spi_of_notifier)); return 0; return 0; err3: class_unregister(&spi_master_class); err2: err2: bus_unregister(&spi_bus_type); bus_unregister(&spi_bus_type); err1: err1: Loading
include/linux/spi/spi.h +31 −4 Original line number Original line Diff line number Diff line Loading @@ -27,8 +27,8 @@ struct spi_master; struct spi_transfer; struct spi_transfer; /* /* * INTERFACES between SPI master-side drivers and SPI infrastructure. * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, * (There's no SPI slave support for Linux yet...) * and SPI infrastructure. */ */ extern struct bus_type spi_bus_type; extern struct bus_type spi_bus_type; Loading Loading @@ -303,6 +303,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @min_speed_hz: Lowest supported transfer speed * @min_speed_hz: Lowest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver * @flags: other constraints relevant to this driver * @slave: indicates that this is an SPI slave controller * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use Loading Loading @@ -361,6 +362,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @handle_err: the subsystem calls the driver to handle an error that occurs * @handle_err: the subsystem calls the driver to handle an error that occurs * in the generic implementation of transfer_one_message(). * in the generic implementation of transfer_one_message(). * @unprepare_message: undo any work done by prepare_message(). * @unprepare_message: undo any work done by prepare_message(). * @slave_abort: abort the ongoing transfer request on an SPI slave controller * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). * are not GPIOs (driven by the SPI controller itself). Loading Loading @@ -425,6 +427,9 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ /* flag indicating this is an SPI slave controller */ bool slave; /* lock and mutex for SPI bus locking */ /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; struct mutex bus_lock_mutex; Loading Loading @@ -507,6 +512,7 @@ struct spi_master { struct spi_message *message); struct spi_message *message); int (*unprepare_message)(struct spi_master *master, int (*unprepare_message)(struct spi_master *master, struct spi_message *message); struct spi_message *message); int (*slave_abort)(struct spi_master *spi); /* /* * These hooks are for drivers that use a generic implementation * These hooks are for drivers that use a generic implementation Loading Loading @@ -556,6 +562,11 @@ static inline void spi_master_put(struct spi_master *master) put_device(&master->dev); put_device(&master->dev); } } static inline bool spi_controller_is_slave(struct spi_master *ctlr) { return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave; } /* PM calls that need to be issued by the driver */ /* PM calls that need to be issued by the driver */ extern int spi_master_suspend(struct spi_master *master); extern int spi_master_suspend(struct spi_master *master); extern int spi_master_resume(struct spi_master *master); extern int spi_master_resume(struct spi_master *master); Loading @@ -566,8 +577,23 @@ extern void spi_finalize_current_message(struct spi_master *master); extern void spi_finalize_current_transfer(struct spi_master *master); extern void spi_finalize_current_transfer(struct spi_master *master); /* the spi driver core manages memory for the spi_master classdev */ /* the spi driver core manages memory for the spi_master classdev */ extern struct spi_master * extern struct spi_master *__spi_alloc_controller(struct device *host, spi_alloc_master(struct device *host, unsigned size); unsigned int size, bool slave); static inline struct spi_master *spi_alloc_master(struct device *host, unsigned int size) { return __spi_alloc_controller(host, size, false); } static inline struct spi_master *spi_alloc_slave(struct device *host, unsigned int size) { if (!IS_ENABLED(CONFIG_SPI_SLAVE)) return NULL; return __spi_alloc_controller(host, size, true); } extern int spi_register_master(struct spi_master *master); extern int spi_register_master(struct spi_master *master); extern int devm_spi_register_master(struct device *dev, extern int devm_spi_register_master(struct device *dev, Loading Loading @@ -831,6 +857,7 @@ extern int spi_setup(struct spi_device *spi); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, extern int spi_async_locked(struct spi_device *spi, struct spi_message *message); struct spi_message *message); extern int spi_slave_abort(struct spi_device *spi); /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ Loading