doc: replace @return by Return:
[platform/kernel/u-boot.git] / drivers / serial / serial_bcm283x_pl011.c
index bfd39f8..fe74629 100644 (file)
@@ -1,7 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2018 Alexander Graf <agraf@suse.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -9,6 +8,7 @@
 #include <asm/gpio.h>
 #include <dm/pinctrl.h>
 #include <dm/platform_data/serial_pl01x.h>
+#include <serial.h>
 #include "serial_pl01x_internal.h"
 
 /*
@@ -17,7 +17,7 @@
  * The serial device will only work properly if it has been muxed to the serial
  * pins by firmware. Check whether that happened here.
  *
- * @return true if serial device is muxed, false if not
+ * Return: true if serial device is muxed, false if not
  */
 static bool bcm283x_is_serial_muxed(void)
 {
@@ -33,16 +33,21 @@ static bool bcm283x_is_serial_muxed(void)
        return true;
 }
 
-static int bcm283x_pl011_serial_ofdata_to_platdata(struct udevice *dev)
+static int bcm283x_pl011_serial_probe(struct udevice *dev)
 {
-       struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
+       struct pl01x_serial_plat *plat = dev_get_plat(dev);
        int ret;
 
        /* Don't spawn the device if it's not muxed */
        if (!bcm283x_is_serial_muxed())
                return -ENODEV;
 
-       ret = pl01x_serial_ofdata_to_platdata(dev);
+       /*
+        * Read the ofdata here rather than in an of_to_plat() method
+        * since we need the soc simple-bus to be probed so that the 'ranges'
+        * property is used.
+        */
+       ret = pl01x_serial_of_to_plat(dev);
        if (ret)
                return ret;
 
@@ -52,9 +57,31 @@ static int bcm283x_pl011_serial_ofdata_to_platdata(struct udevice *dev)
         */
        plat->skip_init = true;
 
-       return 0;
+       return pl01x_serial_probe(dev);
 }
 
+static int bcm283x_pl011_serial_setbrg(struct udevice *dev, int baudrate)
+{
+       int r;
+
+       r = pl01x_serial_setbrg(dev, baudrate);
+
+       /*
+        * We may have been muxed to a bogus line before. Drain the RX
+        * queue so we start at a clean slate.
+        */
+       while (pl01x_serial_getc(dev) != -EAGAIN) ;
+
+       return r;
+}
+
+static const struct dm_serial_ops bcm283x_pl011_serial_ops = {
+       .putc = pl01x_serial_putc,
+       .pending = pl01x_serial_pending,
+       .getc = pl01x_serial_getc,
+       .setbrg = bcm283x_pl011_serial_setbrg,
+};
+
 static const struct udevice_id bcm283x_pl011_serial_id[] = {
        {.compatible = "brcm,bcm2835-pl011", .data = TYPE_PL011},
        {}
@@ -64,10 +91,11 @@ U_BOOT_DRIVER(bcm283x_pl011_uart) = {
        .name   = "bcm283x_pl011",
        .id     = UCLASS_SERIAL,
        .of_match = of_match_ptr(bcm283x_pl011_serial_id),
-       .ofdata_to_platdata = of_match_ptr(bcm283x_pl011_serial_ofdata_to_platdata),
-       .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),
-       .probe  = pl01x_serial_probe,
-       .ops    = &pl01x_serial_ops,
+       .probe  = bcm283x_pl011_serial_probe,
+       .plat_auto      = sizeof(struct pl01x_serial_plat),
+       .ops    = &bcm283x_pl011_serial_ops,
+#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_BOARD)
        .flags  = DM_FLAG_PRE_RELOC,
-       .priv_auto_alloc_size = sizeof(struct pl01x_priv),
+#endif
+       .priv_auto      = sizeof(struct pl01x_priv),
 };