From patchwork Mon Jun 21 17:53:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 464830 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4343BC4743C for ; Mon, 21 Jun 2021 17:56:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 28D8561361 for ; Mon, 21 Jun 2021 17:56:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232051AbhFUR6W (ORCPT ); Mon, 21 Jun 2021 13:58:22 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:51016 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232996AbhFUR4S (ORCPT ); Mon, 21 Jun 2021 13:56:18 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id B63DE1F4267B Received: by jupiter.universe (Postfix, from userid 1000) id 0982F4800C7; Mon, 21 Jun 2021 19:54:00 +0200 (CEST) From: Sebastian Reichel To: Mark Brown , Rob Herring Cc: Arnd Bergmann , Greg Kroah-Hartman , Shawn Guo , Sascha Hauer , Fabio Estevam , Ian Ray , linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org, kernel@collabora.com, Sebastian Reichel Subject: [PATCHv5 1/5] spi: add ancillary device support Date: Mon, 21 Jun 2021 19:53:55 +0200 Message-Id: <20210621175359.126729-2-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210621175359.126729-1-sebastian.reichel@collabora.com> References: <20210621175359.126729-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Introduce support for ancillary devices, similar to existing implementation for I2C. This is useful for devices having multiple chip-selects, for example some microcontrollers provide a normal SPI interface and a flashing SPI interface. Signed-off-by: Sebastian Reichel --- drivers/spi/spi.c | 137 +++++++++++++++++++++++++++++++--------- include/linux/spi/spi.h | 2 + 2 files changed, 108 insertions(+), 31 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 16b377581d16..b1b6031961b7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -564,49 +564,23 @@ static void spi_cleanup(struct spi_device *spi) spi->controller->cleanup(spi); } -/** - * spi_add_device - Add spi_device allocated with spi_alloc_device - * @spi: spi_device to register - * - * Companion function to spi_alloc_device. Devices allocated with - * spi_alloc_device can be added onto the spi bus with this function. - * - * Return: 0 on success; negative errno on failure - */ -int spi_add_device(struct spi_device *spi) +static int __spi_add_device(struct spi_device *spi) { struct spi_controller *ctlr = spi->controller; struct device *dev = ctlr->dev.parent; int status; - /* Chipselects are numbered 0..max; validate. */ - if (spi->chip_select >= ctlr->num_chipselect) { - dev_err(dev, "cs%d >= max %d\n", spi->chip_select, - ctlr->num_chipselect); - return -EINVAL; - } - - /* Set the bus ID string */ - spi_dev_set_name(spi); - - /* We need to make sure there's no other device with this - * chipselect **BEFORE** we call setup(), else we'll trash - * its configuration. Lock against concurrent add() calls. - */ - mutex_lock(&spi_add_lock); - status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); if (status) { dev_err(dev, "chipselect %d already in use\n", spi->chip_select); - goto done; + return status; } /* Controller may unregister concurrently */ if (IS_ENABLED(CONFIG_SPI_DYNAMIC) && !device_is_registered(&ctlr->dev)) { - status = -ENODEV; - goto done; + return -ENODEV; } /* Descriptors take precedence */ @@ -623,7 +597,7 @@ int spi_add_device(struct spi_device *spi) if (status < 0) { dev_err(dev, "can't setup %s, status %d\n", dev_name(&spi->dev), status); - goto done; + return status; } /* Device may be bound to an active driver when this returns */ @@ -636,12 +610,64 @@ int spi_add_device(struct spi_device *spi) dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); } -done: + return status; +} + +/** + * spi_add_device - Add spi_device allocated with spi_alloc_device + * @spi: spi_device to register + * + * Companion function to spi_alloc_device. Devices allocated with + * spi_alloc_device can be added onto the spi bus with this function. + * + * Return: 0 on success; negative errno on failure + */ +int spi_add_device(struct spi_device *spi) +{ + struct spi_controller *ctlr = spi->controller; + struct device *dev = ctlr->dev.parent; + int status; + + /* Chipselects are numbered 0..max; validate. */ + if (spi->chip_select >= ctlr->num_chipselect) { + dev_err(dev, "cs%d >= max %d\n", spi->chip_select, + ctlr->num_chipselect); + return -EINVAL; + } + + /* Set the bus ID string */ + spi_dev_set_name(spi); + + /* We need to make sure there's no other device with this + * chipselect **BEFORE** we call setup(), else we'll trash + * its configuration. Lock against concurrent add() calls. + */ + mutex_lock(&spi_add_lock); + status = __spi_add_device(spi); mutex_unlock(&spi_add_lock); return status; } EXPORT_SYMBOL_GPL(spi_add_device); +static int spi_add_device_locked(struct spi_device *spi) +{ + struct spi_controller *ctlr = spi->controller; + struct device *dev = ctlr->dev.parent; + + /* Chipselects are numbered 0..max; validate. */ + if (spi->chip_select >= ctlr->num_chipselect) { + dev_err(dev, "cs%d >= max %d\n", spi->chip_select, + ctlr->num_chipselect); + return -EINVAL; + } + + /* Set the bus ID string */ + spi_dev_set_name(spi); + + WARN_ON(!mutex_is_locked(&spi_add_lock)); + return __spi_add_device(spi); +} + /** * spi_new_device - instantiate one new SPI device * @ctlr: Controller to which device is connected @@ -2126,6 +2152,55 @@ static void of_register_spi_devices(struct spi_controller *ctlr) static void of_register_spi_devices(struct spi_controller *ctlr) { } #endif +/** + * spi_new_ancillary_device() - Register ancillary SPI device + * @spi: Pointer to the main SPI device registering the ancillary device + * @chip_select: Chip Select of the ancillary device + * + * Register an ancillary SPI device; for example some chips have a chip-select + * for normal device usage and another one for setup/firmware upload. + * + * This may only be called from main SPI device's probe routine. + * + * Return: 0 on success; negative errno on failure + */ +struct spi_device *spi_new_ancillary_device(struct spi_device *spi, + u8 chip_select) +{ + struct spi_device *ancillary; + int rc = 0; + + /* Alloc an spi_device */ + ancillary = spi_alloc_device(spi->controller); + if (!ancillary) { + rc = -ENOMEM; + goto err_out; + } + + strlcpy(ancillary->modalias, "dummy", sizeof(ancillary->modalias)); + + /* Use provided chip-select for ancillary device */ + ancillary->chip_select = chip_select; + + /* Take over SPI mode/speed from SPI main device */ + ancillary->max_speed_hz = spi->max_speed_hz; + ancillary->mode = ancillary->mode; + + /* Register the new device */ + rc = spi_add_device_locked(ancillary); + if (rc) { + dev_err(&spi->dev, "failed to register ancillary device\n"); + goto err_out; + } + + return ancillary; + +err_out: + spi_dev_put(ancillary); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(spi_new_ancillary_device); + #ifdef CONFIG_ACPI struct acpi_spi_lookup { struct spi_controller *ctlr; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index f924160e995f..3ada36175e5f 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -299,6 +299,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) driver_unregister(&sdrv->driver); } +extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select); + /* use a define to avoid include chaining to get THIS_MODULE */ #define spi_register_driver(driver) \ __spi_register_driver(THIS_MODULE, driver) From patchwork Mon Jun 21 17:53:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 464829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D147C49EA2 for ; Mon, 21 Jun 2021 17:56:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 086C461370 for ; Mon, 21 Jun 2021 17:56:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233367AbhFUR6c (ORCPT ); Mon, 21 Jun 2021 13:58:32 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:51048 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233007AbhFUR4S (ORCPT ); Mon, 21 Jun 2021 13:56:18 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id C1A471F42689 Received: by jupiter.universe (Postfix, from userid 1000) id 0CEA24800C8; Mon, 21 Jun 2021 19:54:00 +0200 (CEST) From: Sebastian Reichel To: Mark Brown , Rob Herring Cc: Arnd Bergmann , Greg Kroah-Hartman , Shawn Guo , Sascha Hauer , Fabio Estevam , Ian Ray , linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org, kernel@collabora.com, Sebastian Reichel , Rob Herring Subject: [PATCHv5 2/5] spi: dt-bindings: support devices with multiple chipselects Date: Mon, 21 Jun 2021 19:53:56 +0200 Message-Id: <20210621175359.126729-3-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210621175359.126729-1-sebastian.reichel@collabora.com> References: <20210621175359.126729-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Add binding support for devices, that have more than one chip select. A typical example are SPI connected microcontroller, that can also be programmed over SPI like NXP Kinetis or chips with a configuration and a data chip select, such as Microchip's MRF89XA transceiver. Reviewed-by: Rob Herring Signed-off-by: Sebastian Reichel --- Documentation/devicetree/bindings/spi/spi-controller.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-controller.yaml b/Documentation/devicetree/bindings/spi/spi-controller.yaml index 0477396e4945..faef4f6f55b8 100644 --- a/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ b/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -114,8 +114,11 @@ patternProperties: Compatible of the SPI device. reg: - minimum: 0 - maximum: 256 + minItems: 1 + maxItems: 256 + items: + minimum: 0 + maximum: 256 description: Chip select used by the device. From patchwork Mon Jun 21 17:53:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 464828 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F018FC48BC2 for ; Mon, 21 Jun 2021 18:04:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D40EB6100B for ; Mon, 21 Jun 2021 18:04:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232524AbhFUSGx (ORCPT ); Mon, 21 Jun 2021 14:06:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231262AbhFUSD6 (ORCPT ); Mon, 21 Jun 2021 14:03:58 -0400 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1103C061D7F; Mon, 21 Jun 2021 10:54:05 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id BDCEF1F42682 Received: by jupiter.universe (Postfix, from userid 1000) id 13F934800DD; Mon, 21 Jun 2021 19:54:00 +0200 (CEST) From: Sebastian Reichel To: Mark Brown , Rob Herring Cc: Arnd Bergmann , Greg Kroah-Hartman , Shawn Guo , Sascha Hauer , Fabio Estevam , Ian Ray , linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, devicetree@vger.kernel.org, kernel@collabora.com, Sebastian Reichel Subject: [PATCHv5 4/5] ARM: dts: imx53-ppd: Fix ACHC entry Date: Mon, 21 Jun 2021 19:53:58 +0200 Message-Id: <20210621175359.126729-5-sebastian.reichel@collabora.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210621175359.126729-1-sebastian.reichel@collabora.com> References: <20210621175359.126729-1-sebastian.reichel@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org PPD has only one ACHC device, which effectively is a Kinetis microcontroller. It has one SPI interface used for normal communication. Additionally it's possible to flash the device firmware using NXP's EzPort protocol by correctly driving a second chip select pin and the device reset pin. Signed-off-by: Sebastian Reichel --- arch/arm/boot/dts/imx53-ppd.dts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts index be040b6a02fa..1f3ee60fb102 100644 --- a/arch/arm/boot/dts/imx53-ppd.dts +++ b/arch/arm/boot/dts/imx53-ppd.dts @@ -70,6 +70,12 @@ cko2_11M: sgtl-clock-cko2 { clock-frequency = <11289600>; }; + achc_24M: achc-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + sgtlsound: sound { compatible = "fsl,imx53-cpuvo-sgtl5000", "fsl,imx-audio-sgtl5000"; @@ -314,16 +320,13 @@ &gpio4 11 GPIO_ACTIVE_LOW &gpio4 12 GPIO_ACTIVE_LOW>; status = "okay"; - spidev0: spi@0 { - compatible = "ge,achc"; - reg = <0>; - spi-max-frequency = <1000000>; - }; - - spidev1: spi@1 { - compatible = "ge,achc"; - reg = <1>; - spi-max-frequency = <1000000>; + spidev0: spi@1 { + compatible = "ge,achc", "nxp,kinetis-k20"; + reg = <1>, <0>; + vdd-supply = <®_3v3>; + vdda-supply = <®_3v3>; + clocks = <&achc_24M>; + reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; }; gpioxra0: gpio@2 {