All of lore.kernel.org
 help / color / mirror / Atom feed
From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 1/7] mfd: add pruss mfd driver.
Date: Fri, 11 Mar 2011 16:28:57 +0100	[thread overview]
Message-ID: <201103111628.57549.arnd@arndb.de> (raw)
In-Reply-To: <1299592667-21367-2-git-send-email-subhasish@mistralsolutions.com>

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

WARNING: multiple messages have this Message-ID (diff)
From: Arnd Bergmann <arnd@arndb.de>
To: linux-arm-kernel@lists.infradead.org
Cc: Subhasish Ghosh <subhasish@mistralsolutions.com>,
	davinci-linux-open-source@linux.davincidsp.com,
	sachi@mistralsolutions.com, Samuel Ortiz <sameo@linux.intel.com>,
	nsekhar@ti.com, open list <linux-kernel@vger.kernel.org>,
	m-watkins@ti.com, "Marc Kleine-Budde" <mkl@pengutronix.de>
Subject: Re: [PATCH v3 1/7] mfd: add pruss mfd driver.
Date: Fri, 11 Mar 2011 16:28:57 +0100	[thread overview]
Message-ID: <201103111628.57549.arnd@arndb.de> (raw)
In-Reply-To: <1299592667-21367-2-git-send-email-subhasish@mistralsolutions.com>

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

  parent reply	other threads:[~2011-03-11 15:28 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-08 13:57 [PATCH v3 0/7] pruss mfd drivers Subhasish Ghosh
2011-03-08 13:57 ` [PATCH v3 1/7] mfd: add pruss mfd driver Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-09 11:56   ` Marc Kleine-Budde
2011-03-09 11:56     ` Marc Kleine-Budde
2011-03-24 13:16     ` Subhasish Ghosh
2011-03-24 13:16       ` Subhasish Ghosh
2011-03-24 13:24       ` Marc Kleine-Budde
2011-03-24 13:24         ` Marc Kleine-Budde
2011-03-24 13:41         ` Kurt Van Dijck
2011-03-24 13:41           ` Kurt Van Dijck
2011-03-11 15:28   ` Arnd Bergmann [this message]
2011-03-11 15:28     ` Arnd Bergmann
2011-03-30  7:16     ` Subhasish Ghosh
2011-03-30  7:16       ` Subhasish Ghosh
2011-03-30 10:59       ` Arnd Bergmann
2011-03-30 10:59         ` Arnd Bergmann
2011-04-05  6:40         ` Subhasish Ghosh
2011-04-05  6:40           ` Subhasish Ghosh
2011-03-30  9:15     ` Subhasish Ghosh
2011-03-30  9:15       ` Subhasish Ghosh
2011-03-30 11:38       ` Arnd Bergmann
2011-03-30 11:38         ` Arnd Bergmann
2011-03-18 11:59   ` Nori, Sekhar
2011-03-18 11:59     ` Nori, Sekhar
2011-03-18 12:39     ` Mark Brown
2011-03-18 12:39       ` Mark Brown
2011-03-22  9:35       ` Nori, Sekhar
2011-03-22  9:35         ` Nori, Sekhar
2011-03-22  9:43         ` Nori, Sekhar
2011-03-22  9:43           ` Nori, Sekhar
2011-03-22 16:52         ` Mark Brown
2011-03-22 16:52           ` Mark Brown
2011-03-08 13:57 ` [PATCH v3 2/7] da850: pruss platform specific additions Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 15:17   ` Sergei Shtylyov
2011-03-08 15:17     ` Sergei Shtylyov
2011-03-08 13:57 ` [PATCH v3 3/7] da850: pruss board " Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 15:19   ` Sergei Shtylyov
2011-03-08 15:19     ` Sergei Shtylyov
2011-03-09  4:29     ` Subhasish Ghosh
2011-03-09  4:29       ` Subhasish Ghosh
2011-03-09 11:59   ` Marc Kleine-Budde
2011-03-09 11:59     ` Marc Kleine-Budde
2011-03-08 13:57 ` [PATCH v3 4/7] mfd: pruss SUART private data Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 13:57 ` [PATCH v3 5/7] da850: pruss SUART board specific additions Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 13:57 ` [PATCH v3 6/7] da850: pruss SUART platform " Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 13:57 ` [PATCH v3 7/7] tty: add pruss SUART driver Subhasish Ghosh
2011-03-08 13:57   ` Subhasish Ghosh
2011-03-08 18:47   ` Randy Dunlap
2011-03-08 18:47     ` Randy Dunlap
2011-03-15  7:23     ` Subhasish Ghosh
2011-03-15  7:23       ` Subhasish Ghosh
2011-03-18  5:43   ` Subhasish Ghosh
2011-03-18  5:43     ` Subhasish Ghosh
2011-03-18 11:45     ` Alan Cox
2011-03-18 11:45       ` Alan Cox
2011-03-18 12:07     ` Arnd Bergmann
2011-03-18 12:07       ` Arnd Bergmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201103111628.57549.arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.