Subject: Re: [PATCH v3 2/2] powerpc/mpc5121: add initial support for PDM360NG board

From: Anatolij Gustschin <[email-masked]>
Date: Tue, 27 Jul 2010 12:36:47 +0200

Hi Grant,

On Sun, 25 Jul 2010 01:42:23 -0600
Grant Likely <[email-masked]> wrote:
...
> Hi Anatolij,
> 
> Finally got some time tonight to properly dig into this patch.  Comments below.

Thanks for review and comments! My reply below.

...
> > +       nfc@40000000 {
> > +               compatible = "fsl,mpc5121-nfc";
> > +               reg = <0x40000000 0x100000>;
> > +               interrupts = <0x6 0x8>;
> > +               interrupt-parent = <&ipic>;
> 
> This device tree can be less verbose if you remove the
> interrupt-parent property from all the nodes, and have a single
> interrupt-parent = <&ipic>; in the root node.  Nodes inherit the
> interrupt-parent from their (grand-)parents.

Fixed in next patch version to use interrupt-parent in root node only.

...
> > +               mdio@2800 {
> > +                       compatible = "fsl,mpc5121-fec-mdio";
> > +                       reg = <0x2800 0x200>;
> > +                       #address-cells = <1>;
> > +                       #size-cells = <0>;
> > +                       phy: ethernet-phy@0 {
> > +                               reg = <0x1f>;
> 
> For completeness, phy should have a compatible property.

Added in next patch version.

...
> > +               spi@11900 {
> > +                       compatible = "fsl,mpc5121-psc-spi", "fsl,mpc5121-psc";
> > +                       cell-index = <9>;
> 
> Try to drop the cell-index properties.  They are almost always misused.

Removing cell-index would require changing the spi driver's probe.
Currently cell-index is used to set spi bus number. What could be used
for bus enumeration instead? Is it okay to use part of the spi node
address? e.g. obtaining the offset 0x11900, masking out the unrelated
bits and shifting by 8 would deliver unique index 9 for PSC9 in SPI
mode. This would work for all 12 PSC SPI controllers of mpc5121.

...
> > +static int pdm360ng_get_pendown_state(void)
> > +{
> > +       u32 reg;
> > +
> > +       reg = in_be32((u32 *)(pdm360ng_gpio_base + 0xc));
> > +       if (reg & 0x40)
> > +               setbits32((u32 *)(pdm360ng_gpio_base + 0xc), 0x40);
> > +
> > +       reg = in_be32((u32 *)(pdm360ng_gpio_base + 0x8));
> 
> (u32*) casts are unnecessary and can be removed.

Fixed.

> > +
> > +       /* return 1 if pen is down */
> > +       return reg & 0x40 ? 0 : 1;
> 
> return reg & 0x40 == 0;

Fixed.

...
> > +static int __init pdm360ng_penirq_init(void)
> > +{
> > +       struct device_node *np;
> > +       struct resource r;
> > +
> > +       np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio");
> > +       if (!np) {
> > +               pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__);
> > +               return -1;
> > +       }
> 
> return -ENODEV;

Ok, fixed also.

...
> > +       pdm360ng_gpio_base = ioremap(r.start, resource_size(&r));
> 
> Or you could have simply used of_iomap() to eliminate some code.

of_iomap() is used in next patch version.

...
> > +static int __init pdm360ng_touchscreen_init(void)
> > +{
> > +       struct device_node *np;
> > +       struct of_device *of_dev;
> > +       struct spi_board_info info;
> > +       const u32 *prop;
> > +       int bus_num = -1;
> > +       int len;
> > +
> > +       np = of_find_compatible_node(NULL, NULL, "ti,ads7845");
> > +       if (!np)
> > +               return -ENODEV;
> > +
> > +       memset(&info, 0, sizeof(info));
> > +       info.irq = irq_of_parse_and_map(np, 0);
> > +       if (info.irq == NO_IRQ)
> > +               return -ENODEV;
> > +
> > +       info.platform_data = &pdm360ng_ads7846_pdata;
> > +       if (strlcpy(info.modalias, "ads7846",
> > +                   SPI_NAME_SIZE) >= SPI_NAME_SIZE)
> > +               return -ENOMEM;
> > +
> > +       np = of_get_next_parent(np);
> > +       if (!np)
> > +               return -ENODEV;
> > +
> > +       prop = of_get_property(np, "cell-index", &len);
> > +       if (prop && len == 4)
> > +               bus_num = *prop;
> 
> Blech.  Don't use cell-index for bus enumeration.  In fact, none of
> this should be necessary at all (see below).

I dropped this code entirely in the next patch version.

> > +
> > +       if (bus_num < 0 || bus_num > 11)
> > +               return -ENODEV;
> > +
> > +       info.bus_num = bus_num;
> > +
> > +       of_dev = of_find_device_by_node(np);
> > +       of_node_put(np);
> > +       if (of_dev) {
> > +               struct fsl_spi_platform_data *pdata;
> > +
> > +               pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
> > +               if (pdata) {
> > +                       pdata->bus_num = bus_num;
> > +                       pdata->max_chipselect = 1;
> > +                       of_dev->dev.platform_data = pdata;
> > +               }
> > +       }
> > +
> > +       if (pdm360ng_penirq_init())
> > +               return -ENODEV;
> > +
> > +       return spi_register_board_info(&info, 1);
> 
> This ends up being a lot of code simply to attach a pdata structure to
> an spi device.  I've been thinking about this problem, and I think
> there is a better way.  Instead, use a bus notifier attached to the
> SPI bus to wait for the spi_device to get registered, but before it
> gets bound to a driver.  Then you can attach the pdata structure very
> simply.  Something like this I think (completely untested, or even
> compiled.  Details are left as an exercise to the developer):
> 
> static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb,
> 					unsigned long event, void *__dev)
> {
> 	struct device *dev = __dev;
> 
> 	if ((event == BUS_NOTIFIY_ADD_DEVICE) && (dev->of_node == [FOO]))
> 		dev->platform_data = [BAR];
> }
> 
> static struct notifier_block pdm360ng_touchscreen_nb = {
> 	notifier_call = pdm360ng_touchscreen_notifier_call;
> };
> 
> static int __init pdm360ng_touchscreen_init(void)
> {
> 	bus_register_notifier(&spi_bus_type, pdm360ng_touchscreen_nb);
> }

Thanks! Bus notifier is now used for setting platform data in v4.
This requires fixing the mpc5121 psc spi driver to create spi child
nodes of the spi master node. I have already send the appropriate
patch to spi-devel list, but it is not the right approach to call
of_register_spi_devices() in each driver. Do you plan to fix it in
core spi code in v2.6.36?

...
> > +}
> > +machine_device_initcall(pdm360ng, pdm360ng_touchscreen_init);
> 
> This code is *in the same file* as the board setup file.  Don't use an
> initcall.  Call it from the init callback instead.

OK, initcall dropped.

Thanks,
Anatolij