dm: serial: Add ->getconfig() callback
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 20 Nov 2018 21:52:32 +0000 (23:52 +0200)
committerSimon Glass <sjg@chromium.org>
Wed, 5 Dec 2018 13:06:44 +0000 (06:06 -0700)
In some cases it would be good to know the settings, such as parity,
of current serial console. One example might be an ACPI SPCR table
to generate using these parameters.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-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 4a05ea44ce99fed335c722fb5791f5c27b5bbb8e..76d26d3c59e364e53d33cd59f5ab43841eefd1b0 100644 (file)
@@ -163,6 +163,18 @@ DEBUG_UART_FUNCS
 
 #endif /* CONFIG_DEBUG_UART_SANDBOX */
 
+static int sandbox_serial_getconfig(struct udevice *dev, uint *serial_config)
+{
+       uint config = SERIAL_DEFAULT_CONFIG;
+
+       if (!serial_config)
+               return -EINVAL;
+
+       *serial_config = config;
+
+       return 0;
+}
+
 static int sandbox_serial_setconfig(struct udevice *dev, uint serial_config)
 {
        u8 parity = SERIAL_GET_PARITY(serial_config);
@@ -207,6 +219,7 @@ static const struct dm_serial_ops sandbox_serial_ops = {
        .putc = sandbox_serial_putc,
        .pending = sandbox_serial_pending,
        .getc = sandbox_serial_getc,
+       .getconfig = sandbox_serial_getconfig,
        .setconfig = sandbox_serial_setconfig,
 };
 
index 3ded62732d4b21324cd981153b71aee22a99a496..51ae1763fb6280dbbb66110aa7f71594ed67373c 100644 (file)
@@ -294,6 +294,20 @@ void serial_setbrg(void)
                ops->setbrg(gd->cur_serial_dev, gd->baudrate);
 }
 
+int serial_getconfig(uint *config)
+{
+       struct dm_serial_ops *ops;
+
+       if (!gd->cur_serial_dev)
+               return 0;
+
+       ops = serial_get_ops(gd->cur_serial_dev);
+       if (ops->getconfig)
+               return ops->getconfig(gd->cur_serial_dev, config);
+
+       return 0;
+}
+
 int serial_setconfig(uint config)
 {
        struct dm_serial_ops *ops;
@@ -419,6 +433,8 @@ static int serial_post_probe(struct udevice *dev)
                ops->pending += gd->reloc_off;
        if (ops->clear)
                ops->clear += gd->reloc_off;
+       if (ops->getconfig)
+               ops->getconfig += gd->reloc_off;
        if (ops->setconfig)
                ops->setconfig += gd->reloc_off;
 #if CONFIG_POST & CONFIG_SYS_POST_UART
index a8e879e1b9a5a011c8df9a4690367c9228cb238e..57478365c7c253d7e99ec368462de852bae91049 100644 (file)
@@ -364,6 +364,7 @@ void        serial_putc_raw(const char);
 void   serial_puts   (const char *);
 int    serial_getc   (void);
 int    serial_tstc   (void);
+int    serial_getconfig(uint *config);
 int    serial_setconfig(uint config);
 
 /* $(CPU)/speed.c */
index 9133d07fd519cc1747f3f2b7d1b6d8a723e0dfed..de21514c0c0d93a1a84f070a6fed6a6004128842 100644 (file)
@@ -75,6 +75,8 @@ enum serial_par {
 
 #define SERIAL_PAR_SHIFT       0
 #define SERIAL_PAR_MASK                (0x03 << SERIAL_PAR_SHIFT)
+#define SERIAL_SET_PARITY(parity) \
+       ((parity << SERIAL_PAR_SHIFT) & SERIAL_PAR_MASK)
 #define SERIAL_GET_PARITY(config) \
        ((config & SERIAL_PAR_MASK) >> SERIAL_PAR_SHIFT)
 
@@ -87,6 +89,8 @@ enum serial_bits {
 
 #define SERIAL_BITS_SHIFT      2
 #define SERIAL_BITS_MASK       (0x3 << SERIAL_BITS_SHIFT)
+#define SERIAL_SET_BITS(bits) \
+       ((bits << SERIAL_BITS_SHIFT) & SERIAL_BITS_MASK)
 #define SERIAL_GET_BITS(config) \
        ((config & SERIAL_BITS_MASK) >> SERIAL_BITS_SHIFT)
 
@@ -99,6 +103,8 @@ enum serial_stop {
 
 #define SERIAL_STOP_SHIFT      4
 #define SERIAL_STOP_MASK       (0x3 << SERIAL_STOP_SHIFT)
+#define SERIAL_SET_STOP(stop) \
+       ((stop << SERIAL_STOP_SHIFT) & SERIAL_STOP_MASK)
 #define SERIAL_GET_STOP(config) \
        ((config & SERIAL_STOP_MASK) >> SERIAL_STOP_SHIFT)
 
@@ -107,9 +113,10 @@ enum serial_stop {
                      bits << SERIAL_BITS_SHIFT | \
                      stop << SERIAL_STOP_SHIFT)
 
-#define SERIAL_DEFAULT_CONFIG  SERIAL_PAR_NONE << SERIAL_PAR_SHIFT | \
-                               SERIAL_8_BITS << SERIAL_BITS_SHIFT | \
-                               SERIAL_ONE_STOP << SERIAL_STOP_SHIFT
+#define SERIAL_DEFAULT_CONFIG \
+                       (SERIAL_PAR_NONE << SERIAL_PAR_SHIFT | \
+                        SERIAL_8_BITS << SERIAL_BITS_SHIFT | \
+                        SERIAL_ONE_STOP << SERIAL_STOP_SHIFT)
 
 /**
  * struct struct dm_serial_ops - Driver model serial operations
@@ -188,6 +195,19 @@ struct dm_serial_ops {
        int (*loop)(struct udevice *dev, int on);
 #endif
 
+       /**
+        * getconfig() - Get the uart configuration
+        * (parity, 5/6/7/8 bits word length, stop bits)
+        *
+        * Get a current config for this device.
+        *
+        * @dev: Device pointer
+        * @parity: parity to use
+        * @bits: bits number to use
+        * @stop: stop bits number to use
+        * @return 0 if OK, -ve on error
+        */
+       int (*getconfig)(struct udevice *dev, uint *serial_config);
        /**
         * setconfig() - Set up the uart configuration
         * (parity, 5/6/7/8 bits word length, stop bits)
index 5c603e1f42e9a4996131ed063681576ae0c69c7c..7a1a1526a448f34ee899876bef6aabdf6bf242f2 100644 (file)
@@ -12,6 +12,7 @@
 static int dm_test_serial(struct unit_test_state *uts)
 {
        struct udevice *dev_serial;
+       uint value_serial;
 
        ut_assertok(uclass_get_device_by_name(UCLASS_SERIAL, "serial",
                                              &dev_serial));
@@ -22,6 +23,12 @@ static int dm_test_serial(struct unit_test_state *uts)
         * sandbox_serial driver
         */
        ut_assertok(serial_setconfig(SERIAL_DEFAULT_CONFIG));
+       ut_assertok(serial_getconfig(&value_serial));
+       ut_assert(value_serial == SERIAL_DEFAULT_CONFIG);
+       /*
+        * test with a parameter which is NULL pointer
+        */
+       ut_asserteq(-EINVAL, serial_getconfig(NULL));
        /*
         * test with a serial config which is not supported by
         * sandbox_serial driver: test with wrong parity