Commit 080ffb4b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i3c updates from Alexandre Belloni:
 "New driver:
   - Analog Devices I3C Controller

  Subsystem:
   - fix big-endian FIFO transfers
   - fix default I2C adapter timeout value

  Drivers:
   - dw: shutdown support
   - mipi-i3c-hci: Intel Wildcat Lake-U support, IOMMU support
   - renesas: RZ/V2H(P) and RZ/V2N support"

* tag 'i3c/for-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (22 commits)
  i3c: fix big-endian FIFO transfers
  i3c: master: adi: fix number of bytes written to fifo
  i3c: Remove superfluous FIXME
  i3c: master: adi: fix header location
  i3c: dw: Add shutdown support to dw_i3c_master driver
  i3c: renesas: Simplify return statement in 'renesas_i3c_daa'
  dt-bindings: i3c: renesas,i3c: Add RZ/V2H(P) and RZ/V2N support
  i3c: master: svc: Recycle unused IBI slot
  i3c: master: svc: Use manual response for IBI events
  i3c: master: Add driver for Analog Devices I3C Controller IP
  dt-bindings: i3c: Add adi-i3c-master
  i3c: Fix default I2C adapter timeout value
  i3c: mipi-i3c-hci: Convert remaining DBG() prints to dev_dbg()
  i3c: mipi-i3c-hci: Remove function enter DBG() printouts
  i3c: mipi-i3c-hci: Uniform ring number printouts
  i3c: mipi-i3c-hci: Remove nonexistent ring interrupt
  i3c: mipi-i3c-hci: Change interrupt status prints to dev_dbg()
  i3c: mipi-i3c-hci: Use own DMA bounce buffer management for I2C transfers
  i3c: mipi-i3c-hci: Use physical device pointer with DMA API
  i3c: mipi-i3c-hci: Use core helpers for DMA mapping and bounce buffering
  ...
parents cf8da116 d6ddd9be
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/i3c/adi,i3c-master.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Analog Devices I3C Controller

description:
  FPGA-based I3C controller designed to interface with I3C and I2C peripherals,
  implementing a subset of the I3C-basic specification. The IP core is tested
  on arm, microblaze, and arm64 architectures.

  https://analogdevicesinc.github.io/hdl/library/i3c_controller

maintainers:
  - Jorge Marques <jorge.marques@analog.com>

properties:
  compatible:
    const: adi,i3c-master-v1

  reg:
    maxItems: 1

  clocks:
    minItems: 1
    items:
      - description: The AXI interconnect clock, drives the register map.
      - description:
          The secondary clock, drives the internal logic asynchronously to the
          register map. The presence of this entry states that the IP Core was
          synthesized with a second clock input, and the absence of this entry
          indicates a topology where a single clock input drives all the
          internal logic.

  clock-names:
    minItems: 1
    items:
      - const: axi
      - const: i3c

  interrupts:
    maxItems: 1

required:
  - compatible
  - reg
  - clocks
  - clock-names
  - interrupts

allOf:
  - $ref: i3c.yaml#

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>

    i3c@44a00000 {
        compatible = "adi,i3c-master-v1";
        reg = <0x44a00000 0x1000>;
        interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&clkc 15>, <&clkc 15>;
        clock-names = "axi", "i3c";
        #address-cells = <3>;
        #size-cells = <0>;

        /* I3C and I2C devices */
    };
+11 −5
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/i3c/renesas,i3c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Renesas RZ/G3S and RZ/G3E I3C Bus Interface
title: Renesas I3C Bus Interface

maintainers:
  - Wolfram Sang <wsa+renesas@sang-engineering.com>
@@ -12,10 +12,16 @@ maintainers:

properties:
  compatible:
    items:
    oneOf:
      - items:
          - enum:
              - renesas,r9a08g045-i3c # RZ/G3S
              - renesas,r9a09g047-i3c # RZ/G3E
      - items:
          - enum:
              - renesas,r9a09g056-i3c # RZ/V2N
              - renesas,r9a09g057-i3c # RZ/V2H(P)
          - const: renesas,r9a09g047-i3c

  reg:
    maxItems: 1
