From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gregory CLEMENT Date: Wed, 26 Dec 2018 16:37:36 +0100 Subject: [U-Boot] [PATCH] spi: soft_spi: Fix null ptr when probing soft_spi. In-Reply-To: <1545231209-32505-1-git-send-email-horatiu.vultur@microchip.com> (Horatiu Vultur's message of "Wed, 19 Dec 2018 15:53:29 +0100") References: <1545231209-32505-1-git-send-email-horatiu.vultur@microchip.com> Message-ID: <877efwb8ov.fsf@bootlin.com> 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 Hi Horatiu, I am adding Daniel because actually this patch is needed to be able to boot the Luton MIPS based platform. It is on this platform that we find this issue. Gregory =20 On mer., d=C3=A9c. 19 2018, Horatiu Vultur = wrote: > When probing soft_spi the result of dev_get_parent_priv(dev) in probe > function is null ptr because the spi is on the ahb bus which has > per_child_auto_alloc_size set to 0. Therefore it would generate an Ooops > messages when accessing spi_slave structure. > > The fix consist of delaying the read of dm_spi_slave_platdata until a > child under the spi is probed, to be able to read SPI mode. Therefore > implement .child_pre_probe in which updates soft_spi_platdata based on > child dm_spi_slave_platdata. > > Signed-off-by: Horatiu Vultur > --- > drivers/spi/soft_spi.c | 24 +++++++++++++++++------- > 1 file changed, 17 insertions(+), 7 deletions(-) > > diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c > index b06883f..e28591b 100644 > --- a/drivers/spi/soft_spi.c > +++ b/drivers/spi/soft_spi.c > @@ -210,18 +210,13 @@ static int soft_spi_ofdata_to_platdata(struct udevi= ce *dev) > =20 > static int soft_spi_probe(struct udevice *dev) > { > - struct spi_slave *slave =3D dev_get_parent_priv(dev); > struct soft_spi_platdata *plat =3D dev->platdata; > - int cs_flags, clk_flags; > int ret; > =20 > - cs_flags =3D (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW; > - clk_flags =3D (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0; > - > if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs, > - GPIOD_IS_OUT | cs_flags) || > + GPIOD_IS_OUT) || > gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk, > - GPIOD_IS_OUT | clk_flags)) > + GPIOD_IS_OUT)) > return -EINVAL; > =20 > ret =3D gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi, > @@ -241,6 +236,20 @@ static int soft_spi_probe(struct udevice *dev) > return 0; > } > =20 > +static int soft_spi_child_pre_probe(struct udevice *dev) > +{ > + struct udevice *bus =3D dev_get_parent(dev); > + struct dm_spi_slave_platdata *slave =3D dev_get_parent_platdata(dev); > + struct soft_spi_platdata *plat =3D bus->platdata; > + > + if (!(slave->mode & SPI_CS_HIGH)) > + plat->cs.flags |=3D GPIOD_ACTIVE_LOW; > + if (slave->mode & SPI_CPOL) > + plat->sclk.flags |=3D GPIOD_ACTIVE_LOW; > + > + return 0; > +} > + > static const struct udevice_id soft_spi_ids[] =3D { > { .compatible =3D "spi-gpio" }, > { } > @@ -254,5 +263,6 @@ U_BOOT_DRIVER(soft_spi) =3D { > .ofdata_to_platdata =3D soft_spi_ofdata_to_platdata, > .platdata_auto_alloc_size =3D sizeof(struct soft_spi_platdata), > .priv_auto_alloc_size =3D sizeof(struct soft_spi_priv), > + .child_pre_probe =3D soft_spi_child_pre_probe, > .probe =3D soft_spi_probe, > }; > --=20 > 2.7.4 > --=20 Gregory Clement, Bootlin Embedded Linux and Kernel engineering http://bootlin.com