dm: serial: Add ->getconfig() callback

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>
This commit is contained in:
Andy Shevchenko 2018-11-20 23:52:32 +02:00 committed by Simon Glass
parent 4f86a724e8
commit ac7f5db9dc
5 changed files with 60 additions and 3 deletions

View 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,
};

View 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

View 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 */

View 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)

View 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