drivers: serial: pl011: drop usage of uart_device_config

Create a driver specific configuration structure, containing the
required fields only. Since the config struct can now store a pointer to
the UART structure, casts from address to (struct pl011_regs *) are no
longer needed. PL011_REGS has also been dropped in favor of using the
config pointer directly now that it is possible.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2022-01-25 20:08:47 +01:00 committed by Anas Nashif
commit cb982cd669

View file

@ -39,6 +39,14 @@ struct pl011_regs {
uint32_t dmacr; uint32_t dmacr;
}; };
struct pl011_config {
volatile struct pl011_regs *uart;
uint32_t sys_clk_freq;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_config_func_t irq_config_func;
#endif
};
/* Device data structure */ /* Device data structure */
struct pl011_data { struct pl011_data {
uint32_t baud_rate; /* Baud rate */ uint32_t baud_rate; /* Baud rate */
@ -142,33 +150,39 @@ struct pl011_data {
PL011_IMSC_RXIM | PL011_IMSC_TXIM | \ PL011_IMSC_RXIM | PL011_IMSC_TXIM | \
PL011_IMSC_RTIM) PL011_IMSC_RTIM)
#define PL011_REGS(dev) \
((volatile struct pl011_regs *) \
((const struct uart_device_config * const)(dev)->config)->base)
static void pl011_enable(const struct device *dev) static void pl011_enable(const struct device *dev)
{ {
PL011_REGS(dev)->cr |= PL011_CR_UARTEN; const struct pl011_config *config = dev->config;
config->uart->cr |= PL011_CR_UARTEN;
} }
static void pl011_disable(const struct device *dev) static void pl011_disable(const struct device *dev)
{ {
PL011_REGS(dev)->cr &= ~PL011_CR_UARTEN; const struct pl011_config *config = dev->config;
config->uart->cr &= ~PL011_CR_UARTEN;
} }
static void pl011_enable_fifo(const struct device *dev) static void pl011_enable_fifo(const struct device *dev)
{ {
PL011_REGS(dev)->lcr_h |= PL011_LCRH_FEN; const struct pl011_config *config = dev->config;
config->uart->lcr_h |= PL011_LCRH_FEN;
} }
static void pl011_disable_fifo(const struct device *dev) static void pl011_disable_fifo(const struct device *dev)
{ {
PL011_REGS(dev)->lcr_h &= ~PL011_LCRH_FEN; const struct pl011_config *config = dev->config;
config->uart->lcr_h &= ~PL011_LCRH_FEN;
} }
static int pl011_set_baudrate(const struct device *dev, static int pl011_set_baudrate(const struct device *dev,
uint32_t clk, uint32_t baudrate) uint32_t clk, uint32_t baudrate)
{ {
const struct pl011_config *config = dev->config;
/* Avoiding float calculations, bauddiv is left shifted by 6 */ /* Avoiding float calculations, bauddiv is left shifted by 6 */
uint64_t bauddiv = (((uint64_t)clk) << PL011_FBRD_WIDTH) uint64_t bauddiv = (((uint64_t)clk) << PL011_FBRD_WIDTH)
/ (baudrate * 16U); / (baudrate * 16U);
@ -182,8 +196,8 @@ static int pl011_set_baudrate(const struct device *dev,
return -EINVAL; return -EINVAL;
} }
PL011_REGS(dev)->ibrd = bauddiv >> PL011_FBRD_WIDTH; config->uart->ibrd = bauddiv >> PL011_FBRD_WIDTH;
PL011_REGS(dev)->fbrd = bauddiv & ((1u << PL011_FBRD_WIDTH) - 1u); config->uart->fbrd = bauddiv & ((1u << PL011_FBRD_WIDTH) - 1u);
__DMB(); __DMB();
@ -191,56 +205,61 @@ static int pl011_set_baudrate(const struct device *dev,
* lcr_h write must always be performed at the end * lcr_h write must always be performed at the end
* ARM DDI 0183F, Pg 3-13 * ARM DDI 0183F, Pg 3-13
*/ */
PL011_REGS(dev)->lcr_h = PL011_REGS(dev)->lcr_h; config->uart->lcr_h = config->uart->lcr_h;
return 0; return 0;
} }
static bool pl011_is_readable(const struct device *dev) static bool pl011_is_readable(const struct device *dev)
{ {
const struct pl011_config *config = dev->config;
struct pl011_data *data = dev->data; struct pl011_data *data = dev->data;
if (!data->sbsa && if (!data->sbsa &&
(!(PL011_REGS(dev)->cr & PL011_CR_UARTEN) || (!(config->uart->cr & PL011_CR_UARTEN) ||
!(PL011_REGS(dev)->cr & PL011_CR_RXE))) !(config->uart->cr & PL011_CR_RXE)))
return false; return false;
return (PL011_REGS(dev)->fr & PL011_FR_RXFE) == 0U; return (config->uart->fr & PL011_FR_RXFE) == 0U;
} }
static int pl011_poll_in(const struct device *dev, unsigned char *c) static int pl011_poll_in(const struct device *dev, unsigned char *c)
{ {
const struct pl011_config *config = dev->config;
if (!pl011_is_readable(dev)) { if (!pl011_is_readable(dev)) {
return -1; return -1;
} }
/* got a character */ /* got a character */
*c = (unsigned char)PL011_REGS(dev)->dr; *c = (unsigned char)config->uart->dr;
return PL011_REGS(dev)->rsr & PL011_RSR_ERROR_MASK; return config->uart->rsr & PL011_RSR_ERROR_MASK;
} }
static void pl011_poll_out(const struct device *dev, static void pl011_poll_out(const struct device *dev,
unsigned char c) unsigned char c)
{ {
const struct pl011_config *config = dev->config;
/* Wait for space in FIFO */ /* Wait for space in FIFO */
while (PL011_REGS(dev)->fr & PL011_FR_TXFF) { while (config->uart->fr & PL011_FR_TXFF) {
; /* Wait */ ; /* Wait */
} }
/* Send a character */ /* Send a character */
PL011_REGS(dev)->dr = (uint32_t)c; config->uart->dr = (uint32_t)c;
} }
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
static int pl011_fifo_fill(const struct device *dev, static int pl011_fifo_fill(const struct device *dev,
const uint8_t *tx_data, int len) const uint8_t *tx_data, int len)
{ {
const struct pl011_config *config = dev->config;
uint8_t num_tx = 0U; uint8_t num_tx = 0U;
while (!(PL011_REGS(dev)->fr & PL011_FR_TXFF) && while (!(config->uart->fr & PL011_FR_TXFF) && (len - num_tx > 0)) {
(len - num_tx > 0)) { config->uart->dr = tx_data[num_tx++];
PL011_REGS(dev)->dr = tx_data[num_tx++];
} }
return num_tx; return num_tx;
} }
@ -248,11 +267,11 @@ static int pl011_fifo_fill(const struct device *dev,
static int pl011_fifo_read(const struct device *dev, static int pl011_fifo_read(const struct device *dev,
uint8_t *rx_data, const int len) uint8_t *rx_data, const int len)
{ {
const struct pl011_config *config = dev->config;
uint8_t num_rx = 0U; uint8_t num_rx = 0U;
while ((len - num_rx > 0) && while ((len - num_rx > 0) && !(config->uart->fr & PL011_FR_RXFE)) {
!(PL011_REGS(dev)->fr & PL011_FR_RXFE)) { rx_data[num_rx++] = config->uart->dr;
rx_data[num_rx++] = PL011_REGS(dev)->dr;
} }
return num_rx; return num_rx;
@ -260,63 +279,77 @@ static int pl011_fifo_read(const struct device *dev,
static void pl011_irq_tx_enable(const struct device *dev) static void pl011_irq_tx_enable(const struct device *dev)
{ {
PL011_REGS(dev)->imsc |= PL011_IMSC_TXIM; const struct pl011_config *config = dev->config;
config->uart->imsc |= PL011_IMSC_TXIM;
} }
static void pl011_irq_tx_disable(const struct device *dev) static void pl011_irq_tx_disable(const struct device *dev)
{ {
PL011_REGS(dev)->imsc &= ~PL011_IMSC_TXIM; const struct pl011_config *config = dev->config;
config->uart->imsc &= ~PL011_IMSC_TXIM;
} }
static int pl011_irq_tx_complete(const struct device *dev) static int pl011_irq_tx_complete(const struct device *dev)
{ {
const struct pl011_config *config = dev->config;
/* check for TX FIFO empty */ /* check for TX FIFO empty */
return PL011_REGS(dev)->fr & PL011_FR_TXFE; return config->uart->fr & PL011_FR_TXFE;
} }
static int pl011_irq_tx_ready(const struct device *dev) static int pl011_irq_tx_ready(const struct device *dev)
{ {
const struct pl011_config *config = dev->config;
struct pl011_data *data = dev->data; struct pl011_data *data = dev->data;
if (!data->sbsa && !(PL011_REGS(dev)->cr & PL011_CR_TXE)) if (!data->sbsa && !(config->uart->cr & PL011_CR_TXE))
return false; return false;
return ((PL011_REGS(dev)->imsc & PL011_IMSC_TXIM) && return ((config->uart->imsc & PL011_IMSC_TXIM) &&
pl011_irq_tx_complete(dev)); pl011_irq_tx_complete(dev));
} }
static void pl011_irq_rx_enable(const struct device *dev) static void pl011_irq_rx_enable(const struct device *dev)
{ {
PL011_REGS(dev)->imsc |= PL011_IMSC_RXIM | const struct pl011_config *config = dev->config;
PL011_IMSC_RTIM;
config->uart->imsc |= PL011_IMSC_RXIM | PL011_IMSC_RTIM;
} }
static void pl011_irq_rx_disable(const struct device *dev) static void pl011_irq_rx_disable(const struct device *dev)
{ {
PL011_REGS(dev)->imsc &= ~(PL011_IMSC_RXIM | const struct pl011_config *config = dev->config;
PL011_IMSC_RTIM);
config->uart->imsc &= ~(PL011_IMSC_RXIM | PL011_IMSC_RTIM);
} }
static int pl011_irq_rx_ready(const struct device *dev) static int pl011_irq_rx_ready(const struct device *dev)
{ {
const struct pl011_config *config = dev->config;
struct pl011_data *data = dev->data; struct pl011_data *data = dev->data;
if (!data->sbsa && !(PL011_REGS(dev)->cr & PL011_CR_RXE)) if (!data->sbsa && !(config->uart->cr & PL011_CR_RXE))
return false; return false;
return ((PL011_REGS(dev)->imsc & PL011_IMSC_RXIM) && return ((config->uart->imsc & PL011_IMSC_RXIM) &&
(!(PL011_REGS(dev)->fr & PL011_FR_RXFE))); (!(config->uart->fr & PL011_FR_RXFE)));
} }
static void pl011_irq_err_enable(const struct device *dev) static void pl011_irq_err_enable(const struct device *dev)
{ {
const struct pl011_config *config = dev->config;
/* enable framing, parity, break, and overrun */ /* enable framing, parity, break, and overrun */
PL011_REGS(dev)->imsc |= PL011_IMSC_ERROR_MASK; config->uart->imsc |= PL011_IMSC_ERROR_MASK;
} }
static void pl011_irq_err_disable(const struct device *dev) static void pl011_irq_err_disable(const struct device *dev)
{ {
PL011_REGS(dev)->imsc &= ~PL011_IMSC_ERROR_MASK; const struct pl011_config *config = dev->config;
config->uart->imsc &= ~PL011_IMSC_ERROR_MASK;
} }
static int pl011_irq_is_pending(const struct device *dev) static int pl011_irq_is_pending(const struct device *dev)
@ -363,7 +396,7 @@ static const struct uart_driver_api pl011_driver_api = {
static int pl011_init(const struct device *dev) static int pl011_init(const struct device *dev)
{ {
const struct uart_device_config *config = dev->config; const struct pl011_config *config = dev->config;
struct pl011_data *data = dev->data; struct pl011_data *data = dev->data;
int ret; int ret;
uint32_t lcrh; uint32_t lcrh;
@ -386,23 +419,23 @@ static int pl011_init(const struct device *dev)
} }
/* Setting the default character format */ /* Setting the default character format */
lcrh = PL011_REGS(dev)->lcr_h & ~(PL011_LCRH_FORMAT_MASK); lcrh = config->uart->lcr_h & ~(PL011_LCRH_FORMAT_MASK);
lcrh &= ~(BIT(0) | BIT(7)); lcrh &= ~(BIT(0) | BIT(7));
lcrh |= PL011_LCRH_WLEN_SIZE(8) << PL011_LCRH_WLEN_SHIFT; lcrh |= PL011_LCRH_WLEN_SIZE(8) << PL011_LCRH_WLEN_SHIFT;
PL011_REGS(dev)->lcr_h = lcrh; config->uart->lcr_h = lcrh;
/* Enabling the FIFOs */ /* Enabling the FIFOs */
pl011_enable_fifo(dev); pl011_enable_fifo(dev);
} }
/* initialize all IRQs as masked */ /* initialize all IRQs as masked */
PL011_REGS(dev)->imsc = 0U; config->uart->imsc = 0U;
PL011_REGS(dev)->icr = PL011_IMSC_MASK_ALL; config->uart->icr = PL011_IMSC_MASK_ALL;
if (!data->sbsa) { if (!data->sbsa) {
PL011_REGS(dev)->dmacr = 0U; config->uart->dmacr = 0U;
__ISB(); __ISB();
PL011_REGS(dev)->cr &= ~(BIT(14) | BIT(15) | BIT(1)); config->uart->cr &= ~(BIT(14) | BIT(15) | BIT(1));
PL011_REGS(dev)->cr |= PL011_CR_RXE | PL011_CR_TXE; config->uart->cr |= PL011_CR_RXE | PL011_CR_TXE;
__ISB(); __ISB();
} }
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
@ -433,8 +466,8 @@ void pl011_isr(const struct device *dev)
static void pl011_irq_config_func_0(const struct device *dev); static void pl011_irq_config_func_0(const struct device *dev);
#endif #endif
static struct uart_device_config pl011_cfg_port_0 = { static struct pl011_config pl011_cfg_port_0 = {
.base = (uint8_t *)DT_INST_REG_ADDR(0), .uart = (volatile struct pl011_regs *)DT_INST_REG_ADDR(0),
.sys_clk_freq = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency), .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency),
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = pl011_irq_config_func_0, .irq_config_func = pl011_irq_config_func_0,
@ -496,8 +529,8 @@ static void pl011_irq_config_func_0(const struct device *dev)
static void pl011_irq_config_func_1(const struct device *dev); static void pl011_irq_config_func_1(const struct device *dev);
#endif #endif
static struct uart_device_config pl011_cfg_port_1 = { static struct pl011_config pl011_cfg_port_1 = {
.base = (uint8_t *)DT_INST_REG_ADDR(1), .uart = (volatile struct pl011_regs *)DT_INST_REG_ADDR(1),
.sys_clk_freq = DT_INST_PROP_BY_PHANDLE(1, clocks, clock_frequency), .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(1, clocks, clock_frequency),
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = pl011_irq_config_func_1, .irq_config_func = pl011_irq_config_func_1,
@ -562,8 +595,8 @@ static void pl011_irq_config_func_1(const struct device *dev)
static void pl011_irq_config_func_sbsa(const struct device *dev); static void pl011_irq_config_func_sbsa(const struct device *dev);
#endif #endif
static struct uart_device_config pl011_cfg_sbsa = { static struct pl011_config pl011_cfg_sbsa = {
.base = (uint8_t *)DT_INST_REG_ADDR(0), .uart = (volatile struct pl011_regs *)DT_INST_REG_ADDR(0),
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = pl011_irq_config_func_sbsa, .irq_config_func = pl011_irq_config_func_sbsa,
#endif #endif