summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/sandbox.c21
-rw-r--r--drivers/serial/serial-uclass.c21
-rw-r--r--include/common.h3
-rw-r--r--include/serial.h40
-rw-r--r--test/dm/serial.c5
5 files changed, 90 insertions, 0 deletions
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 76d26d3c59..33102fc872 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 = SERIAL_ADDRESS_SPACE_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 51ae1763fb..ffcd6d15af 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 57478365c7..20c99da1aa 100644
--- a/include/common.h
+++ b/include/common.h
@@ -357,6 +357,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);
@@ -366,6 +368,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 de21514c0c..c1a9fee250 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
*
@@ -219,6 +252,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