Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) // Copyright (C) IBM Corporation 2020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/fsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define FSI_ENGID_SPI			0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define FSI_MBOX_ROOT_CTRL_8		0x2860
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define  FSI_MBOX_ROOT_CTRL_8_SPI_MUX	 0xf0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define FSI2SPI_DATA0			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define FSI2SPI_DATA1			0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define FSI2SPI_CMD			0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define  FSI2SPI_CMD_WRITE		 BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define FSI2SPI_RESET			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define FSI2SPI_STATUS			0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define  FSI2SPI_STATUS_ANY_ERROR	 BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define FSI2SPI_IRQ			0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define SPI_FSI_BASE			0x70000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define SPI_FSI_INIT_TIMEOUT_MS		1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define SPI_FSI_MAX_XFR_SIZE		2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SPI_FSI_MAX_XFR_SIZE_RESTRICTED	32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define SPI_FSI_ERROR			0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define SPI_FSI_COUNTER_CFG		0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define  SPI_FSI_COUNTER_CFG_LOOPS(x)	 (((u64)(x) & 0xffULL) << 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define  SPI_FSI_COUNTER_CFG_N2_RX	 BIT_ULL(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define  SPI_FSI_COUNTER_CFG_N2_TX	 BIT_ULL(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define  SPI_FSI_COUNTER_CFG_N2_IMPLICIT BIT_ULL(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define  SPI_FSI_COUNTER_CFG_N2_RELOAD	 BIT_ULL(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define SPI_FSI_CFG1			0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define SPI_FSI_CLOCK_CFG		0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define  SPI_FSI_CLOCK_CFG_MM_ENABLE	 BIT_ULL(32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define  SPI_FSI_CLOCK_CFG_ECC_DISABLE	 (BIT_ULL(35) | BIT_ULL(33))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define  SPI_FSI_CLOCK_CFG_RESET1	 (BIT_ULL(36) | BIT_ULL(38))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define  SPI_FSI_CLOCK_CFG_RESET2	 (BIT_ULL(37) | BIT_ULL(39))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define  SPI_FSI_CLOCK_CFG_MODE		 (BIT_ULL(41) | BIT_ULL(42))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define  SPI_FSI_CLOCK_CFG_SCK_RECV_DEL	 GENMASK_ULL(51, 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define   SPI_FSI_CLOCK_CFG_SCK_NO_DEL	  BIT_ULL(51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define  SPI_FSI_CLOCK_CFG_SCK_DIV	 GENMASK_ULL(63, 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define SPI_FSI_MMAP			0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define SPI_FSI_DATA_TX			0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define SPI_FSI_DATA_RX			0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define SPI_FSI_SEQUENCE		0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define  SPI_FSI_SEQUENCE_STOP		 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define  SPI_FSI_SEQUENCE_SEL_SLAVE(x)	 (0x10 | ((x) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define  SPI_FSI_SEQUENCE_SHIFT_OUT(x)	 (0x30 | ((x) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define  SPI_FSI_SEQUENCE_SHIFT_IN(x)	 (0x40 | ((x) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define  SPI_FSI_SEQUENCE_COPY_DATA_TX	 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define  SPI_FSI_SEQUENCE_BRANCH(x)	 (0xe0 | ((x) & 0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define SPI_FSI_STATUS			0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define  SPI_FSI_STATUS_ERROR		 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	(GENMASK_ULL(31, 21) | GENMASK_ULL(15, 12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define  SPI_FSI_STATUS_SEQ_STATE	 GENMASK_ULL(55, 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define   SPI_FSI_STATUS_SEQ_STATE_IDLE	  BIT_ULL(48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define  SPI_FSI_STATUS_TDR_UNDERRUN	 BIT_ULL(57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define  SPI_FSI_STATUS_TDR_OVERRUN	 BIT_ULL(58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define  SPI_FSI_STATUS_TDR_FULL	 BIT_ULL(59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define  SPI_FSI_STATUS_RDR_UNDERRUN	 BIT_ULL(61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define  SPI_FSI_STATUS_RDR_OVERRUN	 BIT_ULL(62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define  SPI_FSI_STATUS_RDR_FULL	 BIT_ULL(63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define  SPI_FSI_STATUS_ANY_ERROR	 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	(SPI_FSI_STATUS_ERROR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 SPI_FSI_STATUS_TDR_OVERRUN | SPI_FSI_STATUS_RDR_UNDERRUN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	 SPI_FSI_STATUS_RDR_OVERRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define SPI_FSI_PORT_CTRL		0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) struct fsi_spi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	struct device *dev;	/* SPI controller device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct fsi_device *fsi;	/* FSI2SPI CFAM engine device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u32 base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	size_t max_xfr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	bool restricted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) struct fsi_spi_sequence {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u64 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static int fsi_spi_check_mux(struct fsi_device *fsi, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	u32 root_ctrl_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	__be32 root_ctrl_8_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			    sizeof(root_ctrl_8_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	root_ctrl_8 = be32_to_cpu(root_ctrl_8_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	dev_dbg(dev, "Root control register 8: %08x\n", root_ctrl_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if ((root_ctrl_8 & FSI_MBOX_ROOT_CTRL_8_SPI_MUX) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	     FSI_MBOX_ROOT_CTRL_8_SPI_MUX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int fsi_spi_check_status(struct fsi_spi *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	u32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	__be32 sts_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	rc = fsi_device_read(ctx->fsi, FSI2SPI_STATUS, &sts_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			     sizeof(sts_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	sts = be32_to_cpu(sts_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (sts & FSI2SPI_STATUS_ANY_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		dev_err(ctx->dev, "Error with FSI2SPI interface: %08x.\n", sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	__be32 cmd_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	__be32 data_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	u32 cmd = offset + ctx->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	*value = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (cmd & FSI2SPI_CMD_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	cmd_be = cpu_to_be32(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	rc = fsi_spi_check_status(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA0, &data_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			     sizeof(data_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	*value |= (u64)be32_to_cpu(data_be) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	rc = fsi_device_read(ctx->fsi, FSI2SPI_DATA1, &data_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			     sizeof(data_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	*value |= (u64)be32_to_cpu(data_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int fsi_spi_write_reg(struct fsi_spi *ctx, u32 offset, u64 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	__be32 cmd_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	__be32 data_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	u32 cmd = offset + ctx->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	if (cmd & FSI2SPI_CMD_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	data_be = cpu_to_be32(upper_32_bits(value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA0, &data_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			      sizeof(data_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	data_be = cpu_to_be32(lower_32_bits(value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	rc = fsi_device_write(ctx->fsi, FSI2SPI_DATA1, &data_be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			      sizeof(data_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	cmd_be = cpu_to_be32(cmd | FSI2SPI_CMD_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	rc = fsi_device_write(ctx->fsi, FSI2SPI_CMD, &cmd_be, sizeof(cmd_be));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return fsi_spi_check_status(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int fsi_spi_data_in(u64 in, u8 *rx, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int num_bytes = min(len, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	for (i = 0; i < num_bytes; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		rx[i] = (u8)(in >> (8 * ((num_bytes - 1) - i)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return num_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int fsi_spi_data_out(u64 *out, const u8 *tx, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	int num_bytes = min(len, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	u8 *out_bytes = (u8 *)out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	/* Unused bytes of the tx data should be 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	*out = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	for (i = 0; i < num_bytes; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		out_bytes[8 - (i + 1)] = tx[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return num_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int fsi_spi_reset(struct fsi_spi *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	dev_dbg(ctx->dev, "Resetting SPI controller.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			       SPI_FSI_CLOCK_CFG_RESET1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			       SPI_FSI_CLOCK_CFG_RESET2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	return fsi_spi_write_reg(ctx, SPI_FSI_STATUS, 0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	 * Add the next byte of instruction to the 8-byte sequence register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	 * Then decrement the counter so that the next instruction will go in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	 * the right place. Return the index of the slot we just filled in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * sequence register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	seq->data |= (u64)val << seq->bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	seq->bit -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return ((64 - seq->bit) / 8) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void fsi_spi_sequence_init(struct fsi_spi_sequence *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	seq->bit = 56;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	seq->data = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int fsi_spi_sequence_transfer(struct fsi_spi *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 				     struct fsi_spi_sequence *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				     struct spi_transfer *transfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	bool docfg = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	int loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	u8 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	u8 len = min(transfer->len, 8U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	u8 rem = transfer->len % len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	u64 cfg = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	loops = transfer->len / len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (transfer->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		val = SPI_FSI_SEQUENCE_SHIFT_OUT(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		idx = fsi_spi_sequence_add(seq, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		if (rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			rem = SPI_FSI_SEQUENCE_SHIFT_OUT(rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	} else if (transfer->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		val = SPI_FSI_SEQUENCE_SHIFT_IN(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		idx = fsi_spi_sequence_add(seq, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		if (rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			rem = SPI_FSI_SEQUENCE_SHIFT_IN(rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (ctx->restricted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		const int eidx = rem ? 5 : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		while (loops > 1 && idx <= eidx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			idx = fsi_spi_sequence_add(seq, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			loops--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			docfg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		if (loops > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			dev_warn(ctx->dev, "No sequencer slots; aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (loops > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		fsi_spi_sequence_add(seq, SPI_FSI_SEQUENCE_BRANCH(idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		docfg = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (docfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		cfg = SPI_FSI_COUNTER_CFG_LOOPS(loops - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		if (transfer->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			cfg |= SPI_FSI_COUNTER_CFG_N2_RX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 				SPI_FSI_COUNTER_CFG_N2_TX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 				SPI_FSI_COUNTER_CFG_N2_IMPLICIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 				SPI_FSI_COUNTER_CFG_N2_RELOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, 0ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		fsi_spi_sequence_add(seq, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int fsi_spi_transfer_data(struct fsi_spi *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				 struct spi_transfer *transfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	u64 status = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	u64 cfg = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (transfer->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		int nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		int sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		u64 out = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		const u8 *tx = transfer->tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		while (transfer->len > sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			nb = fsi_spi_data_out(&out, &tx[sent],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 					      (int)transfer->len - sent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 						      &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 				if (status & SPI_FSI_STATUS_ANY_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 					rc = fsi_spi_reset(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 					if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 					return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			} while (status & SPI_FSI_STATUS_TDR_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			sent += nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	} else if (transfer->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		int recv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		u64 in = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		u8 *rx = transfer->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		rc = fsi_spi_read_reg(ctx, SPI_FSI_COUNTER_CFG, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		if (cfg & SPI_FSI_COUNTER_CFG_N2_IMPLICIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		while (transfer->len > recv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 				rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 						      &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 				if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 					return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				if (status & SPI_FSI_STATUS_ANY_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 					rc = fsi_spi_reset(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 					if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 						return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 					return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			} while (!(status & SPI_FSI_STATUS_RDR_FULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			rc = fsi_spi_read_reg(ctx, SPI_FSI_DATA_RX, &in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			recv += fsi_spi_data_in(in, &rx[recv],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 						(int)transfer->len - recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int fsi_spi_transfer_init(struct fsi_spi *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	bool reset = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	unsigned long end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	u64 seq_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	u64 clock_cfg = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	u64 status = 0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	u64 wanted_clock_cfg = SPI_FSI_CLOCK_CFG_ECC_DISABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		SPI_FSI_CLOCK_CFG_SCK_NO_DEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		FIELD_PREP(SPI_FSI_CLOCK_CFG_SCK_DIV, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	end = jiffies + msecs_to_jiffies(SPI_FSI_INIT_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		if (time_after(jiffies, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		seq_state = status & SPI_FSI_STATUS_SEQ_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		if (status & (SPI_FSI_STATUS_ANY_ERROR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			      SPI_FSI_STATUS_TDR_FULL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			      SPI_FSI_STATUS_RDR_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			if (reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 				return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			rc = fsi_spi_reset(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	} while (seq_state && (seq_state != SPI_FSI_STATUS_SEQ_STATE_IDLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	rc = fsi_spi_read_reg(ctx, SPI_FSI_CLOCK_CFG, &clock_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if ((clock_cfg & (SPI_FSI_CLOCK_CFG_MM_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			  SPI_FSI_CLOCK_CFG_ECC_DISABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			  SPI_FSI_CLOCK_CFG_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			  SPI_FSI_CLOCK_CFG_SCK_RECV_DEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			  SPI_FSI_CLOCK_CFG_SCK_DIV)) != wanted_clock_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				       wanted_clock_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 					struct spi_message *mesg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(mesg->spi->chip_select + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	struct spi_transfer *transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	rc = fsi_spi_check_mux(ctx->fsi, ctx->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		struct fsi_spi_sequence seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		struct spi_transfer *next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		/* Sequencer must do shift out (tx) first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		if (!transfer->tx_buf ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		    transfer->len > (ctx->max_xfr_size + 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		dev_dbg(ctx->dev, "Start tx of %d bytes.\n", transfer->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		rc = fsi_spi_transfer_init(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		fsi_spi_sequence_init(&seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		fsi_spi_sequence_add(&seq, seq_slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		rc = fsi_spi_sequence_transfer(ctx, &seq, transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (!list_is_last(&transfer->transfer_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 				  &mesg->transfers)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			next = list_next_entry(transfer, transfer_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			/* Sequencer can only do shift in (rx) after tx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			if (next->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 				if (next->len > ctx->max_xfr_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 					rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 					goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 				dev_dbg(ctx->dev, "Sequence rx of %d bytes.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 					next->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 				rc = fsi_spi_sequence_transfer(ctx, &seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 							       next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 					goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		fsi_spi_sequence_add(&seq, SPI_FSI_SEQUENCE_SEL_SLAVE(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		rc = fsi_spi_write_reg(ctx, SPI_FSI_SEQUENCE, seq.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		rc = fsi_spi_transfer_data(ctx, transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		if (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			rc = fsi_spi_transfer_data(ctx, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			transfer = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	mesg->status = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	spi_finalize_current_message(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static size_t fsi_spi_max_transfer_size(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	struct fsi_spi *ctx = spi_controller_get_devdata(spi->controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	return ctx->max_xfr_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int fsi_spi_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	int num_controllers_registered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	struct fsi_device *fsi = to_fsi_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	rc = fsi_spi_check_mux(fsi, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	for_each_available_child_of_node(dev->of_node, np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		u32 base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		struct fsi_spi *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		struct spi_controller *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		if (of_property_read_u32(np, "reg", &base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		ctlr = spi_alloc_master(dev, sizeof(*ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		if (!ctlr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		ctlr->dev.of_node = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		ctlr->num_chipselect = of_get_available_child_count(np) ?: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		ctlr->max_transfer_size = fsi_spi_max_transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		ctlr->transfer_one_message = fsi_spi_transfer_one_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		ctx = spi_controller_get_devdata(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		ctx->dev = &ctlr->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		ctx->fsi = fsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		ctx->base = base + SPI_FSI_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		if (of_device_is_compatible(np, "ibm,fsi2spi-restricted")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 			ctx->restricted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			ctx->max_xfr_size = SPI_FSI_MAX_XFR_SIZE_RESTRICTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			ctx->restricted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 			ctx->max_xfr_size = SPI_FSI_MAX_XFR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		rc = devm_spi_register_controller(dev, ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			spi_controller_put(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			num_controllers_registered++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (!num_controllers_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static const struct fsi_device_id fsi_spi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	{ FSI_ENGID_SPI, FSI_VERSION_ANY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) MODULE_DEVICE_TABLE(fsi, fsi_spi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static struct fsi_driver fsi_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	.id_table = fsi_spi_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	.drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		.name = "spi-fsi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		.bus = &fsi_bus_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		.probe = fsi_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) module_fsi_driver(fsi_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) MODULE_DESCRIPTION("FSI attached SPI controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) MODULE_LICENSE("GPL");