From patchwork Wed Jun 22 13:42:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 9192985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B60D460890 for ; Wed, 22 Jun 2016 13:43:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A6600283FD for ; Wed, 22 Jun 2016 13:43:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B42828409; Wed, 22 Jun 2016 13:43:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27D8128406 for ; Wed, 22 Jun 2016 13:43:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751997AbcFVNm7 (ORCPT ); Wed, 22 Jun 2016 09:42:59 -0400 Received: from xavier.telenet-ops.be ([195.130.132.52]:41979 "EHLO xavier.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752675AbcFVNmS (ORCPT ); Wed, 22 Jun 2016 09:42:18 -0400 Received: from ayla.of.borg ([84.195.107.21]) by xavier.telenet-ops.be with bizsmtp id 9piD1t00v0TjorY01piDHK; Wed, 22 Jun 2016 15:42:15 +0200 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1bFiQ1-0005Rr-HW; Wed, 22 Jun 2016 15:42:13 +0200 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1bFiQ2-00016Q-6G; Wed, 22 Jun 2016 15:42:14 +0200 From: Geert Uytterhoeven To: Mark Brown Cc: Rob Herring , Mark Rutland , Magnus Damm , Hisashi Nakamura , Hiromitsu Yamasaki , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC 2/6] spi: core: Add support for registering SPI slave controllers Date: Wed, 22 Jun 2016 15:42:05 +0200 Message-Id: <1466602929-4191-3-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466602929-4191-1-git-send-email-geert+renesas@glider.be> References: <1466602929-4191-1-git-send-email-geert+renesas@glider.be> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for registering SPI slave controllers using the existing SPI master framework: - SPI slave controllers must set the SPI_MASTER_IS_SLAVE flag in spi_master.flags, - The "cs-gpios" property is ignored, - The bus is described in DT as having a single slave node, "reg" and "spi-max-frequency" properties are ignored. From the point of view of an SPI slave protocol handler, an SPI slave controller looks exactly like an ordinary SPI master controller. Signed-off-by: Geert Uytterhoeven --- Should we rename spi_master to spi_controller? --- drivers/spi/Kconfig | 14 +++++++++++++- drivers/spi/Makefile | 2 ++ drivers/spi/spi.c | 39 ++++++++++++++++++++++++--------------- include/linux/spi/spi.h | 5 +++-- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4b931ec8d90b610f..00e990d91a715c0e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -736,6 +736,18 @@ config SPI_TLE62X0 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 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 3c74d003535bb9fb..71d02939080fb747 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -97,3 +97,5 @@ obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o obj-$(CONFIG_SPI_XLP) += spi-xlp.o obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + +# SPI slave protocol handlers diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 77e6e45951f4c5e1..6ea32255d6d9e780 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1462,6 +1462,7 @@ err_init_queue: static struct spi_device * of_register_spi_device(struct spi_master *master, struct device_node *nc) { + bool slave = master->flags & SPI_MASTER_IS_SLAVE; struct spi_device *spi; int rc; u32 value; @@ -1485,13 +1486,16 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) } /* 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); - goto err_out; + if (!slave) { + 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); + goto err_out; + } + spi->chip_select = value; } - spi->chip_select = value; /* Mode (clock phase/polarity/etc.) */ if (of_find_property(nc, "spi-cpha", NULL)) @@ -1543,13 +1547,16 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc) } /* Device speed */ - rc = of_property_read_u32(nc, "spi-max-frequency", &value); - if (rc) { - dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n", - nc->full_name, rc); - goto err_out; + if (!slave) { + rc = of_property_read_u32(nc, "spi-max-frequency", &value); + if (rc) { + dev_err(&master->dev, + "%s has no valid 'spi-max-frequency' property (%d)\n", + nc->full_name, rc); + goto err_out; + } + spi->max_speed_hz = value; } - spi->max_speed_hz = value; /* Store a pointer to the node in the device structure */ of_node_get(nc); @@ -1779,7 +1786,7 @@ static int of_spi_register_master(struct spi_master *master) int nb, i, *cs; struct device_node *np = master->dev.of_node; - if (!np) + if (!np || master->flags & SPI_MASTER_IS_SLAVE) return 0; nb = of_gpio_named_count(np, "cs-gpios"); @@ -1885,8 +1892,10 @@ int spi_register_master(struct spi_master *master) status = device_add(&master->dev); if (status < 0) goto done; - dev_dbg(dev, "registered master %s%s\n", dev_name(&master->dev), - dynamic ? " (dynamic)" : ""); + dev_dbg(dev, "registered %s %s%s\n", + master->flags & SPI_MASTER_IS_SLAVE ? "slave" + : "master", + dev_name(&master->dev), dynamic ? " (dynamic)" : ""); /* If we're using a queued driver, start the queue */ if (master->transfer) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 1f03483f61e5714b..0fbebaa7d93990a4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -28,8 +28,8 @@ struct spi_transfer; struct spi_flash_read_message; /* - * INTERFACES between SPI master-side drivers and SPI infrastructure. - * (There's no SPI slave support for Linux yet...) + * INTERFACES between SPI master-side drivers and SPI slave protocol handers, + * and SPI infrastructure. */ extern struct bus_type spi_bus_type; @@ -439,6 +439,7 @@ struct spi_master { #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ +#define SPI_MASTER_IS_SLAVE BIT(5) /* SPI slave controller */ /* * on some hardware transfer size may be constrained