diff mbox series

[v4] spi: add Renesas RPC-IF driver

Message ID 1ece0e6c-71af-f0f1-709e-571f4b0b4853@cogentembedded.com (mailing list archive)
State Mainlined
Commit eb8d6d464a27850498dced21a8450e85d4a02009
Delegated to: Geert Uytterhoeven
Headers show
Series [v4] spi: add Renesas RPC-IF driver | expand

Commit Message

Sergei Shtylyov June 13, 2020, 7:18 p.m. UTC
Add the SPI driver for the Renesas RPC-IF.  It's the "front end" driver
using the "back end" APIs in the main driver to talk to the real hardware.
We only implement the 'spi-mem' interface -- there's no need to implement
the usual SPI driver methods...

Based on the original patch by Mason Yang <masonccyang@mxic.com.tw>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 4:
- refreshed the patch.

Changes in version 3:
- properly set up the direction field in rpcif_spi_mem_prepare() when there's
  no data;
- renamed rpcif_io_xfer() to rpcif_manual_xfer();
- extended Cogent Embedded's copyright to this year.

Changes in version 2:
- removed unneeded transfer_one_message() method and the related code;
- fixed up #include's as we switch from MFD to the memory core driver;
- removed unneeded #include <linux/pm_runtime.h>;
- removed 'struct rpcif_spi', replacing it with 'struct rpcif' everywhere;
- added spi_mem_default_supports_op() call to rpcif_spi_mem_supports_op();
- added rpcif_sw_init() call in rpcif_spi_probe();
- set SPI_CONTROLLER_HALF_DUPLEX flag in rpcif_spi_probe();
- added a new variable 'struct device *parent' and renamed the 'ret' variable
  to 'error' in rpcif_spi_probe();
- changed the order of calls in the error path of rpcif_spi_probe() and in
  rpcif_spi_remove();
- changed from 'select' to 'depends on' the main driver Kconfig symbol,
  removed 'depends on ARCH_RENESAS || COMPILE TEST';
- renamed rpcif_spi_mem_set_prep_op_cfg() to rpcif_spi_mem_prepare(), updated
  the rpcif_io_xfer() call there to match the RPC-IF core driver, changed
  'rpc_op' there from parameter into the local variable;
- changed the platform driver's name to "rpc-if-spi";
- fixed whitespace in rpcif_spi_mem_exec_op()'s prototype; 
- beautified the whitespace in the initializers of 'rpcif_spi_mem_ops' and
  'rpcif_spi_driver';
- changed the heading comment from /* */ to //;
- updated the patch description with more details.

 drivers/spi/Kconfig      |    6 +
 drivers/spi/Makefile     |    1 
 drivers/spi/spi-rpc-if.c |  216 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 223 insertions(+)

Comments

Mark Brown June 15, 2020, 11:41 p.m. UTC | #1
On Sat, 13 Jun 2020 22:18:34 +0300, Sergei Shtylyov wrote:
> Add the SPI driver for the Renesas RPC-IF.  It's the "front end" driver
> using the "back end" APIs in the main driver to talk to the real hardware.
> We only implement the 'spi-mem' interface -- there's no need to implement
> the usual SPI driver methods...
> 
> Based on the original patch by Mason Yang <masonccyang@mxic.com.tw>.

Applied to

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

Thanks!

[1/1] spi: add Renesas RPC-IF driver
      commit: eb8d6d464a27850498dced21a8450e85d4a02009

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
Sergei Shtylyov June 16, 2020, 8:24 a.m. UTC | #2
On 16.06.2020 2:41, Mark Brown wrote:

