+ while (!(readl(&usart->csr) & USART3_BIT(TXRDY)));
+ writel(c, &usart->thr);
+}
+
+static int atmel_serial_getc(void)
+{
+ atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
+
+ while (!(readl(&usart->csr) & USART3_BIT(RXRDY)))
+ WATCHDOG_RESET();
+ return readl(&usart->rhr);
+}
+
+static int atmel_serial_tstc(void)
+{
+ atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
+ return (readl(&usart->csr) & USART3_BIT(RXRDY)) != 0;
+}
+
+static struct serial_device atmel_serial_drv = {
+ .name = "atmel_serial",
+ .start = atmel_serial_init,
+ .stop = NULL,
+ .setbrg = atmel_serial_setbrg,
+ .putc = atmel_serial_putc,
+ .puts = default_serial_puts,
+ .getc = atmel_serial_getc,
+ .tstc = atmel_serial_tstc,
+};
+
+void atmel_serial_initialize(void)
+{
+ serial_register(&atmel_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &atmel_serial_drv;
+}
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+struct atmel_serial_priv {
+ atmel_usart3_t *usart;
+};
+
+int atmel_serial_setbrg(struct udevice *dev, int baudrate)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ atmel_serial_setbrg_internal(priv->usart, 0 /* ignored */, baudrate);
+ atmel_serial_activate(priv->usart);
+
+ return 0;
+}
+
+static int atmel_serial_getc(struct udevice *dev)
+{
+ struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+ if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
+ return -EAGAIN;
+
+ return readl(&priv->usart->rhr);