linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/2] SPI bus multiplexing
@ 2020-02-04  3:28 Chris Packham
  2020-02-04  3:28 ` [PATCH v5 1/2] dt-bindings: spi: Document binding for generic SPI multiplexer Chris Packham
  2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
  0 siblings, 2 replies; 9+ messages in thread
From: Chris Packham @ 2020-02-04  3:28 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, Andy Shevchenko
  Cc: linux-spi, devicetree, linux-kernel, Chris Packham

This is a revisit of two earlier efforts to add more complex mutliplexing to
SPI busses.

https://patchwork.kernel.org/patch/2706151/
https://patchwork.kernel.org/patch/10897255/

This version makes use of the general purpose mux controller which simplifies
things greatly.

One outstanding problem is the need for the spi-max-frequency on the mux
device. This is not used for anything and is just needed to satisfy the spi
driver infrastructure which expects all spi devices to have this property.

Chris Packham (2):
  dt-bindings: spi: Document binding for generic SPI multiplexer
  spi: Add generic SPI multiplexer

 .../devicetree/bindings/spi/spi-mux.yaml      |  89 +++++++++
 drivers/spi/Kconfig                           |  11 ++
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-mux.c                         | 187 ++++++++++++++++++
 4 files changed, 288 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux.yaml
 create mode 100644 drivers/spi/spi-mux.c

-- 
2.25.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v5 1/2] dt-bindings: spi: Document binding for generic SPI multiplexer
  2020-02-04  3:28 [PATCH v5 0/2] SPI bus multiplexing Chris Packham
@ 2020-02-04  3:28 ` Chris Packham
  2020-02-12 23:58   ` Applied "dt-bindings: spi: Document binding for generic SPI multiplexer" to the spi tree Mark Brown
  2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
  1 sibling, 1 reply; 9+ messages in thread
From: Chris Packham @ 2020-02-04  3:28 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, Andy Shevchenko
  Cc: linux-spi, devicetree, linux-kernel, Chris Packham

Add binding documentation for the spi-mux driver. This allows a generic
multiplexer to be used to provide access to multiple SPI devices.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: Rob Herring <robh@kernel.org>
---

Notes:
    Changes in v5:
    - Add reviewed-by from Rob
    
    Changes in v3:
    - make dt_binding_check clean (properly this time)
    
    Changes in v2:
    - update license
    - make dt_binding_check clean

 .../devicetree/bindings/spi/spi-mux.yaml      | 89 +++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux.yaml

diff --git a/Documentation/devicetree/bindings/spi/spi-mux.yaml b/Documentation/devicetree/bindings/spi/spi-mux.yaml
new file mode 100644
index 000000000000..0ae692dc28b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-mux.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/spi-mux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic SPI Multiplexer
+
+description: |
+  This binding describes a SPI bus multiplexer to route the SPI chip select
+  signals. This can be used when you need more devices than the SPI controller
+  has chip selects available. An example setup is shown in ASCII art; the actual
+  setting of the multiplexer to a channel needs to be done by a specific SPI mux
+  driver.
+
+        MOSI /--------------------------------+--------+--------+--------\
+        MISO |/------------------------------+|-------+|-------+|-------\|
+         SCL ||/----------------------------+||------+||------+||------\||
+             |||                            |||      |||      |||      |||
+      +------------+                        |||      |||      |||      |||
+      | SoC  |||   |                      +-+++-+  +-+++-+  +-+++-+  +-+++-+
+      |      |||   |                      | dev |  | dev |  | dev |  | dev |
+      |   +--+++-+ | CS-X  +------+\      +--+--+  +--+--+  +--+--+  +--+--+
+      |   | SPI  +-|-------+ Mux  |\\   CS-0 |        |        |        |
+      |   +------+ |       +--+---+\\\-------/   CS-1 |        |        |
+      |            |          |    \\\----------------/   CS-2 |        |
+      |   +------+ |          |     \\-------------------------/   CS-3 |
+      |   | ?    +-|----------/      \----------------------------------/
+      |   +------+ |
+      +------------+
+
+allOf:
+  - $ref: "/schemas/spi/spi-controller.yaml#"
+
+maintainers:
+  - Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+properties:
+  compatible:
+    const: spi-mux
+
+  mux-controls:
+    maxItems: 1
+
+required:
+   - compatible
+   - reg
+   - spi-max-frequency
+   - mux-controls
+
+examples:
+   - |
+     #include <dt-bindings/gpio/gpio.h>
+     mux: mux-controller {
+       compatible = "gpio-mux";
+       #mux-control-cells = <0>;
+
+       mux-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+     };
+
+     spi {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       spi@0 {
+         compatible = "spi-mux";
+         reg = <0>;
+         #address-cells = <1>;
+         #size-cells = <0>;
+         spi-max-frequency = <100000000>;
+
+         mux-controls = <&mux>;
+
+         spi-flash@0 {
+           compatible = "jedec,spi-nor";
+           reg = <0>;
+           #address-cells = <1>;
+           #size-cells = <0>;
+           spi-max-frequency = <40000000>;
+         };
+
+         spi-device@1 {
+           compatible = "lineartechnology,ltc2488";
+           reg = <1>;
+           #address-cells = <1>;
+           #size-cells = <0>;
+           spi-max-frequency = <10000000>;
+         };
+       };
+     };
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v5 2/2] spi: Add generic SPI multiplexer
  2020-02-04  3:28 [PATCH v5 0/2] SPI bus multiplexing Chris Packham
  2020-02-04  3:28 ` [PATCH v5 1/2] dt-bindings: spi: Document binding for generic SPI multiplexer Chris Packham