>> Add the SPI driver for the Renesas RPC-IF.  It's the "front end" driver
>> using the "back end" APIs in the main driver to talk to the real hardware.
>> We only implement the 'spi-mem' interface -- there's no need to implement
>> the usual SPI driver methods...
>>
>> Based on the original patch by Mason Yang <masonccyang@mxic.com.tw>.
> 
> Applied to
> 
>     https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
> 
> Thanks!
> 
> [1/1] spi: add Renesas RPC-IF driver
>        commit: eb8d6d464a27850498dced21a8450e85d4a02009
> 
> 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 realize that the SPI driver won't build alone, w/o the drivers/memory/ 
core driver merged, right?

> 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

MBR, Sergei
Mark Brown June 16, 2020, 8:38 a.m. UTC | #3
On Tue, Jun 16, 2020 at 11:24:55AM +0300, Sergei Shtylyov wrote:
> On 16.06.2020 2:41, Mark Brown wrote:

> > 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 realize that the SPI driver won't build alone, w/o the
> drivers/memory/ core driver merged, right?

Those aren't merged yet?  There was no mention of any dependencies in
the patch, no feedback for months on the patch and I've not seen any
ongoing discussion.
Sergei Shtylyov June 16, 2020, 8:48 a.m. UTC | #4
On 16.06.2020 11:38, Mark Brown wrote:
> On Tue, Jun 16, 2020 at 11:24:55AM +0300, Sergei Shtylyov wrote:
>> On 16.06.2020 2:41, Mark Brown wrote:
> 
>>> 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 realize that the SPI driver won't build alone, w/o the
>> drivers/memory/ core driver merged, right?
> 
> Those aren't merged yet?  There was no mention of any dependencies in

    No. I thought we had an agreement about this (core) driver going in thru
the SPI tree (because there's no repo for drivers/memory/ anyway). Looking
at the DT patchwork:

https://patchwork.ozlabs.org/project/devicetree-bindings/patch/4becbd3b-c9b9-070a-5771-48cade6651e5@cogentembedded.com/

the DT bindings still need to be reviewed -- but by whom? The "Checks"
section indicates that they did pass the DT checks this time around).
Rob?

> the patch, no feedback for months on the patch and I've not seen any
> ongoing discussion.

    Everybody seems to be in a silent agreement. :-)

MBR, Sergei
Sergei Shtylyov June 16, 2020, 9:26 a.m. UTC | #5
On 16.06.2020 11:38, Mark Brown wrote:
> On Tue, Jun 16, 2020 at 11:24:55AM +0300, Sergei Shtylyov wrote:
>> On 16.06.2020 2:41, Mark Brown wrote:
> 
>>> 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 realize that the SPI driver won't build alone, w/o the
>> drivers/memory/ core driver merged, right?
> 
> Those aren't merged yet?  There was no mention of any dependencies in
> the patch, no feedback for months on the patch and I've not seen any
> ongoing discussion.

    I thought the below passage was speaking for itself:

<<
It's the "front end" driver using the "back end" APIs in the main driver to 
talk to the real hardware."
 >>

    Sorry for not being clear enough...

MBR, Sergei
Mark Brown June 16, 2020, 9:34 a.m. UTC | #6
On Tue, Jun 16, 2020 at 11:48:36AM +0300, Sergei Shtylyov wrote:
> On 16.06.2020 11:38, Mark Brown wrote:
> > On Tue, Jun 16, 2020 at 11:24:55AM +0300, Sergei Shtylyov wrote:

> > >     You realize that the SPI driver won't build alone, w/o the
> > > drivers/memory/ core driver merged, right?

> > Those aren't merged yet?  There was no mention of any dependencies in

>    No. I thought we had an agreement about this (core) driver going in thru
> the SPI tree (because there's no repo for drivers/memory/ anyway). Looking
> at the DT patchwork:

> https://patchwork.ozlabs.org/project/devicetree-bindings/patch/4becbd3b-c9b9-070a-5771-48cade6651e5@cogentembedded.com/

Nobody appears to have ever actually sent me these to me so they're not
getting applied...

> the DT bindings still need to be reviewed -- but by whom? The "Checks"
> section indicates that they did pass the DT checks this time around).
> Rob?

