[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250313183440.261872-3-Raju.Rangoju@amd.com>
Date: Fri, 14 Mar 2025 00:04:32 +0530
From: Raju Rangoju <Raju.Rangoju@....com>
To: <broonie@...nel.org>, <linux-spi@...r.kernel.org>,
<linux-kernel@...r.kernel.org>
CC: <Raju.Rangoju@....com>, <krishnamoorthi.m@....com>,
<akshata.mukundshetty@....com>
Subject: [PATCH 02/10] spi: espi_amd: Add eSPI set config IOCTL command
This patch introduces an IOCTL command to set the configuration of the
eSPI controller and eSPI slave0. The configuration options include
parameters like frequency, channel, and IO mode. The new IOCTL command
allow users to dynamically configure the eSPI controller and slave.
Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@....com>
Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@....com>
Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@....com>
Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@....com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@....com>
---
drivers/spi/espi-amd-dev.c | 94 ++++++++++++++++++++++++++++++++++++++
drivers/spi/espi-amd.h | 4 ++
2 files changed, 98 insertions(+)
diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c
index 4e46c30d3405..5f25ad2b1eef 100644
--- a/drivers/spi/espi-amd-dev.c
+++ b/drivers/spi/espi-amd-dev.c
@@ -28,6 +28,99 @@ static DEFINE_MUTEX(device_list_lock);
static struct class *amd_espi_dev_class;
static struct cdev cdev;
+static int amd_espi_ioctl_set_conf(struct amd_espi *amd_espi, unsigned long arg)
+{
+ struct config *dev_conf, *config;
+ u32 slave_config;
+ int ret;
+
+ dev_conf = kzalloc(sizeof(*dev_conf), GFP_KERNEL);
+ if (!dev_conf)
+ return -ENOMEM;
+
+ config = kzalloc(sizeof(*config), GFP_KERNEL);
+ if (!config) {
+ kfree(dev_conf);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) {
+ ret = -EFAULT;
+ goto set_config_free;
+ }
+
+ /* IO mode configuration */
+ if (config->io_mode != IO_MODE_SINGLE && config->io_mode != IO_MODE_DUAL &&
+ config->io_mode != IO_MODE_QUAD) {
+ dev_err(amd_espi->dev, "Invalid IO mode\n");
+ ret = -EOPNOTSUPP;
+ goto set_config_free;
+ } else {
+ dev_conf->io_mode = config->io_mode;
+ }
+
+ /* Set operating frequency configuration */
+ if (config->op_freq != SLAVE_OP_FREQ_16 && config->op_freq != SLAVE_OP_FREQ_33 &&
+ config->op_freq != SLAVE_OP_FREQ_66) {
+ dev_err(amd_espi->dev, "Invalid operating frequency\n");
+ ret = -EOPNOTSUPP;
+ goto set_config_free;
+ } else {
+ dev_conf->op_freq = config->op_freq;
+ }
+
+ ret = amd_espi_set_general_conf(amd_espi, dev_conf);
+ if (ret != CB_SUCCESS)
+ goto set_config_free;
+
+ /* Set channel configuration */
+ ret = amd_espi_get_general_config(amd_espi, &slave_config);
+ if (ret != CB_SUCCESS)
+ goto set_config_free;
+
+ if (config->channel_mode == CHANNEL_MODE_PC) {
+ ret = amd_espi_setup_periph_channel(amd_espi, slave_config);
+ if (ret) {
+ dev_err(amd_espi->dev, "Peripheral channel setup failed\n");
+ goto set_config_free;
+ }
+ } else if (config->channel_mode == CHANNEL_MODE_VW) {
+ ret = amd_espi_setup_vw_channel(amd_espi, slave_config);
+ if (ret) {
+ dev_err(amd_espi->dev, "Virtual wire channel setup failed\n");
+ goto set_config_free;
+ }
+ } else {
+ ret = -EOPNOTSUPP;
+ }
+
+set_config_free:
+ kfree(dev_conf);
+ 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;
+ int ret = 0;
+
+ /* Check type and command number */
+ if (_IOC_TYPE(cmd) != ESPI_MAGIC_NUMBER)
+ return -EINVAL;
+
+ switch (cmd) {
+ case ESPI_SET_CONFIG:
+ ret = amd_espi_ioctl_set_conf(amd_espi, arg);
+ break;
+ default:
+ dev_err(amd_espi->dev, "ESPI command not found, returning error\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
static int amd_espi_open(struct inode *inode, struct file *filp)
{
struct amd_espi *espi;
@@ -68,6 +161,7 @@ static int amd_espi_release(struct inode *inode, struct file *filp)
static const struct file_operations amd_espi_fops = {
.owner = THIS_MODULE,
+ .unlocked_ioctl = amd_espi_ioctl,
.open = amd_espi_open,
.release = amd_espi_release,
};
diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h
index 57b156fb0a05..1de53426059b 100644
--- a/drivers/spi/espi-amd.h
+++ b/drivers/spi/espi-amd.h
@@ -138,6 +138,10 @@
#define ESPI_BASE ((u8 __iomem *)amd_espi->io_remap_addr)
+/* IOCTL calls */
+#define ESPI_MAGIC_NUMBER 'i'
+#define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config)
+
/*
* enum amd_espi_versions - eSPI controller versions
* @AMD_ESPI_V1: AMDI0070 hardware version
--
2.34.1
Powered by blists - more mailing lists