Message ID | 81e37f79d335d17d8802f127d59f89e263c50136.1532701430.git.damien.hedde@greensocs.com |
---|---|
State | New |
Headers | show |
Series | Clock and power gating support | expand |
On 07/27/2018 11:37 AM, Damien Hedde wrote: > Only discard input characters when unpowered/unclocked. > As it is a sysbus device, mmio are already disabled when unpowered > or unclocked. This is common to all Chardev frontends (also Ethernet/CAN devices, see NetClientInfo). Maybe qemu_chr_fe_accept_input() can take a boolean, so when we disable a device (power/clock), the char-fe code can discard characters for all frontends? > > Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> > --- > hw/char/cadence_uart.c | 25 ++++++++++++++++++++++++- > 1 file changed, 24 insertions(+), 1 deletion(-) > > diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c > index fbdbd463bb..dd51d9a087 100644 > --- a/hw/char/cadence_uart.c > +++ b/hw/char/cadence_uart.c > @@ -335,8 +335,14 @@ static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf, > static void uart_receive(void *opaque, const uint8_t *buf, int size) > { > CadenceUARTState *s = opaque; > + DeviceState *dev = DEVICE(s); > uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE; > > + /* ignore characters if unpowered or unclocked */ > + if (!dev->powered || !dev->clocked) { > + return; > + } > + > if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) { > uart_write_rx_fifo(opaque, buf, size); > } > @@ -348,8 +354,14 @@ static void uart_receive(void *opaque, const uint8_t *buf, int size) > static void uart_event(void *opaque, int event) > { > CadenceUARTState *s = opaque; > + DeviceState *dev = DEVICE(s); > uint8_t buf = '\0'; > > + /* ignore event if we're unpowered or unclocked */ > + if (!dev->powered || !dev->clocked) { > + return; > + } > + > if (event == CHR_EVENT_BREAK) { > uart_write_rx_fifo(opaque, &buf, 1); > } > @@ -516,10 +528,19 @@ static int cadence_uart_post_load(void *opaque, int version_id) > return 0; > } > > +static int cadence_uart_pre_load(void *opaque) > +{ > + DeviceState *s = opaque; > + s->clocked = true; > + s->powered = true; > + return 0; > +} > + > static const VMStateDescription vmstate_cadence_uart = { > .name = "cadence_uart", > - .version_id = 2, > + .version_id = 3, > .minimum_version_id = 2, > + .pre_load = cadence_uart_pre_load, > .post_load = cadence_uart_post_load, > .fields = (VMStateField[]) { > VMSTATE_UINT32_ARRAY(r, CadenceUARTState, CADENCE_UART_R_MAX), > @@ -531,6 +552,8 @@ static const VMStateDescription vmstate_cadence_uart = { > VMSTATE_UINT32(tx_count, CadenceUARTState), > VMSTATE_UINT32(rx_wpos, CadenceUARTState), > VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState), > + VMSTATE_BOOL_V(powered, DeviceState, 3), > + VMSTATE_BOOL_V(clocked, DeviceState, 3), > VMSTATE_END_OF_LIST() > } > }; >
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index fbdbd463bb..dd51d9a087 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -335,8 +335,14 @@ static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf, static void uart_receive(void *opaque, const uint8_t *buf, int size) { CadenceUARTState *s = opaque; + DeviceState *dev = DEVICE(s); uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE; + /* ignore characters if unpowered or unclocked */ + if (!dev->powered || !dev->clocked) { + return; + } + if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) { uart_write_rx_fifo(opaque, buf, size); } @@ -348,8 +354,14 @@ static void uart_receive(void *opaque, const uint8_t *buf, int size) static void uart_event(void *opaque, int event) { CadenceUARTState *s = opaque; + DeviceState *dev = DEVICE(s); uint8_t buf = '\0'; + /* ignore event if we're unpowered or unclocked */ + if (!dev->powered || !dev->clocked) { + return; + } + if (event == CHR_EVENT_BREAK) { uart_write_rx_fifo(opaque, &buf, 1); } @@ -516,10 +528,19 @@ static int cadence_uart_post_load(void *opaque, int version_id) return 0; } +static int cadence_uart_pre_load(void *opaque) +{ + DeviceState *s = opaque; + s->clocked = true; + s->powered = true; + return 0; +} + static const VMStateDescription vmstate_cadence_uart = { .name = "cadence_uart", - .version_id = 2, + .version_id = 3, .minimum_version_id = 2, + .pre_load = cadence_uart_pre_load, .post_load = cadence_uart_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(r, CadenceUARTState, CADENCE_UART_R_MAX), @@ -531,6 +552,8 @@ static const VMStateDescription vmstate_cadence_uart = { VMSTATE_UINT32(tx_count, CadenceUARTState), VMSTATE_UINT32(rx_wpos, CadenceUARTState), VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState), + VMSTATE_BOOL_V(powered, DeviceState, 3), + VMSTATE_BOOL_V(clocked, DeviceState, 3), VMSTATE_END_OF_LIST() } };
Only discard input characters when unpowered/unclocked. As it is a sysbus device, mmio are already disabled when unpowered or unclocked. Signed-off-by: Damien Hedde <damien.hedde@greensocs.com> --- hw/char/cadence_uart.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)