[U-Boot] [PATCH v2 18/34] pch: Add ioctl support

Simon Glass sjg at chromium.org
Sun Feb 17 03:24:51 UTC 2019


At present the PCH has 4 operations and these are reasonably widely used
in the drivers. But sometimes we want to add rarely used operations, and
each of these currently adds to the size of the PCH operations table.

Add an ioctl() method which can be easily expanded without any more impact
on the operations table.

Signed-off-by: Simon Glass <sjg at chromium.org>
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>
---

Changes in v2:
- Fix comment about @return value in ioctl() method and function

 drivers/pch/pch-uclass.c  | 10 ++++++++
 drivers/pch/sandbox_pch.c | 17 ++++++++++++++
 include/pch.h             | 48 ++++++++++++++++++++++++++++++++++++++-
 test/dm/pch.c             | 19 ++++++++++++++++
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/pch/pch-uclass.c b/drivers/pch/pch-uclass.c
index 831b283d7b4..caf8b72803c 100644
--- a/drivers/pch/pch-uclass.c
+++ b/drivers/pch/pch-uclass.c
@@ -51,6 +51,16 @@ int pch_get_io_base(struct udevice *dev, u32 *iobasep)
 	return ops->get_io_base(dev, iobasep);
 }
 
+int pch_ioctl(struct udevice *dev, ulong req, void *data, int size)
+{
+	struct pch_ops *ops = pch_get_ops(dev);
+
+	if (!ops->ioctl)
+		return -ENOSYS;
+
+	return ops->ioctl(dev, req, data, size);
+}
+
 UCLASS_DRIVER(pch) = {
 	.id		= UCLASS_PCH,
 	.name		= "pch",
diff --git a/drivers/pch/sandbox_pch.c b/drivers/pch/sandbox_pch.c
index 004de901ac7..01ff3bed351 100644
--- a/drivers/pch/sandbox_pch.c
+++ b/drivers/pch/sandbox_pch.c
@@ -48,11 +48,28 @@ static int sandbox_pch_get_io_base(struct udevice *dev, u32 *iobasep)
 	return 0;
 }
 
+int sandbox_pch_ioctl(struct udevice *dev, enum pch_req_t req, void *data,
+		      int size)
+{
+	switch (req) {
+	case PCH_REQ_TEST1:
+		return -ENOSYS;
+	case PCH_REQ_TEST2:
+		return *(char *)data;
+	case PCH_REQ_TEST3:
+		*(char *)data = 'x';
+		return 1;
+	default:
+		return -ENOSYS;
+	}
+}
+
 static const struct pch_ops sandbox_pch_ops = {
 	.get_spi_base	= sandbox_pch_get_spi_base,
 	.set_spi_protect = sandbox_pch_set_spi_protect,
 	.get_gpio_base	= sandbox_pch_get_gpio_base,
 	.get_io_base = sandbox_pch_get_io_base,
+	.ioctl		= sandbox_pch_ioctl,
 };
 
 static const struct udevice_id sandbox_pch_ids[] = {
diff --git a/include/pch.h b/include/pch.h
index 73994b8343f..b8b62d74acb 100644
--- a/include/pch.h
+++ b/include/pch.h
@@ -11,7 +11,20 @@
 
 #define BIOS_CTRL_BIOSWE	BIT(0)
 
-/* Operations for the Platform Controller Hub */
+/* All the supported PCH ioctls */
+enum pch_req_t {
+	PCH_REQ_TEST1,		/* Test requests for sandbox driver */
+	PCH_REQ_TEST2,
+	PCH_REQ_TEST3,
+
+	PCH_REQ_COUNT,		/* Number of ioctrls supported */
+};
+
+/**
+ * struct pch_ops - Operations for the Platform Controller Hub
+ *
+ * Consider using ioctl() to add rarely used or driver-specific operations.
+ */
 struct pch_ops {
 	/**
 	 * get_spi_base() - get the address of SPI base
@@ -49,6 +62,23 @@ struct pch_ops {
 	 * @return 0 if OK, -ve on error (e.g. there is no IO base)
 	 */
 	int (*get_io_base)(struct udevice *dev, u32 *iobasep);
+
+	/**
+	 * ioctl() - perform misc read/write operations
+	 *
+	 * This is a catch-all operation intended to avoid adding lots of
+	 * methods to this uclass, of which few are commonly used. Uncommon
+	 * operations that pertain only to a few devices in this uclass should
+	 * use this method instead of adding new methods.
+	 *
+	 * @dev:	PCH device to check
+	 * @req:	PCH request ID
+	 * @data:	Input/output data
+	 * @size:	Size of input data (and maximum size of output data)
+	 * @return size of output data on sucesss, -ve on error
+	 */
+	int (*ioctl)(struct udevice *dev, enum pch_req_t req, void *data,
+		     int size);
 };
 
 #define pch_get_ops(dev)        ((struct pch_ops *)(dev)->driver->ops)
@@ -90,4 +120,20 @@ int pch_get_gpio_base(struct udevice *dev, u32 *gbasep);
  */
 int pch_get_io_base(struct udevice *dev, u32 *iobasep);
 
+/**
+ * pch_ioctl() - perform misc read/write operations
+ *
+ * This is a catch-all operation intended to avoid adding lots of
+ * methods to this uclass, of which few are commonly used. Uncommon
+ * operations that pertain only to a few devices in this uclass should
+ * use this method instead of adding new methods.
+ *
+ * @dev:	PCH device to check
+ * @req:	PCH request ID
+ * @data:	Input/output data
+ * @size:	Size of input data (and maximum size of output data)
+ * @return size of output data on sucesss, -ve on error
+ */
+int pch_ioctl(struct udevice *dev, ulong req, void *data, int size);
+
 #endif
diff --git a/test/dm/pch.c b/test/dm/pch.c
index f184445342b..54e33d187b6 100644
--- a/test/dm/pch.c
+++ b/test/dm/pch.c
@@ -34,3 +34,22 @@ static int dm_test_pch_base(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_pch_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test sandbox PCH ioctl */
+static int dm_test_pch_ioctl(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+	char data;
+
+	ut_assertok(uclass_first_device_err(UCLASS_PCH, &dev));
+
+	ut_asserteq(-ENOSYS, pch_ioctl(dev, PCH_REQ_TEST1, NULL, 0));
+
+	ut_asserteq('a', pch_ioctl(dev, PCH_REQ_TEST2, "a", 1));
+
+	ut_asserteq(1, pch_ioctl(dev, PCH_REQ_TEST3, &data, 1));
+	ut_asserteq('x', data);
+
+	return 0;
+}
+DM_TEST(dm_test_pch_ioctl, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.21.0.rc0.258.g878e2cd30e-goog



More information about the U-Boot mailing list