+6 −0
Original line number Diff line number Diff line
@@ -11674,6 +11674,12 @@ S: Maintained
F:	Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c.yaml
F:	drivers/i3c/master/ast2600-i3c-master.c
I3C DRIVER FOR ANALOG DEVICES I3C CONTROLLER IP
M:	Jorge Marques <jorge.marques@analog.com>
S:	Maintained
F:	Documentation/devicetree/bindings/i3c/adi,i3c-master.yaml
F:	drivers/i3c/master/adi-i3c-master.c
I3C DRIVER FOR CADENCE I3C MASTER IP
M:	Przemysław Gaj <pgaj@cadence.com>
S:	Maintained
+10 −2
Original line number Diff line number Diff line
@@ -38,7 +38,11 @@ static inline void i3c_writel_fifo(void __iomem *addr, const void *buf,
		u32 tmp = 0;

		memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3);
		writel(tmp, addr);
		/*
		 * writesl() instead of writel() to keep FIFO
		 * byteorder on big-endian targets
		 */
		writesl(addr, &tmp, 1);
	}
}

@@ -55,7 +59,11 @@ static inline void i3c_readl_fifo(const void __iomem *addr, void *buf,
	if (nbytes & 3) {
		u32 tmp;

		tmp = readl(addr);
		/*
		 * readsl() instead of readl() to keep FIFO
		 * byteorder on big-endian targets
		 */
		readsl(addr, &tmp, 1);
		memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3);
	}
}
+75 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/atomic.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/kernel.h>
@@ -1727,6 +1728,79 @@ int i3c_master_do_daa(struct i3c_master_controller *master)
}
EXPORT_SYMBOL_GPL(i3c_master_do_daa);

/**
 * i3c_master_dma_map_single() - Map buffer for single DMA transfer
 * @dev: device object of a device doing DMA
 * @buf: destination/source buffer for DMA
 * @len: length of transfer
 * @force_bounce: true, force to use a bounce buffer,
 *                false, function will auto check is a bounce buffer required
 * @dir: DMA direction
 *
 * Map buffer for a DMA transfer and allocate a bounce buffer if required.
 *
 * Return: I3C DMA transfer descriptor or NULL in case of error.
 */
struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *buf,
	size_t len, bool force_bounce, enum dma_data_direction dir)
{
	struct i3c_dma *dma_xfer __free(kfree) = NULL;
	void *bounce __free(kfree) = NULL;
	void *dma_buf = buf;

	dma_xfer = kzalloc(sizeof(*dma_xfer), GFP_KERNEL);
	if (!dma_xfer)
		return NULL;

	dma_xfer->dev = dev;
	dma_xfer->buf = buf;
	dma_xfer->dir = dir;
	dma_xfer->len = len;
	dma_xfer->map_len = len;

	if (is_vmalloc_addr(buf))
		force_bounce = true;

	if (force_bounce) {
		dma_xfer->map_len = ALIGN(len, cache_line_size());
		if (dir == DMA_FROM_DEVICE)
			bounce = kzalloc(dma_xfer->map_len, GFP_KERNEL);
		else
			bounce = kmemdup(buf, dma_xfer->map_len, GFP_KERNEL);
		if (!bounce)
			return NULL;
		dma_buf = bounce;
	}

	dma_xfer->addr = dma_map_single(dev, dma_buf, dma_xfer->map_len, dir);
	if (dma_mapping_error(dev, dma_xfer->addr))
		return NULL;

	dma_xfer->bounce_buf = no_free_ptr(bounce);
	return no_free_ptr(dma_xfer);
}
EXPORT_SYMBOL_GPL(i3c_master_dma_map_single);

/**
 * i3c_master_dma_unmap_single() - Unmap buffer after DMA
 * @dma_xfer: DMA transfer and mapping descriptor
 *
 * Unmap buffer and cleanup DMA transfer descriptor.
 */
void i3c_master_dma_unmap_single(struct i3c_dma *dma_xfer)
{
	dma_unmap_single(dma_xfer->dev, dma_xfer->addr,
			 dma_xfer->map_len, dma_xfer->dir);
	if (dma_xfer->bounce_buf) {
		if (dma_xfer->dir == DMA_FROM_DEVICE)
			memcpy(dma_xfer->buf, dma_xfer->bounce_buf,
			       dma_xfer->len);
		kfree(dma_xfer->bounce_buf);
	}
	kfree(dma_xfer);
}
EXPORT_SYMBOL_GPL(i3c_master_dma_unmap_single);

/**
 * i3c_master_set_info() - set master device information
 * @master: master used to send frames on the bus
@@ -2490,9 +2564,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
	adap->owner = master->dev.parent->driver->owner;
	adap->algo = &i3c_master_i2c_algo;
	strscpy(adap->name, dev_name(master->dev.parent), sizeof(adap->name));

	/* FIXME: Should we allow i3c masters to override these values? */
	adap->timeout = 1000;
	adap->timeout = HZ;
	adap->retries = 3;

	id = of_alias_get_id(master->dev.of_node, "i2c");
Loading