There's a backlog on YAML binding reviews, I'm sure Rob will get to it
in time.

> > the patch, no feedback for months on the patch and I've not seen any
> > ongoing discussion.

>    Everybody seems to be in a silent agreement. :-)

Or lost track of things given how long this has been going on :(
Mark Brown June 16, 2020, 9:34 a.m. UTC | #7
On Tue, Jun 16, 2020 at 12:26:46PM +0300, Sergei Shtylyov wrote:
> On 16.06.2020 11:38, Mark Brown wrote:

> > Those aren't merged yet?  There was no mention of any dependencies in
> > the patch, no feedback for months on the patch and I've not seen any
> > ongoing discussion.

>    I thought the below passage was speaking for itself:

> <<
> It's the "front end" driver using the "back end" APIs in the main driver to
> talk to the real hardware."
> >>

>    Sorry for not being clear enough...

That tells me that there's a back end driver, it doesn't tell me that
the back end driver isn't merged yet.
Sergei Shtylyov June 16, 2020, 12:55 p.m. UTC | #8
On 16.06.2020 12:34, Mark Brown wrote:

>>>>      You realize that the SPI driver won't build alone, w/o the
>>>> drivers/memory/ core driver merged, right?
> 
>>> Those aren't merged yet?  There was no mention of any dependencies in
> 
>>     No. I thought we had an agreement about this (core) driver going in thru
>> the SPI tree (because there's no repo for drivers/memory/ anyway). Looking
>> at the DT patchwork:
> 
>> https://patchwork.ozlabs.org/project/devicetree-bindings/patch/4becbd3b-c9b9-070a-5771-48cade6651e5@cogentembedded.com/
> 
> Nobody appears to have ever actually sent me these to me so they're not
> getting applied...

    Ah, you need to be explicitly CCed! I seem to be relying on the patchwork 
too much... OK, I'm going for v5 of the core driver/bindings later today (with 
r8a77970 added to compatibles -- I tested it yesterday).

>> the DT bindings still need to be reviewed -- but by whom? The "Checks"
>> section indicates that they did pass the DT checks this time around).
>> Rob?
> 
> There's a backlog on YAML binding reviews, I'm sure Rob will get to it
> in time.