@ 2020-02-04  3:28 ` Chris Packham
  2020-02-04 11:10   ` Andy Shevchenko
                     ` (2 more replies)
  1 sibling, 3 replies; 9+ messages in thread
From: Chris Packham @ 2020-02-04  3:28 UTC (permalink / raw)
  To: broonie, robh+dt, mark.rutland, Andy Shevchenko
  Cc: linux-spi, devicetree, linux-kernel, Chris Packham

Add a SPI device driver that sits in-band and provides a SPI controller
which supports chip selects via a mux-control. This enables extra SPI
devices to be connected with limited native chip selects.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---

Notes:
    Changes in v5:
    - Drop redudnant lines, use IS_ERR() instead of PTR_ERR_OR_ZERO
    
    Changes in v4:
    - incorporate review feedback from Andy

 drivers/spi/Kconfig   |  11 +++
 drivers/spi/Makefile  |   1 +
 drivers/spi/spi-mux.c | 187 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 drivers/spi/spi-mux.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 870f7797b56b..a4509000a291 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -881,6 +881,17 @@ config SPI_ZYNQMP_GQSPI
 # Add new SPI master controllers in alphabetical order above this line
 #
 
+comment "SPI Multiplexer support"
+
+config SPI_MUX
+	tristate "SPI multiplexer support"
+	select MULTIPLEXER
+	help
+	  This adds support for SPI multiplexers. Each SPI mux will be
+	  accessible as a SPI controller, the devices behind the mux will appear
+	  to be chip selects on this controller. It is still necessary to
+	  select one or more specific mux-controller drivers.
+
 #
 # There are lots of SPI device types, with sensors and memory
 # being probably the most widely used ones.
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index bb49c9e6d0a0..116409533727 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -9,6 +9,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG
 # config declarations into driver model code
 obj-$(CONFIG_SPI_MASTER)		+= spi.o
 obj-$(CONFIG_SPI_MEM)			+= spi-mem.o
+obj-$(CONFIG_SPI_MUX)			+= spi-mux.o
 obj-$(CONFIG_SPI_SPIDEV)		+= spidev.o
 obj-$(CONFIG_SPI_LOOPBACK_TEST)		+= spi-loopback-test.o
 
diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c
new file mode 100644
index 000000000000..4f94c9127fc1
--- /dev/null
+++ b/drivers/spi/spi-mux.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// General Purpose SPI multiplexer
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mux/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#define SPI_MUX_NO_CS	((unsigned int)-1)
+
+/**
+ * DOC: Driver description
+ *
+ * This driver supports a MUX on an SPI bus. This can be useful when you need
+ * more chip selects than the hardware peripherals support, or than are
+ * available in a particular board setup.
+ *
+ * The driver will create an additional SPI controller. Devices added under the
+ * mux will be handled as 'chip selects' on this controller.
+ */
+
+/**
+ * struct spi_mux_priv - the basic spi_mux structure
+ * @spi:		pointer to the device struct attached to the parent
+ *			spi controller
+ * @current_cs:		The current chip select set in the mux
+ * @child_msg_complete: The mux replaces the complete callback in the child's
+ *			message to its own callback; this field is used by the
+ *			driver to store the child's callback during a transfer
+ * @child_msg_context:	Used to store the child's context to the callback
+ * @child_msg_dev:	Used to store the spi_device pointer to the child
+ * @mux:		mux_control structure used to provide chip selects for
+ *			downstream spi devices
+ */
+struct spi_mux_priv {
+	struct spi_device	*spi;
+	unsigned int		current_cs;
+
+	void			(*child_msg_complete)(void *context);
+	void			*child_msg_context;
+	struct spi_device	*child_msg_dev;
+	struct mux_control	*mux;
+};
+
+/* should not get called when the parent controller is doing a transfer */
+static int spi_mux_select(struct spi_device *spi)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
+	int ret;
+
+	if (priv->current_cs == spi->chip_select)
+		return 0;
+
+	dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n",
+		spi->chip_select);
+
+	/* copy the child device's settings except for the cs */
+	priv->spi->max_speed_hz = spi->max_speed_hz;
+	priv->spi->mode = spi->mode;
+	priv->spi->bits_per_word = spi->bits_per_word;
+
+	ret = mux_control_select(priv->mux, spi->chip_select);
+	if (ret)
+		return ret;
+
+	priv->current_cs = spi->chip_select;
+
+	return 0;
+}
+
+static int spi_mux_setup(struct spi_device *spi)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
+
+	/*
+	 * can be called multiple times, won't do a valid setup now but we will
+	 * change the settings when we do a transfer (necessary because we
+	 * can't predict from which device it will be anyway)
+	 */
+	return spi_setup(priv->spi);
+}
+
+static void spi_mux_complete_cb(void *context)
+{
+	struct spi_mux_priv *priv = (struct spi_mux_priv *)context;
+	struct spi_controller *ctlr = spi_get_drvdata(priv->spi);
+	struct spi_message *m = ctlr->cur_msg;
+
+	m->complete = priv->child_msg_complete;
+	m->context = priv->child_msg_context;
+	m->spi = priv->child_msg_dev;
+	spi_finalize_current_message(ctlr);
+	mux_control_deselect(priv->mux);
+}
+
+static int spi_mux_transfer_one_message(struct spi_controller *ctlr,
+						struct spi_message *m)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(ctlr);
+	struct spi_device *spi = m->spi;
+	int ret;
+
+	ret = spi_mux_select(spi);
+	if (ret)
+		return ret;
+
+	/*
+	 * Replace the complete callback, context and spi_device with our own
+	 * pointers. Save originals
+	 */
+	priv->child_msg_complete = m->complete;
+	priv->child_msg_context = m->context;
+	priv->child_msg_dev = m->spi;
+
+	m->complete = spi_mux_complete_cb;
+	m->context = priv;
+	m->spi = priv->spi;
+
+	/* do the transfer */
+	return spi_async(priv->spi, m);
+}
+
+static int spi_mux_probe(struct spi_device *spi)
+{
+	struct spi_controller *ctlr;
+	struct spi_mux_priv *priv;
+	int ret;
+
+	ctlr = spi_alloc_master(&spi->dev, sizeof(*priv));
+	if (!ctlr)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, ctlr);
+	priv = spi_controller_get_devdata(ctlr);
+	priv->spi = spi;
+
+	priv->mux = devm_mux_control_get(&spi->dev, NULL);
+	if (IS_ERR(priv->mux)) {
+		ret = PTR_ERR(priv->mux);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&spi->dev, "failed to get control-mux\n");
+		goto err_put_ctlr;
+	}
+
+	priv->current_cs = SPI_MUX_NO_CS;
+
+	/* supported modes are the same as our parent's */
+	ctlr->mode_bits = spi->controller->mode_bits;
+	ctlr->flags = spi->controller->flags;
+	ctlr->transfer_one_message = spi_mux_transfer_one_message;
+	ctlr->setup = spi_mux_setup;
+	ctlr->num_chipselect = mux_control_states(priv->mux);
+	ctlr->bus_num = -1;
+	ctlr->dev.of_node = spi->dev.of_node;
+
+	ret = devm_spi_register_controller(&spi->dev, ctlr);
+	if (ret)
+		goto err_put_ctlr;
+
+	return 0;
+
+err_put_ctlr:
+	spi_controller_put(ctlr);
+
+	return ret;
+}
+
+static const struct of_device_id spi_mux_of_match[] = {
+	{ .compatible = "spi-mux" },
+	{ }
+};
+
+static struct spi_driver spi_mux_driver = {
+	.probe  = spi_mux_probe,
+	.driver = {
+		.name   = "spi-mux",
+		.of_match_table = spi_mux_of_match,
+	},
+};
+
+module_spi_driver(spi_mux_driver);
+
+MODULE_DESCRIPTION("SPI multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/2] spi: Add generic SPI multiplexer
  2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
@ 2020-02-04 11:10   ` Andy Shevchenko
  2020-02-12 23:58   ` Applied "spi: Add generic SPI multiplexer" to the spi tree Mark Brown
  2020-11-13 15:46   ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Nicolas Saenz Julienne
  2 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2020-02-04 11:10 UTC (permalink / raw)
  To: Chris Packham
  Cc: Mark Brown, Rob Herring, Mark Rutland, linux-spi, devicetree,
	Linux Kernel Mailing List

On Tue, Feb 4, 2020 at 5:28 AM Chris Packham
<chris.packham@alliedtelesis.co.nz> wrote:
>
> Add a SPI device driver that sits in-band and provides a SPI controller
> which supports chip selects via a mux-control. This enables extra SPI
> devices to be connected with limited native chip selects.
>

FWIW,
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

Mostly I did style review here.

> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>
> Notes:
>     Changes in v5:
>     - Drop redudnant lines, use IS_ERR() instead of PTR_ERR_OR_ZERO
>
>     Changes in v4:
>     - incorporate review feedback from Andy
>
>  drivers/spi/Kconfig   |  11 +++
>  drivers/spi/Makefile  |   1 +
>  drivers/spi/spi-mux.c | 187 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 199 insertions(+)
>  create mode 100644 drivers/spi/spi-mux.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 870f7797b56b..a4509000a291 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -881,6 +881,17 @@ config SPI_ZYNQMP_GQSPI
>  # Add new SPI master controllers in alphabetical order above this line
>  #
>
> +comment "SPI Multiplexer support"
> +
> +config SPI_MUX
> +       tristate "SPI multiplexer support"
> +       select MULTIPLEXER
> +       help
> +         This adds support for SPI multiplexers. Each SPI mux will be
> +         accessible as a SPI controller, the devices behind the mux will appear
> +         to be chip selects on this controller. It is still necessary to
> +         select one or more specific mux-controller drivers.
> +
>  #
>  # There are lots of SPI device types, with sensors and memory
>  # being probably the most widely used ones.
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index bb49c9e6d0a0..116409533727 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -9,6 +9,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG
>  # config declarations into driver model code
>  obj-$(CONFIG_SPI_MASTER)               += spi.o
>  obj-$(CONFIG_SPI_MEM)                  += spi-mem.o
> +obj-$(CONFIG_SPI_MUX)                  += spi-mux.o
>  obj-$(CONFIG_SPI_SPIDEV)               += spidev.o
>  obj-$(CONFIG_SPI_LOOPBACK_TEST)                += spi-loopback-test.o
>
> diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c
> new file mode 100644
> index 000000000000..4f94c9127fc1
> --- /dev/null
> +++ b/drivers/spi/spi-mux.c
> @@ -0,0 +1,187 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// General Purpose SPI multiplexer
> +
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mux/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/spi/spi.h>
> +
> +#define SPI_MUX_NO_CS  ((unsigned int)-1)
> +
> +/**
> + * DOC: Driver description
> + *
> + * This driver supports a MUX on an SPI bus. This can be useful when you need
> + * more chip selects than the hardware peripherals support, or than are
> + * available in a particular board setup.
> + *
> + * The driver will create an additional SPI controller. Devices added under the
> + * mux will be handled as 'chip selects' on this controller.
> + */
> +
> +/**
> + * struct spi_mux_priv - the basic spi_mux structure
> + * @spi:               pointer to the device struct attached to the parent
> + *                     spi controller
> + * @current_cs:                The current chip select set in the mux
> + * @child_msg_complete: The mux replaces the complete callback in the child's
> + *                     message to its own callback; this field is used by the
> + *                     driver to store the child's callback during a transfer
> + * @child_msg_context: Used to store the child's context to the callback
> + * @child_msg_dev:     Used to store the spi_device pointer to the child
> + * @mux:               mux_control structure used to provide chip selects for
> + *                     downstream spi devices
> + */
> +struct spi_mux_priv {
> +       struct spi_device       *spi;
> +       unsigned int            current_cs;
> +
> +       void                    (*child_msg_complete)(void *context);
> +       void                    *child_msg_context;
> +       struct spi_device       *child_msg_dev;
> +       struct mux_control      *mux;
> +};
> +
> +/* should not get called when the parent controller is doing a transfer */
> +static int spi_mux_select(struct spi_device *spi)
> +{
> +       struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
> +       int ret;
> +
> +       if (priv->current_cs == spi->chip_select)
> +               return 0;
> +
> +       dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n",
> +               spi->chip_select);
> +
> +       /* copy the child device's settings except for the cs */
> +       priv->spi->max_speed_hz = spi->max_speed_hz;
> +       priv->spi->mode = spi->mode;
> +       priv->spi->bits_per_word = spi->bits_per_word;
> +
> +       ret = mux_control_select(priv->mux, spi->chip_select);
> +       if (ret)
> +               return ret;
> +
> +       priv->current_cs = spi->chip_select;
> +
> +       return 0;
> +}
> +
> +static int spi_mux_setup(struct spi_device *spi)
> +{
> +       struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
> +
> +       /*
> +        * can be called multiple times, won't do a valid setup now but we will
> +        * change the settings when we do a transfer (necessary because we
> +        * can't predict from which device it will be anyway)
> +        */
> +       return spi_setup(priv->spi);
> +}
> +
> +static void spi_mux_complete_cb(void *context)
> +{
> +       struct spi_mux_priv *priv = (struct spi_mux_priv *)context;
> +       struct spi_controller *ctlr = spi_get_drvdata(priv->spi);
> +       struct spi_message *m = ctlr->cur_msg;
> +
> +       m->complete = priv->child_msg_complete;
> +       m->context = priv->child_msg_context;
> +       m->spi = priv->child_msg_dev;
> +       spi_finalize_current_message(ctlr);
> +       mux_control_deselect(priv->mux);
> +}
> +
> +static int spi_mux_transfer_one_message(struct spi_controller *ctlr,
> +                                               struct spi_message *m)
> +{
> +       struct spi_mux_priv *priv = spi_controller_get_devdata(ctlr);
> +       struct spi_device *spi = m->spi;
> +       int ret;
> +
> +       ret = spi_mux_select(spi);
> +       if (ret)
> +               return ret;
> +
> +       /*
> +        * Replace the complete callback, context and spi_device with our own
> +        * pointers. Save originals
> +        */
> +       priv->child_msg_complete = m->complete;
> +       priv->child_msg_context = m->context;
> +       priv->child_msg_dev = m->spi;
> +
> +       m->complete = spi_mux_complete_cb;
> +       m->context = priv;
> +       m->spi = priv->spi;
> +
> +       /* do the transfer */
> +       return spi_async(priv->spi, m);
> +}
> +
> +static int spi_mux_probe(struct spi_device *spi)
> +{
> +       struct spi_controller *ctlr;
> +       struct spi_mux_priv *priv;
> +       int ret;
> +
> +       ctlr = spi_alloc_master(&spi->dev, sizeof(*priv));
> +       if (!ctlr)
> +               return -ENOMEM;
> +
> +       spi_set_drvdata(spi, ctlr);
> +       priv = spi_controller_get_devdata(ctlr);
> +       priv->spi = spi;
> +
> +       priv->mux = devm_mux_control_get(&spi->dev, NULL);
> +       if (IS_ERR(priv->mux)) {
> +               ret = PTR_ERR(priv->mux);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&spi->dev, "failed to get control-mux\n");
> +               goto err_put_ctlr;
> +       }
> +
> +       priv->current_cs = SPI_MUX_NO_CS;
> +
> +       /* supported modes are the same as our parent's */
> +       ctlr->mode_bits = spi->controller->mode_bits;
> +       ctlr->flags = spi->controller->flags;
> +       ctlr->transfer_one_message = spi_mux_transfer_one_message;
> +       ctlr->setup = spi_mux_setup;
> +       ctlr->num_chipselect = mux_control_states(priv->mux);
> +       ctlr->bus_num = -1;
> +       ctlr->dev.of_node = spi->dev.of_node;
> +
> +       ret = devm_spi_register_controller(&spi->dev, ctlr);
> +       if (ret)
> +               goto err_put_ctlr;
> +
> +       return 0;
> +
> +err_put_ctlr:
> +       spi_controller_put(ctlr);
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id spi_mux_of_match[] = {
> +       { .compatible = "spi-mux" },
> +       { }
> +};
> +
> +static struct spi_driver spi_mux_driver = {
> +       .probe  = spi_mux_probe,
> +       .driver = {
> +               .name   = "spi-mux",
> +               .of_match_table = spi_mux_of_match,
> +       },
> +};
> +
> +module_spi_driver(spi_mux_driver);
> +
> +MODULE_DESCRIPTION("SPI multiplexer");
> +MODULE_LICENSE("GPL");
> --
> 2.25.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Applied "spi: Add generic SPI multiplexer" to the spi tree
  2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
  2020-02-04 11:10   ` Andy Shevchenko
