dm: serial: Introduce ->getinfo() callback
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 20 Nov 2018 21:52:33 +0000 (23:52 +0200)
committerSimon Glass <sjg@chromium.org>
Wed, 5 Dec 2018 13:08:31 +0000 (06:08 -0700)
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@linux.intel.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Change ADR_SPACE_SYSTEM_IO to SERIAL_ADDRESS_SPACE_IO to fix build error:
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/serial/sandbox.c
drivers/serial/serial-uclass.c
include/common.h
include/serial.h
test/dm/serial.c

index 76d26d3c59e364e53d33cd59f5ab43841eefd1b0..33102fc872f20fd1b1533403ed9c33022fc7df41 100644 (file)
@@ -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[] = {
index 51ae1763fb6280dbbb66110aa7f71594ed67373c..ffcd6d15af2b07049fc5973a68c4478b2fc510ce 100644 (file)
@@ -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) {
index 57478365c7c253d7e99ec368462de852bae91049..20c99da1aa95194284c76d073d87aaeaf890e335 100644 (file)
@@ -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);
index de21514c0c0d93a1a84f070a6fed6a6004128842..c1a9fee250e93456b25138d6a6966e81c94a2b8d 100644 (file)
@@ -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);
 };
 
 /**
index 7a1a1526a448f34ee899876bef6aabdf6bf242f2..19a15d5d95235d21f82cbbae3cf796dba7bcdc91 100644 (file)
@@ -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