>>> the patch, no feedback for months on the patch and I've not seen any
>>> ongoing discussion.
> 
>>     Everybody seems to be in a silent agreement. :-)
> 
> Or lost track of things given how long this has been going on :(

    Sorry, there was a lat of hardware issues slowing me down. :-(

MBR, Sergei
Mark Brown June 16, 2020, 2:32 p.m. UTC | #9
On Tue, Jun 16, 2020 at 03:55:24PM +0300, Sergei Shtylyov wrote:
> On 16.06.2020 12:34, Mark Brown wrote:

> > Nobody appears to have ever actually sent me these to me so they're not
> > getting applied...

>    Ah, you need to be explicitly CCed! I seem to be relying on the patchwork
> too much... OK, I'm going for v5 of the core driver/bindings later today
> (with r8a77970 added to compatibles -- I tested it yesterday).

Yeah, I won't see anything that's only sent to the list.  I don't use
patchwork at all any more, even in my scripting.

> > >     Everybody seems to be in a silent agreement. :-)

> > Or lost track of things given how long this has been going on :(

>    Sorry, there was a lat of hardware issues slowing me down. :-(

Sorry, didn't mean to get at you there - this has been going on for a
long time before you started working on it!
diff mbox series

Patch

Index: spi/drivers/spi/Kconfig
===================================================================
--- spi.orig/drivers/spi/Kconfig
+++ spi/drivers/spi/Kconfig
@@ -605,6 +605,12 @@  config SPI_RB4XX
 	help
 	  SPI controller driver for the Mikrotik RB4xx series boards.
 
+config SPI_RPCIF
+	tristate "Renesas RPC-IF SPI driver"
+	depends on RENESAS_RPCIF
+	help
+	  SPI driver for Renesas R-Car Gen3 RPC-IF.
+
 config SPI_RSPI
 	tristate "Renesas RSPI/QSPI controller"
 	depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
Index: spi/drivers/spi/Makefile
===================================================================
--- spi.orig/drivers/spi/Makefile
+++ spi/drivers/spi/Makefile
@@ -92,6 +92,7 @@  obj-$(CONFIG_SPI_QCOM_QSPI)		+= spi-qcom
 obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
 obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
+obj-$(CONFIG_SPI_RPCIF)			+= spi-rpc-if.o
 obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
 obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
 spi-s3c24xx-hw-y			:= spi-s3c24xx.o
Index: spi/drivers/spi/spi-rpc-if.c
===================================================================
--- /dev/null
+++ spi/drivers/spi/spi-rpc-if.c
@@ -0,0 +1,216 @@ 
+// SPDX-License-Identifier: GPL-2.0
+//
+// RPC-IF SPI/QSPI/Octa driver
+//
+// Copyright (C) 2018 ~ 2019 Renesas Solutions Corp.
+// Copyright (C) 2019 Macronix International Co., Ltd.
+// Copyright (C) 2019 - 2020 Cogent Embedded, Inc.
+//
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+#include <memory/renesas-rpc-if.h>
+
+#include <asm/unaligned.h>
+
+static void rpcif_spi_mem_prepare(struct spi_device *spi_dev,
+				  const struct spi_mem_op *spi_op,
+				  u64 *offs, size_t *len)
+{
+	struct rpcif *rpc = spi_controller_get_devdata(spi_dev->controller);
+	struct rpcif_op rpc_op = { };
+
+	rpc_op.cmd.opcode = spi_op->cmd.opcode;
+	rpc_op.cmd.buswidth = spi_op->cmd.buswidth;
+
+	if (spi_op->addr.nbytes) {
+		rpc_op.addr.buswidth = spi_op->addr.buswidth;
+		rpc_op.addr.nbytes = spi_op->addr.nbytes;
+		rpc_op.addr.val = spi_op->addr.val;
+	}
+
+	if (spi_op->dummy.nbytes) {
+		rpc_op.dummy.buswidth = spi_op->dummy.buswidth;
+		rpc_op.dummy.ncycles  = spi_op->dummy.nbytes * 8 /
+					spi_op->dummy.buswidth;
+	}
+
+	if (spi_op->data.nbytes || (offs && len)) {
+		rpc_op.data.buswidth = spi_op->data.buswidth;
+		rpc_op.data.nbytes = spi_op->data.nbytes;
+		switch (spi_op->data.dir) {
+		case SPI_MEM_DATA_IN:
+			rpc_op.data.dir = RPCIF_DATA_IN;
+			rpc_op.data.buf.in = spi_op->data.buf.in;
+			break;
+		case SPI_MEM_DATA_OUT:
+			rpc_op.data.dir = RPCIF_DATA_OUT;
+			rpc_op.data.buf.out = spi_op->data.buf.out;
+			break;
+		case SPI_MEM_NO_DATA:
+			rpc_op.data.dir = RPCIF_NO_DATA;
+			break;
+		}
+	} else	{
+		rpc_op.data.dir = RPCIF_NO_DATA;
+	}
+
+	rpcif_prepare(rpc, &rpc_op, offs, len);
+}
+
+static bool rpcif_spi_mem_supports_op(struct spi_mem *mem,
+				      const struct spi_mem_op *op)
+{
+	if (!spi_mem_default_supports_op(mem, op))
+		return false;
+
+	if (op->data.buswidth > 4 || op->addr.buswidth > 4 ||
+	    op->dummy.buswidth > 4 || op->cmd.buswidth > 4 ||
+	    op->addr.nbytes > 4)
+		return false;
+
+	return true;
+}
+
+static ssize_t rpcif_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
+					 u64 offs, size_t len, void *buf)
+{
+	struct rpcif *rpc =
+		spi_controller_get_devdata(desc->mem->spi->controller);
+
+	if (offs + desc->info.offset + len > U32_MAX)
+		return -EINVAL;
+
+	rpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);
+
+	return rpcif_dirmap_read(rpc, offs, len, buf);
+}
+
+static int rpcif_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+	struct rpcif *rpc =
+		spi_controller_get_devdata(desc->mem->spi->controller);
+
+	if (desc->info.offset + desc->info.length > U32_MAX)
+		return -ENOTSUPP;
+
+	if (!rpcif_spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
+		return -ENOTSUPP;
+
+	if (!rpc->dirmap && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
+		return -ENOTSUPP;
+
+	if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+static int rpcif_spi_mem_exec_op(struct spi_mem *mem,
+				 const struct spi_mem_op *op)
+{
+	struct rpcif *rpc =
+		spi_controller_get_devdata(mem->spi->controller);
+
+	rpcif_spi_mem_prepare(mem->spi, op, NULL, NULL);
+
+	return rpcif_manual_xfer(rpc);
+}
+
+static const struct spi_controller_mem_ops rpcif_spi_mem_ops = {
+	.supports_op	= rpcif_spi_mem_supports_op,
+	.exec_op	= rpcif_spi_mem_exec_op,
+	.dirmap_create	= rpcif_spi_mem_dirmap_create,
+	.dirmap_read	= rpcif_spi_mem_dirmap_read,
+};
+
+static int rpcif_spi_probe(struct platform_device *pdev)
+{
+	struct device *parent = pdev->dev.parent;
+	struct spi_controller *ctlr;
+	struct rpcif *rpc;
+	int error;
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*rpc));
+	if (!ctlr)
+		return -ENOMEM;
+
+	rpc = spi_controller_get_devdata(ctlr);
+	rpcif_sw_init(rpc, parent);
+
+	platform_set_drvdata(pdev, ctlr);
+
+	ctlr->dev.of_node = parent->of_node;
+
+	rpcif_enable_rpm(rpc);
+
+	ctlr->num_chipselect = 1;
+	ctlr->mem_ops = &rpcif_spi_mem_ops;
+
+	ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_QUAD | SPI_RX_QUAD;
+	ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
+
+	rpcif_hw_init(rpc, false);
+
+	error = spi_register_controller(ctlr);
+	if (error) {
+		dev_err(&pdev->dev, "spi_register_controller failed\n");
+		goto err_put_ctlr;
+	}
+	return 0;
+
+err_put_ctlr:
+	rpcif_disable_rpm(rpc);
+	spi_controller_put(ctlr);
+
+	return error;
+}
+
+static int rpcif_spi_remove(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr = platform_get_drvdata(pdev);
+	struct rpcif *rpc = spi_controller_get_devdata(ctlr);
+
+	spi_unregister_controller(ctlr);
+	rpcif_disable_rpm(rpc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rpcif_spi_suspend(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	return spi_controller_suspend(ctlr);
+}
+
+static int rpcif_spi_resume(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+
+	return spi_controller_resume(ctlr);
+}
+
+static SIMPLE_DEV_PM_OPS(rpcif_spi_pm_ops, rpcif_spi_suspend, rpcif_spi_resume);
+#define DEV_PM_OPS	(&rpcif_spi_pm_ops)
+#else
+#define DEV_PM_OPS	NULL
+#endif
+
+static struct platform_driver rpcif_spi_driver = {
+	.probe	= rpcif_spi_probe,
+	.remove	= rpcif_spi_remove,
+	.driver = {
+		.name	= "rpc-if-spi",
+		.pm	= DEV_PM_OPS,
+	},
+};
+module_platform_driver(rpcif_spi_driver);
+
+MODULE_DESCRIPTION("Renesas RPC-IF SPI driver");
+MODULE_LICENSE("GPL v2");