[PATCH 3/6] of/spi: add support to parse the SPI flash's partitions
Grant Likely
grant.likely at secretlab.ca
Wed Jul 28 05:24:19 EST 2010
[cc'ing spi-devel-general]
On Mon, Jul 26, 2010 at 2:20 AM, Hu Mingkai-B21284 <B21284 at freescale.com> wrote:
>
>
>> -----Original Message-----
>> From: glikely at secretlab.ca [mailto:glikely at secretlab.ca] On
>> Behalf Of Grant Likely
>> Sent: Monday, July 26, 2010 3:53 PM
>> To: Hu Mingkai-B21284
>> Cc: linuxppc-dev at ozlabs.org; galak at kernel.crashing.org; Zang
>> Roy-R61911
>> Subject: Re: [PATCH 3/6] of/spi: add support to parse the SPI
>> flash's partitions
>>
>> On Mon, Jul 26, 2010 at 1:25 AM, Hu Mingkai-B21284
>> <B21284 at freescale.com> wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: Grant Likely [mailto:glikely at secretlab.ca] On Behalf
>> Of Grant
>> >> Likely
>> >> Sent: Monday, July 26, 2010 8:28 AM
>> >> To: Hu Mingkai-B21284
>> >> Cc: linuxppc-dev at ozlabs.org; galak at kernel.crashing.org; Zang
>> >> Roy-R61911
>> >> Subject: Re: [PATCH 3/6] of/spi: add support to parse the
>> SPI flash's
>> >> partitions
>> >>
>> >> On Tue, Jul 20, 2010 at 10:08:22AM +0800, Mingkai Hu wrote:
>> >> > Signed-off-by: Mingkai Hu <Mingkai.hu at freescale.com>
>> >> > ---
>> >> > drivers/of/of_spi.c | 11 +++++++++++
>> >> > drivers/spi/spi_mpc8xxx.c | 1 +
>> >> > 2 files changed, 12 insertions(+), 0 deletions(-)
>> >> >
>> >> > diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index
>> >> > 5fed7e3..284ca0e 100644
>> >> > --- a/drivers/of/of_spi.c
>> >> > +++ b/drivers/of/of_spi.c
>> >> > @@ -10,6 +10,8 @@
>> >> > #include <linux/device.h>
>> >> > #include <linux/spi/spi.h>
>> >> > #include <linux/of_spi.h>
>> >> > +#include <linux/spi/flash.h>
>> >> > +#include <linux/mtd/partitions.h>
>> >> >
>> >> > /**
>> >> > * of_register_spi_devices - Register child devices onto
>> >> the SPI bus
>> >> > @@ -26,6 +28,7 @@ void of_register_spi_devices(struct
>> >> spi_master *master, struct device_node *np)
>> >> > const __be32 *prop;
>> >> > int rc;
>> >> > int len;
>> >> > + struct flash_platform_data *pdata;
>> >> >
>> >> > for_each_child_of_node(np, nc) {
>> >> > /* Alloc an spi_device */ @@ -81,6 +84,14 @@ void
>> >> > of_register_spi_devices(struct
>> >> spi_master *master, struct device_node *np)
>> >> > of_node_get(nc);
>> >> > spi->dev.of_node = nc;
>> >> >
>> >> > + /* Parse the mtd partitions */
>> >> > + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
>> >> > + if (!pdata)
>> >> > + return;
>> >> > + pdata->nr_parts =
>> of_mtd_parse_partitions(&master->dev,
>> >> > + nc, &pdata->parts);
>> >> > + spi->dev.platform_data = pdata;
>> >> > +
>> >>
>> >> Nack. Not all spi devices are mtd devices. In fact, most are not.
>> >>
>> >> The spi driver itself should call the
>> of_mtd_parse_partitions code to
>> >> get the partition map. Do not use pdata in this case.
>> >>
>> >
>> > Yes, we can call of_mtd_parse_partitions to get the
>> partiton map, but
>> > how can we pass this map to spi device to register to MTD layer?
>> >
>> > The spi device is created and registered when call
>> > of_register_spi_device in the spi controller probe
>> function, then the
>> > spi device will traverse the spi device driver list to find
>> the proper
>> > driver, if matched, then call the spi device driver probe
>> code where
>> > the mtd partition info is registered to the mtd layer.
>> >
>> > so where is the proper place to put the
>> of_mtd_parse_partitions code?
>>
>> In the device driver probe code.
>>
>
> This is the way that I did at first, thus we need to add the same code
> in all the spi flash driver to get partition map info.
>
> or we add the get partition map code to of_spi.c?
No, it really does not belong in of_spi.c because the spi code has no
knowledge about MTD devices.
I only see two valid options, to either:
a) add it to each MTD driver, or
b) add a hook to the core MTD code so that if an of_node pointer is
provided, and no partition data is provided, then it will parse the
partitions when the MTD device is registered. You'd also need to code
it in a way that becomes a no-op when CONFIG_OF is not set.
>
> +/*
> + * of_parse_flash_partition - Parse the flash partition on the SPI bus
> + * @spi: Pointer to spi_device device
> + */
> +void of_parse_flash_partition(struct spi_device *spi)
> +{
> + struct mtd_partition *parts;
> + struct flash_platform_data *spi_pdata;
> + int nr_parts = 0;
> + static int num_flash;
> + struct device_node *np = spi->dev.archdata.of_node;
> +
> + nr_parts = of_mtd_parse_partitions(&spi->dev, np, &parts);
> + if (!nr_parts)
> + goto end;
> +
> + spi_pdata = kzalloc(sizeof(*spi_pdata), GFP_KERNEL);
> + if (!spi_pdata)
> + goto end;
> + spi_pdata->name = kzalloc(10, GFP_KERNEL);
> + if (!spi_pdata->name)
> + goto free_flash;
> + snprintf(spi_pdata->name, 10, "SPIFLASH%d", num_flash++);
> +
> + spi_pdata->parts = parts;
> + spi_pdata->nr_parts = nr_parts;
> +
> + spi->dev.platform_data = spi_pdata;
> +
> + return;
> +
> +free_flash:
> + kfree(spi_pdata);
> +end:
> + return;
> +}
>
>
>> >> > diff --git a/drivers/spi/spi_mpc8xxx.c
>> b/drivers/spi/spi_mpc8xxx.c
>> >> > index efed70e..0fadaeb 100644
>> >> > --- a/drivers/spi/spi_mpc8xxx.c
>> >> > +++ b/drivers/spi/spi_mpc8xxx.c
>> >> > @@ -137,6 +137,7 @@ int mpc8xxx_spi_transfer(struct spi_device
>> >> > *spi,
>> >> >
>> >> > void mpc8xxx_spi_cleanup(struct spi_device *spi) {
>> >> > + kfree(spi->dev.platform_data);
>> >>
>> >> Irrelevant given the above comment, but how does this even work?
>> >> What if a driver was detached and reattached to an
>> spi_device? The
>> >> platform_data would be freed. Not to mention that the
>> pointer isn't
>> >> cleared, so the driver would have no idea that it has a freed
>> >> pointer.
>> >>
>> >
>> > It works. If the driver detached, the spi device
>> platform_data will be
>> > released, when reattached, the of_register_spi_devices will
>> be called
>> > again, the platform_data will be allocated.
>>
>> Ah right, I wasn't looking in the right place. On that note
>> however, the cleanup of spi_device allocated by the OF code
>> should also have a reciprocal helper that frees them too. It
>> shouldn't be done in the individual drivers.
>>
>
> We can define a helper to free the platform_data, but where it should be called?
> Maybe spidev_release is a better place to call, after all the platfrom_data is allocated
> when the spi device is created, so it should be freed when released.
It would be called from the spi core code. However, with two options
I gave above, platform_data shouldn't be needed at all.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
More information about the Linuxppc-dev
mailing list