@ 2020-02-12 23:58   ` Mark Brown
  2020-11-13 15:46   ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Nicolas Saenz Julienne
  2 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2020-02-12 23:58 UTC (permalink / raw)
  To: Chris Packham
  Cc: Andy Shevchenko, broonie, devicetree, linux-kernel, linux-spi,
	Mark Brown, mark.rutland, robh+dt

The patch

   spi: Add generic SPI multiplexer

has been applied to the spi tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.7

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From e9e40543ad5b38b848879768359fd13650529961 Mon Sep 17 00:00:00 2001
From: Chris Packham <chris.packham@alliedtelesis.co.nz>
Date: Tue, 4 Feb 2020 16:28:38 +1300
Subject: [PATCH] spi: Add generic SPI multiplexer

Add a SPI device driver that sits in-band and provides a SPI controller
which supports chip selects via a mux-control. This enables extra SPI
devices to be connected with limited native chip selects.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20200204032838.20739-3-chris.packham@alliedtelesis.co.nz
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/Kconfig   |  11 +++
 drivers/spi/Makefile  |   1 +
 drivers/spi/spi-mux.c | 187 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 drivers/spi/spi-mux.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 0434614d8201..887fefe87fd5 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -897,6 +897,17 @@ config SPI_ZYNQMP_GQSPI
 # Add new SPI master controllers in alphabetical order above this line
 #
 
+comment "SPI Multiplexer support"
+
+config SPI_MUX
+	tristate "SPI multiplexer support"
+	select MULTIPLEXER
+	help
+	  This adds support for SPI multiplexers. Each SPI mux will be
+	  accessible as a SPI controller, the devices behind the mux will appear
+	  to be chip selects on this controller. It is still necessary to
+	  select one or more specific mux-controller drivers.
+
 #
 # There are lots of SPI device types, with sensors and memory
 # being probably the most widely used ones.
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 9892bdfab15e..74db1f2c3299 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -9,6 +9,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG
 # config declarations into driver model code
 obj-$(CONFIG_SPI_MASTER)		+= spi.o
 obj-$(CONFIG_SPI_MEM)			+= spi-mem.o
+obj-$(CONFIG_SPI_MUX)			+= spi-mux.o
 obj-$(CONFIG_SPI_SPIDEV)		+= spidev.o
 obj-$(CONFIG_SPI_LOOPBACK_TEST)		+= spi-loopback-test.o
 
diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c
new file mode 100644
index 000000000000..4f94c9127fc1
--- /dev/null
+++ b/drivers/spi/spi-mux.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// General Purpose SPI multiplexer
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mux/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#define SPI_MUX_NO_CS	((unsigned int)-1)
+
+/**
+ * DOC: Driver description
+ *
+ * This driver supports a MUX on an SPI bus. This can be useful when you need
+ * more chip selects than the hardware peripherals support, or than are
+ * available in a particular board setup.
+ *
+ * The driver will create an additional SPI controller. Devices added under the
+ * mux will be handled as 'chip selects' on this controller.
+ */
+
+/**
+ * struct spi_mux_priv - the basic spi_mux structure
+ * @spi:		pointer to the device struct attached to the parent
+ *			spi controller
+ * @current_cs:		The current chip select set in the mux
+ * @child_msg_complete: The mux replaces the complete callback in the child's
+ *			message to its own callback; this field is used by the
+ *			driver to store the child's callback during a transfer
+ * @child_msg_context:	Used to store the child's context to the callback
+ * @child_msg_dev:	Used to store the spi_device pointer to the child
+ * @mux:		mux_control structure used to provide chip selects for
+ *			downstream spi devices
+ */
+struct spi_mux_priv {
+	struct spi_device	*spi;
+	unsigned int		current_cs;
+
+	void			(*child_msg_complete)(void *context);
+	void			*child_msg_context;
+	struct spi_device	*child_msg_dev;
+	struct mux_control	*mux;
+};
+
+/* should not get called when the parent controller is doing a transfer */
+static int spi_mux_select(struct spi_device *spi)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
+	int ret;
+
+	if (priv->current_cs == spi->chip_select)
+		return 0;
+
+	dev_dbg(&priv->spi->dev, "setting up the mux for cs %d\n",
+		spi->chip_select);
+
+	/* copy the child device's settings except for the cs */
+	priv->spi->max_speed_hz = spi->max_speed_hz;
+	priv->spi->mode = spi->mode;
+	priv->spi->bits_per_word = spi->bits_per_word;
+
+	ret = mux_control_select(priv->mux, spi->chip_select);
+	if (ret)
+		return ret;
+
+	priv->current_cs = spi->chip_select;
+
+	return 0;
+}
+
+static int spi_mux_setup(struct spi_device *spi)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(spi->controller);
+
+	/*
+	 * can be called multiple times, won't do a valid setup now but we will
+	 * change the settings when we do a transfer (necessary because we
+	 * can't predict from which device it will be anyway)
+	 */
+	return spi_setup(priv->spi);
+}
+
+static void spi_mux_complete_cb(void *context)
+{
+	struct spi_mux_priv *priv = (struct spi_mux_priv *)context;
+	struct spi_controller *ctlr = spi_get_drvdata(priv->spi);
+	struct spi_message *m = ctlr->cur_msg;
+
+	m->complete = priv->child_msg_complete;
+	m->context = priv->child_msg_context;
+	m->spi = priv->child_msg_dev;
+	spi_finalize_current_message(ctlr);
+	mux_control_deselect(priv->mux);
+}
+
+static int spi_mux_transfer_one_message(struct spi_controller *ctlr,
+						struct spi_message *m)
+{
+	struct spi_mux_priv *priv = spi_controller_get_devdata(ctlr);
+	struct spi_device *spi = m->spi;
+	int ret;
+
+	ret = spi_mux_select(spi);
+	if (ret)
+		return ret;
+
+	/*
+	 * Replace the complete callback, context and spi_device with our own
+	 * pointers. Save originals
+	 */
+	priv->child_msg_complete = m->complete;
+	priv->child_msg_context = m->context;
+	priv->child_msg_dev = m->spi;
+
+	m->complete = spi_mux_complete_cb;
+	m->context = priv;
+	m->spi = priv->spi;
+
+	/* do the transfer */
+	return spi_async(priv->spi, m);
+}
+
+static int spi_mux_probe(struct spi_device *spi)
+{
+	struct spi_controller *ctlr;
+	struct spi_mux_priv *priv;
+	int ret;
+
+	ctlr = spi_alloc_master(&spi->dev, sizeof(*priv));
+	if (!ctlr)
+		return -ENOMEM;
+
+	spi_set_drvdata(spi, ctlr);
+	priv = spi_controller_get_devdata(ctlr);
+	priv->spi = spi;
+
+	priv->mux = devm_mux_control_get(&spi->dev, NULL);
+	if (IS_ERR(priv->mux)) {
+		ret = PTR_ERR(priv->mux);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&spi->dev, "failed to get control-mux\n");
+		goto err_put_ctlr;
+	}
+
+	priv->current_cs = SPI_MUX_NO_CS;
+
+	/* supported modes are the same as our parent's */
+	ctlr->mode_bits = spi->controller->mode_bits;
+	ctlr->flags = spi->controller->flags;
+	ctlr->transfer_one_message = spi_mux_transfer_one_message;
+	ctlr->setup = spi_mux_setup;
+	ctlr->num_chipselect = mux_control_states(priv->mux);
+	ctlr->bus_num = -1;
+	ctlr->dev.of_node = spi->dev.of_node;
+
+	ret = devm_spi_register_controller(&spi->dev, ctlr);
+	if (ret)
+		goto err_put_ctlr;
+
+	return 0;
+
+err_put_ctlr:
+	spi_controller_put(ctlr);
+
+	return ret;
+}
+
+static const struct of_device_id spi_mux_of_match[] = {
+	{ .compatible = "spi-mux" },
+	{ }
+};
+
+static struct spi_driver spi_mux_driver = {
+	.probe  = spi_mux_probe,
+	.driver = {
+		.name   = "spi-mux",
+		.of_match_table = spi_mux_of_match,
+	},
+};
+
+module_spi_driver(spi_mux_driver);
+
+MODULE_DESCRIPTION("SPI multiplexer");
+MODULE_LICENSE("GPL");
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Applied "dt-bindings: spi: Document binding for generic SPI multiplexer" to the spi tree
  2020-02-04  3:28 ` [PATCH v5 1/2] dt-bindings: spi: Document binding for generic SPI multiplexer Chris Packham
