This patch introduces an IOCTL command to allow users to dynamically configure the supported IO modes such as single, dual and quad modes. Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@xxxxxxx> Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@xxxxxxx> Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@xxxxxxx> Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@xxxxxxx> Signed-off-by: Raju Rangoju <Raju.Rangoju@xxxxxxx> --- drivers/spi/espi-amd-dev.c | 40 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 41 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index ba2becdec8e6..821cc0486657 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -166,6 +166,43 @@ static int amd_espi_ioctl_get_conf(struct amd_espi *amd_espi, unsigned long arg) return ret; } +static int amd_espi_ioctl_set_io_mode(struct amd_espi *amd_espi, unsigned long arg) +{ + u32 ctrlr_config, slave_config; + struct config *config; + int ret; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) { + ret = -EFAULT; + goto set_io_mode_free; + } + + ctrlr_config = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + + ret = amd_espi_get_general_config(amd_espi, &slave_config); + if (ret != CB_SUCCESS) + goto set_io_mode_free; + + ret = amd_espi_set_iomode(amd_espi, &slave_config, &ctrlr_config, config->io_mode); + if (ret != CB_SUCCESS) + goto set_io_mode_free; + + ret = amd_espi_set_config(amd_espi, slave_config, ESPI_SLAVE_GENERAL_CAPS_CFG); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Set IO mode failed\n"); + goto set_io_mode_free; + } + writel(ctrlr_config, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); + +set_io_mode_free: + kfree(config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -187,6 +224,9 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar if (ret != CB_SUCCESS) dev_err(amd_espi->dev, "In-band reset failed!\n"); break; + case ESPI_SET_IO_MODE: + ret = amd_espi_ioctl_set_io_mode(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 3c6e9b92c08d..f1185f877a05 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -143,6 +143,7 @@ #define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config) #define ESPI_GET_CONFIG _IOR(ESPI_MAGIC_NUMBER, 0x2, struct config) #define ESPI_INBAND_RESET _IO(ESPI_MAGIC_NUMBER, 0x3) +#define ESPI_SET_IO_MODE _IOW(ESPI_MAGIC_NUMBER, 0x4, struct config) /* * enum amd_espi_versions - eSPI controller versions -- 2.34.1