From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Robinson Date: Wed, 7 Mar 2018 12:59:23 +0000 Subject: [U-Boot] [PATCH 2/2] bcm283x_pl011: Flush RX queue after setting baud rate In-Reply-To: <20180306131327.61174-3-agraf@suse.de> References: <20180306131327.61174-1-agraf@suse.de> <20180306131327.61174-3-agraf@suse.de> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: u-boot@lists.denx.de On Tue, Mar 6, 2018 at 1:13 PM, Alexander Graf wrote: > After the UART was initialized, we may still have bogus data in the > RX queue if it was enabled with incorrect pin muxing before. > > So let's flush the RX queue whenever we initialize baud rates. > > This fixes a regression with the dynamic pinmuxing code when enable_uart= =3D1 > is not set in config.txt on Raspberry Pis that use pl011 for serial. This causes my RPi2 devices not to actually boot. When I connected a HDMI monitor to one of them I get the rainbow square. Peter > Fixes: caf2233b28 ("bcm283x: Add pinctrl driver") > Reported-by: G=C3=B6ran Lundberg > Reported-by: Peter Robinson > Signed-off-by: Alexander Graf > --- > drivers/serial/serial_bcm283x_pl011.c | 25 ++++++++++++++++++++++++- > drivers/serial/serial_pl01x.c | 10 +++++----- > drivers/serial/serial_pl01x_internal.h | 7 ++++++- > 3 files changed, 35 insertions(+), 7 deletions(-) > > diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/seria= l_bcm283x_pl011.c > index bfd39f84f3..2c6fb267ff 100644 > --- a/drivers/serial/serial_bcm283x_pl011.c > +++ b/drivers/serial/serial_bcm283x_pl011.c > @@ -9,6 +9,7 @@ > #include > #include > #include > +#include > #include "serial_pl01x_internal.h" > > /* > @@ -55,6 +56,28 @@ static int bcm283x_pl011_serial_ofdata_to_platdata(str= uct udevice *dev) > return 0; > } > > +static int bcm283x_pl011_serial_setbrg(struct udevice *dev, int baudrate) > +{ > + int r; > + > + r =3D 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) =3D=3D -EAGAIN) ; > + > + return r; > +} > + > +static const struct dm_serial_ops bcm283x_pl011_serial_ops =3D { > + .putc =3D pl01x_serial_putc, > + .pending =3D pl01x_serial_pending, > + .getc =3D pl01x_serial_getc, > + .setbrg =3D bcm283x_pl011_serial_setbrg, > +}; > + > static const struct udevice_id bcm283x_pl011_serial_id[] =3D { > {.compatible =3D "brcm,bcm2835-pl011", .data =3D TYPE_PL011}, > {} > @@ -67,7 +90,7 @@ U_BOOT_DRIVER(bcm283x_pl011_uart) =3D { > .ofdata_to_platdata =3D of_match_ptr(bcm283x_pl011_serial_ofdata_= to_platdata), > .platdata_auto_alloc_size =3D sizeof(struct pl01x_serial_platdata= ), > .probe =3D pl01x_serial_probe, > - .ops =3D &pl01x_serial_ops, > + .ops =3D &bcm283x_pl011_serial_ops, > .flags =3D DM_FLAG_PRE_RELOC, > .priv_auto_alloc_size =3D sizeof(struct pl01x_priv), > }; > diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c > index 23d9d839cb..45f1282770 100644 > --- a/drivers/serial/serial_pl01x.c > +++ b/drivers/serial/serial_pl01x.c > @@ -273,7 +273,7 @@ __weak struct serial_device *default_serial_console(v= oid) > > #ifdef CONFIG_DM_SERIAL > > -static int pl01x_serial_setbrg(struct udevice *dev, int baudrate) > +int pl01x_serial_setbrg(struct udevice *dev, int baudrate) > { > struct pl01x_serial_platdata *plat =3D dev_get_platdata(dev); > struct pl01x_priv *priv =3D dev_get_priv(dev); > @@ -299,21 +299,21 @@ int pl01x_serial_probe(struct udevice *dev) > return 0; > } > > -static int pl01x_serial_getc(struct udevice *dev) > +int pl01x_serial_getc(struct udevice *dev) > { > struct pl01x_priv *priv =3D dev_get_priv(dev); > > return pl01x_getc(priv->regs); > } > > -static int pl01x_serial_putc(struct udevice *dev, const char ch) > +int pl01x_serial_putc(struct udevice *dev, const char ch) > { > struct pl01x_priv *priv =3D dev_get_priv(dev); > > return pl01x_putc(priv->regs, ch); > } > > -static int pl01x_serial_pending(struct udevice *dev, bool input) > +int pl01x_serial_pending(struct udevice *dev, bool input) > { > struct pl01x_priv *priv =3D dev_get_priv(dev); > unsigned int fr =3D readl(&priv->regs->fr); > @@ -324,7 +324,7 @@ static int pl01x_serial_pending(struct udevice *dev, = bool input) > return fr & UART_PL01x_FR_TXFF ? 0 : 1; > } > > -const struct dm_serial_ops pl01x_serial_ops =3D { > +static const struct dm_serial_ops pl01x_serial_ops =3D { > .putc =3D pl01x_serial_putc, > .pending =3D pl01x_serial_pending, > .getc =3D pl01x_serial_getc, > diff --git a/drivers/serial/serial_pl01x_internal.h b/drivers/serial/seri= al_pl01x_internal.h > index c56dd54c7b..d4605f24a3 100644 > --- a/drivers/serial/serial_pl01x_internal.h > +++ b/drivers/serial/serial_pl01x_internal.h > @@ -43,7 +43,12 @@ struct pl01x_regs { > > int pl01x_serial_ofdata_to_platdata(struct udevice *dev); > int pl01x_serial_probe(struct udevice *dev); > -extern const struct dm_serial_ops pl01x_serial_ops; > + > +/* Needed for external pl01x_serial_ops drivers */ > +int pl01x_serial_putc(struct udevice *dev, const char ch); > +int pl01x_serial_pending(struct udevice *dev, bool input); > +int pl01x_serial_getc(struct udevice *dev); > +int pl01x_serial_setbrg(struct udevice *dev, int baudrate); > > struct pl01x_priv { > struct pl01x_regs *regs; > -- > 2.12.3 >