@ 2020-02-12 23:58   ` Mark Brown
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2020-02-12 23:58 UTC (permalink / raw)
  To: Chris Packham
  Cc: Andy Shevchenko, broonie, devicetree, linux-kernel, linux-spi,
	Mark Brown, mark.rutland, robh+dt

The patch

   dt-bindings: spi: Document binding for generic SPI multiplexer

has been applied to the spi tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-5.7

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From d548ed71cb8862c96a1a8d17861bb5dabd1e2299 Mon Sep 17 00:00:00 2001
From: Chris Packham <chris.packham@alliedtelesis.co.nz>
Date: Tue, 4 Feb 2020 16:28:37 +1300
Subject: [PATCH] dt-bindings: spi: Document binding for generic SPI
 multiplexer

Add binding documentation for the spi-mux driver. This allows a generic
multiplexer to be used to provide access to multiple SPI devices.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20200204032838.20739-2-chris.packham@alliedtelesis.co.nz
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 .../devicetree/bindings/spi/spi-mux.yaml      | 89 +++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux.yaml

diff --git a/Documentation/devicetree/bindings/spi/spi-mux.yaml b/Documentation/devicetree/bindings/spi/spi-mux.yaml
new file mode 100644
index 000000000000..0ae692dc28b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-mux.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/spi-mux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic SPI Multiplexer
+
+description: |
+  This binding describes a SPI bus multiplexer to route the SPI chip select
+  signals. This can be used when you need more devices than the SPI controller
+  has chip selects available. An example setup is shown in ASCII art; the actual
+  setting of the multiplexer to a channel needs to be done by a specific SPI mux
+  driver.
+
+        MOSI /--------------------------------+--------+--------+--------\
+        MISO |/------------------------------+|-------+|-------+|-------\|
+         SCL ||/----------------------------+||------+||------+||------\||
+             |||                            |||      |||      |||      |||
+      +------------+                        |||      |||      |||      |||
+      | SoC  |||   |                      +-+++-+  +-+++-+  +-+++-+  +-+++-+
+      |      |||   |                      | dev |  | dev |  | dev |  | dev |
+      |   +--+++-+ | CS-X  +------+\      +--+--+  +--+--+  +--+--+  +--+--+
+      |   | SPI  +-|-------+ Mux  |\\   CS-0 |        |        |        |
+      |   +------+ |       +--+---+\\\-------/   CS-1 |        |        |
+      |            |          |    \\\----------------/   CS-2 |        |
+      |   +------+ |          |     \\-------------------------/   CS-3 |
+      |   | ?    +-|----------/      \----------------------------------/
+      |   +------+ |
+      +------------+
+
+allOf:
+  - $ref: "/schemas/spi/spi-controller.yaml#"
+
+maintainers:
+  - Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+properties:
+  compatible:
+    const: spi-mux
+
+  mux-controls:
+    maxItems: 1
+
+required:
+   - compatible
+   - reg
+   - spi-max-frequency
+   - mux-controls
+
+examples:
+   - |
+     #include <dt-bindings/gpio/gpio.h>
+     mux: mux-controller {
+       compatible = "gpio-mux";
+       #mux-control-cells = <0>;
+
+       mux-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+     };
+
+     spi {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       spi@0 {
+         compatible = "spi-mux";
+         reg = <0>;
+         #address-cells = <1>;
+         #size-cells = <0>;
+         spi-max-frequency = <100000000>;
+
+         mux-controls = <&mux>;
+
+         spi-flash@0 {
+           compatible = "jedec,spi-nor";
+           reg = <0>;
+           #address-cells = <1>;
+           #size-cells = <0>;
+           spi-max-frequency = <40000000>;
+         };
+
+         spi-device@1 {
+           compatible = "lineartechnology,ltc2488";
+           reg = <1>;
+           #address-cells = <1>;
+           #size-cells = <0>;
+           spi-max-frequency = <10000000>;
+         };
+       };
+     };
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/2] spi: Add generic SPI multiplexer
  2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
  2020-02-04 11:10   ` Andy Shevchenko
  2020-02-12 23:58   ` Applied "spi: Add generic SPI multiplexer" to the spi tree Mark Brown
@ 2020-11-13 15:46   ` Nicolas Saenz Julienne
  2020-11-17  0:08     ` Chris Packham
  2 siblings, 1 reply; 9+ messages in thread
From: Nicolas Saenz Julienne @ 2020-11-13 15:46 UTC (permalink / raw)
  To: chris.packham, linux-kernel
  Cc: andy.shevchenko, broonie, devicetree, linux-spi, mark.rutland, robh+dt

Upon registering spi-mux's devices through spi_add_device() the kernel gets
stuck waiting for the 'spi_add_lock' mutex to be released. The mutex happens to
be held by spi-mux's parent SPI bus, which unluckily, is waiting for spi-mux's
probe to finish before releasing it.

I might aswell be doing something wrong. But so far I trust my DT
implementation:

	&spi {
		status = "okay";
		pinctrl-names = "default";
		pinctrl-0 = <&spi0_gpio7>;

		spi@0 {
			compatible = "spi-mux";
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;
			spi-max-frequency = <100000000>;

			mux-controls = <&gpio_mux>;

			w5500@0 {
				compatible = "wiznet,w5500";
				reg = <0>;
				pinctrl-names = "default";
				pinctrl-0 = <&eth1_pins>;
				interrupt-parent = <&gpio>;
				interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
				spi-max-frequency = <30000000>;
			};

			spi-flash@1 {
				compatible = "jedec,spi-nor";
				reg = <1>;
				#address-cells = <1>;
				#size-cells = <0>;
				spi-max-frequency = <16000000>;
			};
		};
	};

Regards,
Nicolas

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/2] spi: Add generic SPI multiplexer
  2020-11-13 15:46   ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Nicolas Saenz Julienne
@ 2020-11-17  0:08     ` Chris Packham
  2020-11-20 16:18       ` Nicolas Saenz Julienne
  0 siblings, 1 reply; 9+ messages in thread
From: Chris Packham @ 2020-11-17  0:08 UTC (permalink / raw)
  To: Nicolas Saenz Julienne, linux-kernel
  Cc: andy.shevchenko, broonie, devicetree, linux-spi, mark.rutland, robh+dt


On 14/11/20 4:46 am, Nicolas Saenz Julienne wrote:
> Upon registering spi-mux's devices through spi_add_device() the kernel gets
> stuck waiting for the 'spi_add_lock' mutex to be released. The mutex happens to
> be held by spi-mux's parent SPI bus, which unluckily, is waiting for spi-mux's
> probe to finish before releasing it.

I just re-tested my system with v5.10.0-rc4 and didn't see any problem. 
My dts is pretty similar to yours the only obvious thing missing is 
`mux-control-names = "spi";` and I also set `#size-cells = <1>;` (let me 
know if you want me to post the whole thing).

