From: Zhang Xiaoxu <[email protected]>
v2->v3:
Add configfs to configure and register the device;
Fix some misspelling.
v1->v2:
Use the new _controller() API
P1. Move the license identifier to the entrie comment
P2. Inherit tx_nbits/rx_nbits/cs_off/cs_change from the
spi_transfer to the tracepoint
P3. Removed.
P4. Update the Document.
Zhang Xiaoxu (5):
spi: mockup: Add SPI controller testing driver
spi: mockup: Add writeable tracepoint for spi transfer
spi: mockup: Add support register the device through configfs
spi: mockup: Add speed and flags attribute support
spi: mockup: Add documentation
Documentation/spi/index.rst | 1 +
Documentation/spi/spi-mockup.rst | 196 ++++++++++++
drivers/spi/Kconfig | 13 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-mockup.c | 474 ++++++++++++++++++++++++++++++
include/linux/spi/spi-mockup.h | 17 ++
include/trace/events/spi_mockup.h | 31 ++
7 files changed, 733 insertions(+)
create mode 100644 Documentation/spi/spi-mockup.rst
create mode 100644 drivers/spi/spi-mockup.c
create mode 100644 include/linux/spi/spi-mockup.h
create mode 100644 include/trace/events/spi_mockup.h
--
2.34.1
From: Zhang Xiaoxu <[email protected]>
This enable configure the spi speed and flags through configfs:
echo 40000 > /sys/kernel/config/spi-mockup/spi0/min_speed
echo 25000000 > /sys/kernel/config/spi-mockup/spi0/max_speed
echo 0 > /sys/kernel/config/spi-mockup/spi0/flags
echo 8 > /sys/kernel/config/spi-mockup/spi0/num_cs
Then enable the device can use the special config:
echo 1 > /sys/kernel/config/spi-mockup/spi0/enable
Signed-off-by: Zhang Xiaoxu <[email protected]>
---
drivers/spi/spi-mockup.c | 55 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/drivers/spi/spi-mockup.c b/drivers/spi/spi-mockup.c
index b449a2b7cdd4..06848504d144 100644
--- a/drivers/spi/spi-mockup.c
+++ b/drivers/spi/spi-mockup.c
@@ -207,11 +207,19 @@ static int spi_mockup_transfer(struct spi_controller *ctrl,
return ret;
}
+struct spi_mockup_priv_data {
+ u32 min_speed;
+ u32 max_speed;
+ u16 flags;
+ u16 num_cs;
+};
+
static int spi_mockup_probe(struct platform_device *pdev)
{
int ret;
struct mockup_spi *mock;
struct spi_controller *ctrl;
+ struct spi_mockup_priv_data *data;
ctrl = spi_alloc_host(&pdev->dev, sizeof(struct mockup_spi));
if (!ctrl) {
@@ -228,6 +236,14 @@ static int spi_mockup_probe(struct platform_device *pdev)
ctrl->bus_num = pdev->id;
ctrl->transfer_one_message = spi_mockup_transfer;
+ data = dev_get_platdata(&pdev->dev);
+ if (data) {
+ ctrl->min_speed_hz = data->min_speed;
+ ctrl->max_speed_hz = data->max_speed;
+ ctrl->flags = data->flags;
+ ctrl->num_chipselect = data->num_cs;
+ }
+
mock = spi_controller_get_devdata(ctrl);
mutex_init(&mock->lock);
@@ -259,6 +275,7 @@ struct spi_mockup_device {
unsigned int bus_nr;
struct mutex lock;
struct platform_device *pdev;
+ struct spi_mockup_priv_data data;
};
static struct spi_mockup_device *to_spi_mockup_dev(struct config_item *item)
@@ -283,6 +300,9 @@ spi_mockup_enable_store(struct config_item *item, const char *page, size_t len)
pdevinfo.name = "spi-mockup";
pdevinfo.id = dev->bus_nr;
+ pdevinfo.data = &dev->data;
+ pdevinfo.size_data = sizeof(dev->data);
+
dev->pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(dev->pdev)) {
ret = PTR_ERR(dev->pdev);
@@ -315,9 +335,43 @@ spi_mockup_disable_store(struct config_item *item, const char *page, size_t len)
}
CONFIGFS_ATTR_WO(spi_mockup_, disable);
+#define SPI_MOCKUP_ATTR(type, name) \
+static ssize_t spi_mockup_ ## name ## _store(struct config_item *item, \
+ const char *page, size_t len) \
+{ \
+ int ret; \
+ type val; \
+ struct spi_mockup_device *dev = to_spi_mockup_dev(item); \
+ \
+ mutex_lock(&dev->lock); \
+ if (dev->pdev) { \
+ ret = -EBUSY; \
+ goto out; \
+ } \
+ \
+ ret = kstrto ## type(page, 0, &val); \
+ if (ret) \
+ goto out; \
+ \
+ dev->data.name = val; \
+out: \
+ mutex_unlock(&dev->lock); \
+ return ret ? ret : len; \
+} \
+CONFIGFS_ATTR_WO(spi_mockup_, name) \
+
+SPI_MOCKUP_ATTR(u32, min_speed)
+SPI_MOCKUP_ATTR(u32, max_speed)
+SPI_MOCKUP_ATTR(u16, flags)
+SPI_MOCKUP_ATTR(u16, num_cs)
+
static struct configfs_attribute *spi_mockup_configfs_attrs[] = {
&spi_mockup_attr_enable,
&spi_mockup_attr_disable,
+ &spi_mockup_attr_min_speed,
+ &spi_mockup_attr_max_speed,
+ &spi_mockup_attr_flags,
+ &spi_mockup_attr_num_cs,
NULL,
};
@@ -342,6 +396,7 @@ spi_mockup_config_make_device_group(struct config_group *group,
if (!dev)
return ERR_PTR(-ENOMEM);
+ dev->data.num_cs = MOCKUP_CHIPSELECT_MAX;
dev->bus_nr = nr;
mutex_init(&dev->lock);
--
2.34.1
From: Zhang Xiaoxu <[email protected]>
This enables SPI controller Testing driver, which provides a way to
test SPI subsystem.
This is accomplished by executing the following command:
$ echo adcxx1s 0 > /sys/class/spi_master/spi0/new_device
The name of the target driver and its chip select were used to
instantiate the device.
$ ls /sys/bus/spi/devices/spi0.0/hwmon/hwmon0/ -l
total 0
lrwxrwxrwx 1 root root 0 Aug 10 08:58 device -> ../../../spi0.0
drwxr-xr-x 2 root root 0 Aug 10 08:58 power
lrwxrwxrwx 1 root root 0 Aug 10 08:58 subsystem -> ../../../../../../../../class/hwmon
-rw-r--r-- 1 root root 4096 Aug 10 08:58 uevent
Remove target device by executing the following command:
$ echo 0 > /sys/class/spi_master/spi0/delete_device
Signed-off-by: Wei Yongjun <[email protected]>
Signed-off-by: Zhang Xiaoxu <[email protected]>
---
drivers/spi/Kconfig | 12 +++
drivers/spi/Makefile | 1 +
drivers/spi/spi-mockup.c | 211 +++++++++++++++++++++++++++++++++++++++
3 files changed, 224 insertions(+)
create mode 100644 drivers/spi/spi-mockup.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2c21d5b96fdc..9169081cfecb 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -1218,6 +1218,18 @@ config SPI_TLE62X0
sysfs interface, with each line presented as a kind of GPIO
exposing both switch control and diagnostic feedback.
+config SPI_MOCKUP
+ tristate "SPI controller Testing Driver"
+ depends on OF
+ help
+ This enables SPI controller testing driver, which provides a way to
+ test SPI subsystem.
+
+ If you do build this module, be sure to read the notes and warnings
+ in <file:Documentation/spi/spi-mockup.rst>.
+
+ If you don't know what to do here, definitely say N.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6af54842b9fa..f28074e61df9 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_MEM) += spi-mem.o
obj-$(CONFIG_SPI_MUX) += spi-mux.o
obj-$(CONFIG_SPI_SPIDEV) += spidev.o
obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o
+obj-$(CONFIG_SPI_MOCKUP) += spi-mockup.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ALTERA) += spi-altera-platform.o
diff --git a/drivers/spi/spi-mockup.c b/drivers/spi/spi-mockup.c
new file mode 100644
index 000000000000..683a0fc43f0d
--- /dev/null
+++ b/drivers/spi/spi-mockup.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SPI controller Testing Driver
+ *
+ * Copyright(c) 2022 Huawei Technologies Co., Ltd.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#define MOCKUP_CHIPSELECT_MAX 8
+
+struct mockup_spi {
+ struct mutex lock;
+ struct spi_device *devs[MOCKUP_CHIPSELECT_MAX];
+};
+
+static struct spi_controller *to_spi_controller(struct device *dev)
+{
+ return container_of(dev, struct spi_controller, dev);
+}
+
+static ssize_t
+new_device_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct spi_controller *ctrl = to_spi_controller(dev);
+ struct spi_board_info info;
+ struct mockup_spi *mock;
+ struct spi_device *spi;
+ char *blank, end;
+ int status;
+
+ memset(&info, 0, sizeof(struct spi_board_info));
+
+ blank = strchr(buf, ' ');
+ if (!blank) {
+ dev_err(dev, "%s: Extra parameters\n", "new_device");
+ return -EINVAL;
+ }
+
+ if (blank - buf > SPI_NAME_SIZE - 1) {
+ dev_err(dev, "%s: Invalid device name\n", "new_device");
+ return -EINVAL;
+ }
+
+ memcpy(info.modalias, buf, blank - buf);
+
+ status = sscanf(++blank, "%hi%c", &info.chip_select, &end);
+ if (status < 1) {
+ dev_err(dev, "%s: Can't parse SPI chipselect\n", "new_device");
+ return -EINVAL;
+ }
+
+ if (status > 1 && end != '\n') {
+ dev_err(dev, "%s: Extra parameters\n", "new_device");
+ return -EINVAL;
+ }
+
+ if (info.chip_select >= ctrl->num_chipselect) {
+ dev_err(dev, "%s: Invalid chip_select\n", "new_device");
+ return -EINVAL;
+ }
+
+ mock = spi_controller_get_devdata(ctrl);
+ mutex_lock(&mock->lock);
+
+ if (mock->devs[info.chip_select]) {
+ dev_err(dev, "%s: Chipselect %d already in use\n",
+ "new_device", info.chip_select);
+ mutex_unlock(&mock->lock);
+ return -EINVAL;
+ }
+
+ spi = spi_new_device(ctrl, &info);
+ if (!spi) {
+ mutex_unlock(&mock->lock);
+ return -ENOMEM;
+ }
+ mock->devs[info.chip_select] = spi;
+
+ mutex_unlock(&mock->lock);
+
+ dev_info(dev, "%s: Instantiated device %s at 0x%02x\n", "new_device",
+ info.modalias, info.chip_select);
+
+ return count;
+}
+static DEVICE_ATTR_WO(new_device);
+
+static ssize_t
+delete_device_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct spi_controller *ctrl = to_spi_controller(dev);
+ struct mockup_spi *mock;
+ struct spi_device *spi;
+ unsigned short chip;
+ char end;
+ int res;
+
+ /* Parse parameters, reject extra parameters */
+ res = sscanf(buf, "%hi%c", &chip, &end);
+ if (res < 1) {
+ dev_err(dev, "%s: Can't parse SPI address\n", "delete_device");
+ return -EINVAL;
+ }
+ if (res > 1 && end != '\n') {
+ dev_err(dev, "%s: Extra parameters\n", "delete_device");
+ return -EINVAL;
+ }
+
+ if (chip >= ctrl->num_chipselect) {
+ dev_err(dev, "%s: Invalid chip_select\n", "delete_device");
+ return -EINVAL;
+ }
+
+ mock = spi_controller_get_devdata(ctrl);
+ mutex_lock(&mock->lock);
+
+ spi = mock->devs[chip];
+ if (!spi) {
+ mutex_unlock(&mock->lock);
+ dev_err(dev, "%s: Invalid chip_select\n", "delete_device");
+ return -ENOENT;
+ }
+
+ dev_info(dev, "%s: Deleting device %s at 0x%02hx\n", "delete_device",
+ dev_name(&spi->dev), chip);
+
+ spi_unregister_device(spi);
+ mock->devs[chip] = NULL;
+
+ mutex_unlock(&mock->lock);
+
+ return count;
+}
+static DEVICE_ATTR_WO(delete_device);
+
+static struct attribute *spi_mockup_attrs[] = {
+ &dev_attr_new_device.attr,
+ &dev_attr_delete_device.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(spi_mockup);
+
+static int spi_mockup_transfer(struct spi_controller *ctrl,
+ struct spi_message *msg)
+{
+ msg->status = 0;
+ spi_finalize_current_message(ctrl);
+
+ return 0;
+}
+
+static int spi_mockup_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct mockup_spi *mock;
+ struct spi_controller *ctrl;
+
+ ctrl = spi_alloc_host(&pdev->dev, sizeof(struct mockup_spi));
+ if (!ctrl) {
+ pr_err("failed to alloc spi controller\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, ctrl);
+
+ ctrl->dev.of_node = pdev->dev.of_node;
+ ctrl->dev.groups = spi_mockup_groups;
+ ctrl->num_chipselect = MOCKUP_CHIPSELECT_MAX;
+ ctrl->mode_bits = SPI_MODE_USER_MASK;
+ ctrl->bus_num = 0;
+ ctrl->transfer_one_message = spi_mockup_transfer;
+
+ mock = spi_controller_get_devdata(ctrl);
+ mutex_init(&mock->lock);
+
+ ret = devm_spi_register_controller(&pdev->dev, ctrl);
+ if (ret) {
+ spi_controller_put(ctrl);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id spi_mockup_match[] = {
+ { .compatible = "spi-mockup", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, spi_mockup_match);
+
+static struct platform_driver spi_mockup_driver = {
+ .probe = spi_mockup_probe,
+ .driver = {
+ .name = "spi-mockup",
+ .of_match_table = spi_mockup_match,
+ },
+};
+module_platform_driver(spi_mockup_driver);
+
+MODULE_AUTHOR("Wei Yongjun <[email protected]>");
+MODULE_DESCRIPTION("SPI controller Testing Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
Hi Zhang,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20231103]
url: https://github.com/intel-lab-lkp/linux/commits/Zhang-Xiaoxu/spi-mockup-Add-SPI-controller-testing-driver/20231104-144859
base: next-20231103
patch link: https://lore.kernel.org/r/20231104064650.972687-5-zhangxiaoxu%40huaweicloud.com
patch subject: [PATCH v3 -next 4/5] spi: mockup: Add speed and flags attribute support
config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20231104/[email protected]/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231104/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/spi/spi-mockup.c:339:1: error: expected ',' or ';' before 'static'
339 | static ssize_t spi_mockup_ ## name ## _store(struct config_item *item, \
| ^~~~~~
drivers/spi/spi-mockup.c:364:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
364 | SPI_MOCKUP_ATTR(u32, max_speed)
| ^~~~~~~~~~~~~~~
In file included from drivers/spi/spi-mockup.c:15:
drivers/spi/spi-mockup.c:361:18: error: 'spi_mockup_max_speed_store' undeclared here (not in a function); did you mean 'spi_mockup_min_speed_store'?
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:145:27: note: in definition of macro 'CONFIGFS_ATTR_WO'
145 | .store = _pfx##_name##_store, \
| ^~~~
drivers/spi/spi-mockup.c:364:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
364 | SPI_MOCKUP_ATTR(u32, max_speed)
| ^~~~~~~~~~~~~~~
drivers/spi/spi-mockup.c:339:1: error: expected ',' or ';' before 'static'
339 | static ssize_t spi_mockup_ ## name ## _store(struct config_item *item, \
| ^~~~~~
drivers/spi/spi-mockup.c:365:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
365 | SPI_MOCKUP_ATTR(u16, flags)
| ^~~~~~~~~~~~~~~
drivers/spi/spi-mockup.c:361:18: error: 'spi_mockup_flags_store' undeclared here (not in a function); did you mean 'spi_mockup_enable_store'?
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:145:27: note: in definition of macro 'CONFIGFS_ATTR_WO'
145 | .store = _pfx##_name##_store, \
| ^~~~
drivers/spi/spi-mockup.c:365:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
365 | SPI_MOCKUP_ATTR(u16, flags)
| ^~~~~~~~~~~~~~~
drivers/spi/spi-mockup.c:339:1: error: expected ',' or ';' before 'static'
339 | static ssize_t spi_mockup_ ## name ## _store(struct config_item *item, \
| ^~~~~~
drivers/spi/spi-mockup.c:366:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
366 | SPI_MOCKUP_ATTR(u16, num_cs)
| ^~~~~~~~~~~~~~~
drivers/spi/spi-mockup.c:361:18: error: 'spi_mockup_num_cs_store' undeclared here (not in a function); did you mean 'spi_mockup_enable_store'?
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:145:27: note: in definition of macro 'CONFIGFS_ATTR_WO'
145 | .store = _pfx##_name##_store, \
| ^~~~
drivers/spi/spi-mockup.c:366:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
366 | SPI_MOCKUP_ATTR(u16, num_cs)
| ^~~~~~~~~~~~~~~
drivers/spi/spi-mockup.c:368:1: error: expected ',' or ';' before 'static'
368 | static struct configfs_attribute *spi_mockup_configfs_attrs[] = {
| ^~~~~~
drivers/spi/spi-mockup.c:380:27: error: 'spi_mockup_configfs_attrs' undeclared here (not in a function); did you mean 'spi_mockup_attrs'?
380 | .ct_attrs = spi_mockup_configfs_attrs,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
| spi_mockup_attrs
>> drivers/spi/spi-mockup.c:361:18: warning: 'spi_mockup_attr_num_cs' defined but not used [-Wunused-variable]
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
drivers/spi/spi-mockup.c:366:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
366 | SPI_MOCKUP_ATTR(u16, num_cs)
| ^~~~~~~~~~~~~~~
>> drivers/spi/spi-mockup.c:361:18: warning: 'spi_mockup_attr_flags' defined but not used [-Wunused-variable]
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
drivers/spi/spi-mockup.c:365:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
365 | SPI_MOCKUP_ATTR(u16, flags)
| ^~~~~~~~~~~~~~~
>> drivers/spi/spi-mockup.c:361:18: warning: 'spi_mockup_attr_max_speed' defined but not used [-Wunused-variable]
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
drivers/spi/spi-mockup.c:364:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
364 | SPI_MOCKUP_ATTR(u32, max_speed)
| ^~~~~~~~~~~~~~~
>> drivers/spi/spi-mockup.c:361:18: warning: 'spi_mockup_attr_min_speed' defined but not used [-Wunused-variable]
361 | CONFIGFS_ATTR_WO(spi_mockup_, name) \
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
drivers/spi/spi-mockup.c:363:1: note: in expansion of macro 'SPI_MOCKUP_ATTR'
363 | SPI_MOCKUP_ATTR(u32, min_speed)
| ^~~~~~~~~~~~~~~
>> drivers/spi/spi-mockup.c:336:18: warning: 'spi_mockup_attr_disable' defined but not used [-Wunused-variable]
336 | CONFIGFS_ATTR_WO(spi_mockup_, disable);
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
>> drivers/spi/spi-mockup.c:316:18: warning: 'spi_mockup_attr_enable' defined but not used [-Wunused-variable]
316 | CONFIGFS_ATTR_WO(spi_mockup_, enable);
| ^~~~~~~~~~~
include/linux/configfs.h:141:34: note: in definition of macro 'CONFIGFS_ATTR_WO'
141 | static struct configfs_attribute _pfx##attr_##_name = { \
| ^~~~
Kconfig warnings: (for reference only)
WARNING: unmet direct dependencies detected for BPF_EVENTS
Depends on [n]: FTRACE [=n] && BPF_SYSCALL [=y] && (KPROBE_EVENTS [=n] || UPROBE_EVENTS [=n]) && PERF_EVENTS [=n]
Selected by [y]:
- SPI_MOCKUP [=y] && SPI [=y] && SPI_MASTER [=y] && OF [=y]
vim +/spi_mockup_attr_num_cs +361 drivers/spi/spi-mockup.c
287
288 static ssize_t
289 spi_mockup_enable_store(struct config_item *item, const char *page, size_t len)
290 {
291 int ret = len;
292 struct platform_device_info pdevinfo = {0};
293 struct spi_mockup_device *dev = to_spi_mockup_dev(item);
294
295 mutex_lock(&dev->lock);
296 if (dev->pdev) {
297 ret = -EEXIST;
298 goto out;
299 }
300
301 pdevinfo.name = "spi-mockup";
302 pdevinfo.id = dev->bus_nr;
303 pdevinfo.data = &dev->data;
304 pdevinfo.size_data = sizeof(dev->data);
305
306 dev->pdev = platform_device_register_full(&pdevinfo);
307 if (IS_ERR(dev->pdev)) {
308 ret = PTR_ERR(dev->pdev);
309 dev->pdev = NULL;
310 goto out;
311 }
312 out:
313 mutex_unlock(&dev->lock);
314 return ret;
315 }
> 316 CONFIGFS_ATTR_WO(spi_mockup_, enable);
317
318 static ssize_t
319 spi_mockup_disable_store(struct config_item *item, const char *page, size_t len)
320 {
321 int ret = len;
322 struct spi_mockup_device *dev = to_spi_mockup_dev(item);
323
324 mutex_lock(&dev->lock);
325 if (!dev->pdev) {
326 ret = -ENODEV;
327 goto out;
328 }
329
330 platform_device_unregister(dev->pdev);
331 dev->pdev = NULL;
332 out:
333 mutex_unlock(&dev->lock);
334 return ret;
335 }
> 336 CONFIGFS_ATTR_WO(spi_mockup_, disable);
337
338 #define SPI_MOCKUP_ATTR(type, name) \
339 static ssize_t spi_mockup_ ## name ## _store(struct config_item *item, \
340 const char *page, size_t len) \
341 { \
342 int ret; \
343 type val; \
344 struct spi_mockup_device *dev = to_spi_mockup_dev(item); \
345 \
346 mutex_lock(&dev->lock); \
347 if (dev->pdev) { \
348 ret = -EBUSY; \
349 goto out; \
350 } \
351 \
352 ret = kstrto ## type(page, 0, &val); \
353 if (ret) \
354 goto out; \
355 \
356 dev->data.name = val; \
357 out: \
358 mutex_unlock(&dev->lock); \
359 return ret ? ret : len; \
360 } \
> 361 CONFIGFS_ATTR_WO(spi_mockup_, name) \
362
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Sat, Nov 04, 2023 at 02:46:46PM +0800, Zhang Xiaoxu wrote:
> This is accomplished by executing the following command:
>
> $ echo adcxx1s 0 > /sys/class/spi_master/spi0/new_device
That's not a valid sysfs format, sysfs requires one value per file.
configfs might be a better fit?
> +config SPI_MOCKUP
> + tristate "SPI controller Testing Driver"
> + depends on OF
Why would this depend on DT? Given that any test SPI controller is a
virtual device it should never appear in DT and we probably shouldn't
require providing DT for the created devices even if we implement
support for that, only some devices might care.
`
> +++ b/drivers/spi/spi-mockup.c
> @@ -0,0 +1,211 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * SPI controller Testing Driver
> + *
> + * Copyright(c) 2022 Huawei Technologies Co., Ltd.
> + */
Please keep the entire comment a C++ one so things look more
intentional.
> +#define MOCKUP_CHIPSELECT_MAX 8
Why would we have a hard coded limit here?
> + blank = strchr(buf, ' ');
> + if (!blank) {
> + dev_err(dev, "%s: Extra parameters\n", "new_device");
> + return -EINVAL;
> + }
There is no point in using %s to render a constant string.
> +static const struct of_device_id spi_mockup_match[] = {
> + { .compatible = "spi-mockup", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, spi_mockup_match);
If we were going to instantiate this via DT we'd need a binding, but as
I indicated above since this is purely virtual and not even something
like virtual hardware provided by a VMM but rather just something kernel
internal we should probably not be using DT at all. Providing a device
facing DT interface might be useful, but that's a second stage thing.
Hi Mark,
Thanks for your review.
Most of the comments have been modified. and the v4 has been sent
to the maillist, as has the KDDV (Kernel Device Driver Verfication)
test framework based on python unittests.
Looking forward for your comments.
Thanks.
在 2023/11/6 19:59, Mark Brown 写道:
> On Sat, Nov 04, 2023 at 02:46:46PM +0800, Zhang Xiaoxu wrote:
>
>> This is accomplished by executing the following command:
>>
>> $ echo adcxx1s 0 > /sys/class/spi_master/spi0/new_device
>
> That's not a valid sysfs format, sysfs requires one value per file.
> configfs might be a better fit?
>
>> +config SPI_MOCKUP
>> + tristate "SPI controller Testing Driver"
>> + depends on OF
>
> Why would this depend on DT? Given that any test SPI controller is a
> virtual device it should never appear in DT and we probably shouldn't
> require providing DT for the created devices even if we implement
> support for that, only some devices might care.
> `
>> +++ b/drivers/spi/spi-mockup.c
>> @@ -0,0 +1,211 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * SPI controller Testing Driver
>> + *
>> + * Copyright(c) 2022 Huawei Technologies Co., Ltd.
>> + */
>
> Please keep the entire comment a C++ one so things look more
> intentional.
>
>> +#define MOCKUP_CHIPSELECT_MAX 8
>
> Why would we have a hard coded limit here?
When register the spi controller, we need to specify the maximun
number of chips. Modify it to U16_MAX in next version.
>
>> + blank = strchr(buf, ' ');
>> + if (!blank) {
>> + dev_err(dev, "%s: Extra parameters\n", "new_device");
>> + return -EINVAL;
>> + }
>
> There is no point in using %s to render a constant string.
>
>> +static const struct of_device_id spi_mockup_match[] = {
>> + { .compatible = "spi-mockup", },
>> + { }
>> +};
>> +MODULE_DEVICE_TABLE(of, spi_mockup_match);
>
> If we were going to instantiate this via DT we'd need a binding, but as
> I indicated above since this is purely virtual and not even something
> like virtual hardware provided by a VMM but rather just something kernel
> internal we should probably not be using DT at all. Providing a device
> facing DT interface might be useful, but that's a second stage thing.