[U-Boot] [PATCH v3 2/7] dm: serial: Introduce ->getinfo() callback

Andy Shevchenko andriy.shevchenko at linux.intel.com
Tue Nov 20 21:52:33 UTC 2018


New callback will give a necessary information to fill up ACPI SPCR table,
for example. Maybe used later for other purposes.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
 drivers/serial/sandbox.c       | 21 ++++++++++++++++++
 drivers/serial/serial-uclass.c | 21 ++++++++++++++++++
 include/common.h               |  3 +++
 include/serial.h               | 40 ++++++++++++++++++++++++++++++++++
 test/dm/serial.c               |  5 +++++
 5 files changed, 90 insertions(+)

diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 76d26d3c59..c510a6ed36 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -188,6 +188,26 @@ static int sandbox_serial_setconfig(struct udevice *dev, uint serial_config)
 	return 0;
 }
 
+static int sandbox_serial_getinfo(struct udevice *dev,
+				  struct serial_device_info *serial_info)
+{
+	struct serial_device_info info = {
+		.type = SERIAL_CHIP_UNKNOWN,
+		.addr_space = ADR_SPACE_SYSTEM_IO,
+		.addr = SERIAL_DEFAULT_ADDRESS,
+		.reg_width = 1,
+		.reg_offset = 0,
+		.reg_shift = 0,
+	};
+
+	if (!serial_info)
+		return -EINVAL;
+
+	*serial_info = info;
+
+	return 0;
+}
+
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 static const char * const ansi_colour[] = {
 	"black", "red", "green", "yellow", "blue", "megenta", "cyan",
@@ -221,6 +241,7 @@ static const struct dm_serial_ops sandbox_serial_ops = {
 	.getc = sandbox_serial_getc,
 	.getconfig = sandbox_serial_getconfig,
 	.setconfig = sandbox_serial_setconfig,
+	.getinfo = sandbox_serial_getinfo,
 };
 
 static const struct udevice_id sandbox_serial_ids[] = {
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index d5a3b1255f..8dc8a6788d 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -322,6 +322,25 @@ int serial_setconfig(uint config)
 	return 0;
 }
 
+int serial_getinfo(struct serial_device_info *info)
+{
+	struct dm_serial_ops *ops;
+
+	if (!gd->cur_serial_dev)
+		return -ENODEV;
+
+	if (!info)
+		return -EINVAL;
+
+	info->baudrate = gd->baudrate;
+
+	ops = serial_get_ops(gd->cur_serial_dev);
+	if (ops->getinfo)
+		return ops->getinfo(gd->cur_serial_dev, info);
+
+	return -EINVAL;
+}
+
 void serial_stdio_init(void)
 {
 }
@@ -441,6 +460,8 @@ static int serial_post_probe(struct udevice *dev)
 	if (ops->loop)
 		ops->loop += gd->reloc_off;
 #endif
+	if (ops->getinfo)
+		ops->getinfo += gd->reloc_off;
 #endif
 	/* Set the baud rate */
 	if (ops->setbrg) {
diff --git a/include/common.h b/include/common.h
index 675495bde5..ea1fef0b24 100644
--- a/include/common.h
+++ b/include/common.h
@@ -349,6 +349,8 @@ void smp_set_core_boot_addr(unsigned long addr, int corenr);
 void smp_kick_all_cpus(void);
 
 /* $(CPU)/serial.c */
+struct serial_device_info;
+
 int	serial_init   (void);
 void	serial_setbrg (void);
 void	serial_putc   (const char);
@@ -358,6 +360,7 @@ int	serial_getc   (void);
 int	serial_tstc   (void);
 int	serial_getconfig(uint *config);
 int	serial_setconfig(uint config);
+int	serial_getinfo(struct serial_device_info *info);
 
 /* $(CPU)/speed.c */
 int	get_clocks (void);
diff --git a/include/serial.h b/include/serial.h
index bc6d28ea86..ca549d45aa 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -118,6 +118,39 @@ enum serial_stop {
 			 SERIAL_8_BITS << SERIAL_BITS_SHIFT | \
 			 SERIAL_ONE_STOP << SERIAL_STOP_SHIFT)
 
+enum serial_chip_type {
+	SERIAL_CHIP_UNKNOWN = -1,
+	SERIAL_CHIP_16550_COMPATIBLE,
+};
+
+enum adr_space_type {
+	SERIAL_ADDRESS_SPACE_MEMORY = 0,
+	SERIAL_ADDRESS_SPACE_IO,
+};
+
+/**
+ * struct serial_device_info - structure to hold serial device info
+ *
+ * @type:	type of the UART chip
+ * @addr_space:	address space to access the registers
+ * @addr:	physical address of the registers
+ * @reg_width:	size (in bytes) of the IO accesses to the registers
+ * @reg_offset:	offset to apply to the @addr from the start of the registers
+ * @reg_shift:	quantity to shift the register offsets by
+ * @baudrate:	baud rate
+ */
+struct serial_device_info {
+	enum serial_chip_type type;
+	enum adr_space_type addr_space;
+	ulong addr;
+	u8 reg_width;
+	u8 reg_offset;
+	u8 reg_shift;
+	unsigned int baudrate;
+};
+
+#define SERIAL_DEFAULT_ADDRESS	0xBADACCE5
+
 /**
  * struct struct dm_serial_ops - Driver model serial operations
  *
@@ -221,6 +254,13 @@ struct dm_serial_ops {
 	 * @return 0 if OK, -ve on error
 	 */
 	int (*setconfig)(struct udevice *dev, uint serial_config);
+	/**
+	 * getinfo() - Get serial device information
+	 *
+	 * @dev: Device pointer
+	 * @info: struct serial_device_info to fill
+	 */
+	int (*getinfo)(struct udevice *dev, struct serial_device_info *info);
 };
 
 /**
diff --git a/test/dm/serial.c b/test/dm/serial.c
index 7a1a1526a4..19a15d5d95 100644
--- a/test/dm/serial.c
+++ b/test/dm/serial.c
@@ -11,6 +11,7 @@
 
 static int dm_test_serial(struct unit_test_state *uts)
 {
+	struct serial_device_info info_serial = {0};
 	struct udevice *dev_serial;
 	uint value_serial;
 
@@ -25,10 +26,14 @@ static int dm_test_serial(struct unit_test_state *uts)
 	ut_assertok(serial_setconfig(SERIAL_DEFAULT_CONFIG));
 	ut_assertok(serial_getconfig(&value_serial));
 	ut_assert(value_serial == SERIAL_DEFAULT_CONFIG);
+	ut_assertok(serial_getinfo(&info_serial));
+	ut_assert(info_serial.type == SERIAL_CHIP_UNKNOWN);
+	ut_assert(info_serial.addr == SERIAL_DEFAULT_ADDRESS);
 	/*
 	 * test with a parameter which is NULL pointer
 	 */
 	ut_asserteq(-EINVAL, serial_getconfig(NULL));
+	ut_asserteq(-EINVAL, serial_getinfo(NULL));
 	/*
 	 * test with a serial config which is not supported by
 	 * sandbox_serial driver: test with wrong parity
-- 
2.19.1



More information about the U-Boot mailing list