It might be dependent on the host spi controller. The re-test I just did 
was on a board using the spi-orion.c driver and I tested my original 
change on a board using spi-bcm-qspi.c (I haven't got the board handy 
right now but I could go and find one if necessary).

> I might aswell be doing something wrong. But so far I trust my DT
> implementation:
>
> 	&spi {
> 		status = "okay";
> 		pinctrl-names = "default";
> 		pinctrl-0 = <&spi0_gpio7>;
>
> 		spi@0 {
> 			compatible = "spi-mux";
> 			reg = <0>;
> 			#address-cells = <1>;
> 			#size-cells = <0>;
> 			spi-max-frequency = <100000000>;
>
> 			mux-controls = <&gpio_mux>;
>
> 			w5500@0 {
> 				compatible = "wiznet,w5500";
> 				reg = <0>;
> 				pinctrl-names = "default";
> 				pinctrl-0 = <&eth1_pins>;
> 				interrupt-parent = <&gpio>;
> 				interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
> 				spi-max-frequency = <30000000>;
> 			};
>
> 			spi-flash@1 {
> 				compatible = "jedec,spi-nor";
> 				reg = <1>;
> 				#address-cells = <1>;
> 				#size-cells = <0>;
> 				spi-max-frequency = <16000000>;
> 			};
> 		};
> 	};
>
> Regards,
> Nicolas

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v5 2/2] spi: Add generic SPI multiplexer
  2020-11-17  0:08     ` Chris Packham
@ 2020-11-20 16:18       ` Nicolas Saenz Julienne
  0 siblings, 0 replies; 9+ messages in thread
