On Tuesday 08 March 2011, Subhasish Ghosh wrote:

> +struct da8xx_pruss {
> +     struct device *dev;
> +     spinlock_t lock;
> +     struct resource *res;
> +     struct clk *clk;
> +     u32 clk_freq;
> +     void __iomem *ioaddr;
> +};

> +s32 pruss_disable(struct device *dev, u8 pruss_num)
> +{
> +     struct da8xx_pruss *pruss = dev_get_drvdata(dev->parent);
> +     struct da8xx_prusscore_regs *h_pruss;
> +     struct pruss_map *pruss_mmap = (struct pruss_map *)pruss->ioaddr;
> +     u32 temp_reg;
> +     u32 delay_cnt;

Can you explain the significance of pruss_num? As far as I
can tell, you always pass constants in here, so it should
be possible to determine the number from the device.

> +     if ((pruss_num != DA8XX_PRUCORE_0) && (pruss_num != DA8XX_PRUCORE_1))
> +             return -EINVAL;
> +
> +     spin_lock(&pruss->lock);
> +     if (pruss_num == DA8XX_PRUCORE_0) {
> +             /* pruss deinit */
> +             __raw_writel(0xFFFFFFFF, (PRUSS_INTC_STATCLRINT0 & 0xFFFF));
> +             /* Disable PRU0  */
> +             h_pruss = (struct da8xx_prusscore_regs *)
> +                     &pruss_mmap->core[DA8XX_PRUCORE_0];
> +
> +             temp_reg = __raw_readl(&h_pruss->CONTROL);
> +             temp_reg = (temp_reg &
> +                             ~DA8XX_PRUCORE_CONTROL_COUNTENABLE_MASK) |
> +                             ((DA8XX_PRUCORE_CONTROL_COUNTENABLE_DISABLE <<
> +                             DA8XX_PRUCORE_CONTROL_COUNTENABLE_SHIFT) &
> +                             DA8XX_PRUCORE_CONTROL_COUNTENABLE_MASK);
> +             __raw_writel(temp_reg, &h_pruss->CONTROL);

Better use readl/writel, the __raw_ variants are not reliable in general.

> +             for (delay_cnt = 0x10000; delay_cnt > 0; delay_cnt--) {
> +
> +                     temp_reg = __raw_readl(&h_pruss->CONTROL);
> +                     temp_reg = (temp_reg &
> +                             ~DA8XX_PRUCORE_CONTROL_ENABLE_MASK) |
> +                             ((DA8XX_PRUCORE_CONTROL_ENABLE_DISABLE <<
> +                             DA8XX_PRUCORE_CONTROL_ENABLE_SHIFT) &
> +                             DA8XX_PRUCORE_CONTROL_ENABLE_MASK);
> +                     __raw_writel(temp_reg, &h_pruss->CONTROL);
> +             }
> +
> +             /* Reset PRU0 */
> +             for (delay_cnt = 0x10000; delay_cnt > 0; delay_cnt--)
> +                     __raw_writel(DA8XX_PRUCORE_CONTROL_RESETVAL,
> +                                     &h_pruss->CONTROL);

Why do you need to reset it 65536 times? Is once not enough?

> +     } else if (pruss_num == DA8XX_PRUCORE_1) {
> +             /* pruss deinit */
> +             __raw_writel(0xFFFFFFFF, (PRUSS_INTC_STATCLRINT1 & 0xFFFF));
> +             /* Disable PRU1 */
> +             h_pruss = (struct da8xx_prusscore_regs *)
> +                     &pruss_mmap->core[DA8XX_PRUCORE_1];
> +             temp_reg = __raw_readl(&h_pruss->CONTROL);
> +             temp_reg = (temp_reg &
> +                             ~DA8XX_PRUCORE_CONTROL_COUNTENABLE_MASK) |
> +                             ((DA8XX_PRUCORE_CONTROL_COUNTENABLE_DISABLE <<
> +                             DA8XX_PRUCORE_CONTROL_COUNTENABLE_SHIFT) &
> +                             DA8XX_PRUCORE_CONTROL_COUNTENABLE_MASK);
> +             __raw_writel(temp_reg, &h_pruss->CONTROL);
> +
> +             for (delay_cnt = 0x10000; delay_cnt > 0; delay_cnt--) {
> +
> +                     temp_reg = __raw_readl(&h_pruss->CONTROL);
> +                     temp_reg = (temp_reg &
> +                             ~DA8XX_PRUCORE_CONTROL_ENABLE_MASK) |
> +                             ((DA8XX_PRUCORE_CONTROL_ENABLE_DISABLE <<
> +                             DA8XX_PRUCORE_CONTROL_ENABLE_SHIFT) &
> +                             DA8XX_PRUCORE_CONTROL_ENABLE_MASK);
> +                     __raw_writel(temp_reg, &h_pruss->CONTROL);
> +             }
> +
> +             /* Reset PRU1 */
> +             for (delay_cnt = 0x10000; delay_cnt > 0; delay_cnt--)
> +                     __raw_writel(DA8XX_PRUCORE_CONTROL_RESETVAL,
> +                                                     &h_pruss->CONTROL);
> +     }
> +     spin_unlock(&pruss->lock);

This is almost the exact same code as for the DA8XX_PRUCORE_0 case.
Please be a little more creative in order to avoid such code duplication.

> +     return 0;
> +}
> +EXPORT_SYMBOL(pruss_disable);

EXPORT_SYMBOL_GPL, please. Also for the other symbols.

> +s32 pruss_writeb(struct device *dev, u32 offset,
> +             u8 *pdatatowrite, u16 bytestowrite)
> +{
> +     struct da8xx_pruss *pruss = dev_get_drvdata(dev->parent);
> +     u8 *paddresstowrite;
> +     u16 loop;
> +     offset = (u32)pruss->ioaddr + offset;
> +     paddresstowrite = (u8 *) (offset);
> +
> +     for (loop = 0; loop < bytestowrite; loop++)
> +             __raw_writeb(*pdatatowrite++, paddresstowrite++);
> +
> +     return 0;
> +}
> +EXPORT_SYMBOL(pruss_writeb);

I would recommend providing a simpler variant of your all I/O accessors,
which write a single word. Most of the users of these simply
pass bytestowrite=1 anyway, so the caller can become more readable.

Also, my comments about __raw_* and Marc's comments about the
type cast apply to all of these.

> +static int pruss_mfd_add_devices(struct platform_device *pdev)
> +{
> +     struct da8xx_pruss_devices *dev_data = pdev->dev.platform_data;
> +     struct device *dev = &pdev->dev;
> +     struct mfd_cell cell;
> +     u32 err, count;
> +
> +     for (count = 0; dev_data[count].dev_name != NULL; count++) {
> +             memset(&cell, 0, sizeof(struct mfd_cell));
> +             cell.id                 = count;
> +             cell.name               = dev_data[count].dev_name;
> +             cell.platform_data      = dev_data[count].pdata;
> +             cell.data_size          = dev_data[count].pdata_size;
> +             cell.resources          = dev_data[count].resources;
> +             cell.num_resources      = dev_data[count].num_resources;
> +
> +             err = mfd_add_devices(dev, 0, &cell, 1, NULL, 0);
> +             if (err) {
> +                     dev_err(dev, "cannot add mfd cells\n");
> +                     return err;
> +             }
> +             dev_info(dev, "mfd: added %s device\n",
> +                             dev_data[count].dev_name);
> +     }
> +
> +     return err;
> +}

This would get much simpler if you just replaced the da8xx_pruss_devices
array with an mfd_cell array.

        Arnd
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to