From: Nicolas Saenz Julienne @ 2020-11-20 16:18 UTC (permalink / raw)
  To: Chris Packham, linux-kernel
  Cc: andy.shevchenko, broonie, devicetree, linux-spi, mark.rutland, robh+dt

[-- Attachment #1: Type: text/plain, Size: 1057 bytes --]

On Tue, 2020-11-17 at 00:08 +0000, Chris Packham wrote:
> On 14/11/20 4:46 am, Nicolas Saenz Julienne wrote:
> > Upon registering spi-mux's devices through spi_add_device() the kernel gets
> > stuck waiting for the 'spi_add_lock' mutex to be released. The mutex happens to
> > be held by spi-mux's parent SPI bus, which unluckily, is waiting for spi-mux's
> > probe to finish before releasing it.
> 
> I just re-tested my system with v5.10.0-rc4 and didn't see any problem. 
> My dts is pretty similar to yours the only obvious thing missing is 
> `mux-control-names = "spi";` and I also set `#size-cells = <1>;` (let me 
> know if you want me to post the whole thing).
> 
> It might be dependent on the host spi controller. The re-test I just did 
> was on a board using the spi-orion.c driver and I tested my original 
> change on a board using spi-bcm-qspi.c (I haven't got the board handy 
> right now but I could go and find one if necessary).

Found the issue, something silly on my side. Sorry for the noise.

Regards,
Nicolas


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-11-20 16:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-04  3:28 [PATCH v5 0/2] SPI bus multiplexing Chris Packham
2020-02-04  3:28 ` [PATCH v5 1/2] dt-bindings: spi: Document binding for generic SPI multiplexer Chris Packham
2020-02-12 23:58   ` Applied "dt-bindings: spi: Document binding for generic SPI multiplexer" to the spi tree Mark Brown
2020-02-04  3:28 ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Chris Packham
2020-02-04 11:10   ` Andy Shevchenko
2020-02-12 23:58   ` Applied "spi: Add generic SPI multiplexer" to the spi tree Mark Brown
2020-11-13 15:46   ` [PATCH v5 2/2] spi: Add generic SPI multiplexer Nicolas Saenz Julienne
2020-11-17  0:08     ` Chris Packham
2020-11-20 16:18       ` Nicolas Saenz Julienne

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).