* [PATCHv2 4/7] ARM: i2c: omap: Remove the i207 errata flag
From: Felipe Balbi @ 2012-11-05 7:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352025873-27492-5-git-send-email-shubhrajyoti@ti.com>
On Sun, Nov 04, 2012 at 04:14:30PM +0530, Shubhrajyoti D wrote:
> The commit [i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207]
> uses the revision id instead of the flag. So the flag can be safely removed.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
> ---
> arch/arm/mach-omap2/omap_hwmod_2430_data.c | 3 +--
> arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 9 +++------
> drivers/i2c/busses/i2c-omap.c | 3 +--
> include/linux/i2c-omap.h | 1 -
> 4 files changed, 5 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
> index c455e41..b79ccf6 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
> @@ -76,8 +76,7 @@ static struct omap_hwmod_class i2c_class = {
>
> static struct omap_i2c_dev_attr i2c_dev_attr = {
> .fifo_depth = 8, /* bytes */
> - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
> - OMAP_I2C_FLAG_BUS_SHIFT_2 |
> + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 |
> OMAP_I2C_FLAG_FORCE_19200_INT_CLK,
> };
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index f67b7ee..943222c4 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
> /* I2C1 */
> static struct omap_i2c_dev_attr i2c1_dev_attr = {
> .fifo_depth = 8, /* bytes */
> - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
> - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> OMAP_I2C_FLAG_BUS_SHIFT_2,
> };
>
> @@ -818,8 +817,7 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = {
> /* I2C2 */
> static struct omap_i2c_dev_attr i2c2_dev_attr = {
> .fifo_depth = 8, /* bytes */
> - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
> - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> OMAP_I2C_FLAG_BUS_SHIFT_2,
> };
>
> @@ -845,8 +843,7 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = {
> /* I2C3 */
> static struct omap_i2c_dev_attr i2c3_dev_attr = {
> .fifo_depth = 64, /* bytes */
> - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
> - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> OMAP_I2C_FLAG_BUS_SHIFT_2,
> };
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index b62cd9d..8a54efc 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -1029,8 +1029,7 @@ static const struct i2c_algorithm omap_i2c_algo = {
> #ifdef CONFIG_OF
> static struct omap_i2c_bus_platform_data omap3_pdata = {
> .rev = OMAP_I2C_IP_VERSION_1,
> - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 |
> - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE |
> OMAP_I2C_FLAG_BUS_SHIFT_2,
> };
>
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index df804ba..5c88187 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -21,7 +21,6 @@
> #define OMAP_I2C_FLAG_SIMPLE_CLOCK BIT(1)
> #define OMAP_I2C_FLAG_16BIT_DATA_REG BIT(2)
> #define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3)
> -#define OMAP_I2C_FLAG_APPLY_ERRATA_I207 BIT(4)
> #define OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK BIT(5)
> #define OMAP_I2C_FLAG_FORCE_19200_INT_CLK BIT(6)
> /* how the CPU address bus must be translated for I2C unit access */
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/4eacb659/attachment-0001.sig>
^ permalink raw reply
* [PATCHv2 5/7] i2c: omap: re-factor omap_i2c_init function
From: Felipe Balbi @ 2012-11-05 7:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352025873-27492-6-git-send-email-shubhrajyoti@ti.com>
On Sun, Nov 04, 2012 at 04:14:31PM +0530, Shubhrajyoti D wrote:
> re-factor omap_i2c_init() so that we can re-use it for resume.
> While at it also remove the bufstate variable as we write it
> in omap_i2c_resize_fifo for every transfer.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
> ---
> drivers/i2c/busses/i2c-omap.c | 75 +++++++++++++++++++----------------------
> 1 files changed, 35 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 8a54efc..a87c20a 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -209,7 +209,6 @@ struct omap_i2c_dev {
> u16 pscstate;
> u16 scllstate;
> u16 sclhstate;
> - u16 bufstate;
> u16 syscstate;
> u16 westate;
> u16 errata;
> @@ -275,9 +274,34 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
> (i2c_dev->regs[reg] << i2c_dev->reg_shift));
> }
>
> +static void __omap_i2c_init(struct omap_i2c_dev *dev)
> +{
> +
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> +
> + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> +
> + /* SCL low and high time values */
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> +
> + /* Take the I2C module out of reset: */
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> +
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +}
> +
> static int omap_i2c_init(struct omap_i2c_dev *dev)
> {
> - u16 psc = 0, scll = 0, sclh = 0, buf = 0;
> + u16 psc = 0, scll = 0, sclh = 0;
> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> unsigned long fclk_rate = 12000000;
> unsigned long timeout;
> @@ -327,11 +351,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> * REVISIT: Some wkup sources might not be needed.
> */
> dev->westate = OMAP_I2C_WE_ALL;
> - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
> - dev->westate);
> }
> }
> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>
> if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
> /*
> @@ -416,28 +437,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
> }
>
> - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
> - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
> -
> - /* SCL low and high time values */
> - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
> - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
> -
> - /* Take the I2C module out of reset: */
> - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> -
> - /* Enable interrupts */
> dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
> OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
> (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> - if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - dev->pscstate = psc;
> - dev->scllstate = scll;
> - dev->sclhstate = sclh;
> - dev->bufstate = buf;
> - }
> +
> + dev->pscstate = psc;
> + dev->scllstate = scll;
> + dev->sclhstate = sclh;
> +
> + __omap_i2c_init(dev);
> +
> return 0;
> }
>
> @@ -1297,23 +1307,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
> if (!_dev->regs)
> return 0;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> - }
> -
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + __omap_i2c_init(_dev);
>
> return 0;
> }
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/dfc44b4b/attachment.sig>
^ permalink raw reply
* [PATCHv2 6/7] i2c: omap: make reset a seperate function
From: Felipe Balbi @ 2012-11-05 7:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352025873-27492-7-git-send-email-shubhrajyoti@ti.com>
Hi,
On Sun, Nov 04, 2012 at 04:14:32PM +0530, Shubhrajyoti D wrote:
> Implement reset as a separate function.
> This will enable us to make sure that we don't do the
> calculation again on every transfer.
> Also at probe the reset is not added as the hwmod is doing that
> for us.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
> ---
> todo: reprodue the errors and optimise the reset if possible.
>
> drivers/i2c/busses/i2c-omap.c | 25 ++++++++++++++++---------
> 1 files changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a87c20a..70d43b7 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -299,15 +299,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev)
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> }
>
> -static int omap_i2c_init(struct omap_i2c_dev *dev)
> +static int omap_i2c_reset(struct omap_i2c_dev *dev)
> {
> - u16 psc = 0, scll = 0, sclh = 0;
> - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> - unsigned long fclk_rate = 12000000;
> unsigned long timeout;
> - unsigned long internal_clk = 0;
> - struct clk *fclk;
> -
> if (dev->rev >= OMAP_I2C_OMAP1_REV_2) {
> /* Disable I2C controller before soft reset */
> omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
> @@ -353,6 +347,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> dev->westate = OMAP_I2C_WE_ALL;
> }
> }
> + return 0;
> +}
> +
> +static int omap_i2c_init(struct omap_i2c_dev *dev)
> +{
> + u16 psc = 0, scll = 0, sclh = 0;
> + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> + unsigned long fclk_rate = 12000000;
> + unsigned long internal_clk = 0;
> + struct clk *fclk;
> +
>
> if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
> /*
> @@ -592,7 +597,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
> dev->buf_len = 0;
> if (timeout == 0) {
> dev_err(dev->dev, "controller timed out\n");
> - omap_i2c_init(dev);
> + omap_i2c_reset(dev);
> + __omap_i2c_init(dev);
> return -ETIMEDOUT;
> }
>
> @@ -602,7 +608,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
> /* We have an error */
> if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
> OMAP_I2C_STAT_XUDF)) {
> - omap_i2c_init(dev);
> + omap_i2c_reset(dev);
> + __omap_i2c_init(dev);
> return -EIO;
> }
>
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/d1d68a8a/attachment.sig>
^ permalink raw reply
* [PATCHv2 7/7] i2c: omap: Restore i2c context always
From: Felipe Balbi @ 2012-11-05 7:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352025873-27492-8-git-send-email-shubhrajyoti@ti.com>
Hi,
On Sun, Nov 04, 2012 at 04:14:33PM +0530, Shubhrajyoti D wrote:
> Currently the restore is done based on the flag
> OMAP_I2C_FLAG_RESET_REGS_POSTIDLE.
>
> This helps the following
> - The driver is always capable of restoring regardless
> of the off mode support being there or not.
>
> - While testing omap2430 it is found that in case of certain
> error paths (timeout) a reset is done. However the restore
> never happens as it is dependent on the POSTIDLE flag.
> The other option would be to call a restore in the reset
> case. As there are only a few registers to be restored
> the penalty in the idle case should not be much.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Looks ok to me, one less unnecessary flag.
Reviewed-by: Felipe Balbi <balbi@ti.com>
> ---
> Todo: the flag could be deleted if the patch is accepted.
>
> drivers/i2c/busses/i2c-omap.c | 3 +--
> 1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 70d43b7..f66c5ab 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -1314,8 +1314,7 @@ static int omap_i2c_runtime_resume(struct device *dev)
> if (!_dev->regs)
> return 0;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> - __omap_i2c_init(_dev);
> + __omap_i2c_init(_dev);
>
> return 0;
> }
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/16f65478/attachment.sig>
^ permalink raw reply
* [PATCH 3/3] ARM: OMAP: Remove plat-omap/common.c
From: Tomi Valkeinen @ 2012-11-05 8:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121102185453.GY15766@atomide.com>
On 2012-11-02 20:54, Tony Lindgren wrote:
>> * Santosh Shilimkar <santosh.shilimkar@ti.com> [121102 01:56]:
>>> On Friday 02 November 2012 02:19 PM, Tomi Valkeinen wrote:
>>>> On 2012-11-02 08:38, Santosh Shilimkar wrote:
>>>>>
>>>>> Lets not move this in DMA code since the above is really related
>>>>> to frame buffer. It reserves more DMA area for dma_alloc_coherent()
>>>>> etc than default 2 MB. Infact, we should no longer need this with
>>>>> CMA and memblock in place.
>>>>>
>>>>> Tomi,
>>>>> Can we not get rid of the above memory reservation ?
>>>>
>>>> Yes, I think so. This one is only used for the old omapfb, i.e. omap1,
>>>> and I have no means to test it out, though. But below is a patch to
>>>> remove it. I also attached the patch, as it looks like thunderbird wants
>>>> to reformat the pasted patch... I'll remove the
>>>> CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE from the omapfb driver's Kconfig file
>>>> in my tree later.
>
> Hmm actually, is it safe to remove for omap1, or should we
> still keep it around for omap1?
Why wouldn't it be safe? Do you mean that CMA doesn't work on omap1,
or...? I'm no expert on CMA, but as far as I can see with it's ARM
generic stuff.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 897 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/106f3a2e/attachment.sig>
^ permalink raw reply
* [PATCH v2] i2c: omap: ensure writes to dev->buf_len are ordered
From: Felipe Balbi @ 2012-11-05 8:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121102085447.GE17063@arwen.pp.htv.fi>
if we allow compiler reorder our writes, we could
fall into a situation where dev->buf_len is reset
for no apparent reason.
This bug was found with a simple script which would
transfer data to an i2c client from 1 to 1024 bytes
(a simple for loop), when we got to transfer sizes
bigger than the fifo size, dev->buf_len was reset
to zero before we had an oportunity to handle XDR
Interrupt. Because dev->buf_len was zero, we entered
omap_i2c_transmit_data() to transfer zero bytes,
which would mean we would just silently exit
omap_i2c_transmit_data() without actually writing
anything to DATA register. That would cause XDR
IRQ to trigger forever and we would never transfer
the remaining bytes.
After adding the memory barrier, we also drop resetting
dev->buf_len to zero in omap_i2c_xfer_msg() because
both omap_i2c_transmit_data() and omap_i2c_receive_data()
will act until dev->buf_len reaches zero, rendering the
other write in omap_i2c_xfer_msg() redundant.
This patch has been tested with pandaboard for a few
iterations of the script mentioned above.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
Changes since v1:
- use barrier() instead of wmb()
Note: this version was compile-tested only
drivers/i2c/busses/i2c-omap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index db31eae..ba03bec 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -521,6 +521,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
dev->buf = msg->buf;
dev->buf_len = msg->len;
+ barrier();
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
@@ -579,7 +580,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
*/
timeout = wait_for_completion_timeout(&dev->cmd_complete,
OMAP_I2C_TIMEOUT);
- dev->buf_len = 0;
if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
omap_i2c_init(dev);
--
1.8.0
^ permalink raw reply related
* [PATCH v2 0/7] I2C patches for v3.8 merge window
From: Felipe Balbi @ 2012-11-05 8:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351167915-15079-1-git-send-email-balbi@ti.com>
Hi,
On Thu, Oct 25, 2012 at 03:25:08PM +0300, Felipe Balbi wrote:
> Hi,
>
> here's another series for OMAP I2C driver. There are a few cleanups
> and one very nice new feature: we can now report how many bytes
> we transferred until NACK.
>
> Note that the implemementation for OMAP-I2C turned out to be a
> little more complex then I expected, mainly because of the way
> I2C_CNT register behaves and because of the very buggy register
> usage on that driver.
>
> I have boot tested all patches on beagle xM (3630) and pandaboard
> rev A3 (4430), will send boot-logs if anyone wants to see.
>
> All patches are available at [1] if anyone wants an easy way to
> test the patches.
Wolfram, patches 1-5 are ok to apply, we just need to rework patches 6
and 7 so drivers can report how many bytes managed to be transferred.
None of these patches cause any known regressions.
let me know if you want me to resend only the 5 patches which should be
applied.
cheers
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/49c4a6f5/attachment.sig>
^ permalink raw reply
* [PATCH] ARM: OMAP2+: AM33XX: clock data: fix mcasp entries
From: Mark Brown @ 2012-11-05 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=GYpYuyfGuEgAWJyE2nkKx4GEsm=eDYAhV966sWVLbEPaqYQ@mail.gmail.com>
On Sat, Nov 03, 2012 at 02:32:59PM -0500, Joel A Fernandes wrote:
> beaglebone_defconfig: Add dummy regulator to init tlv320aic3x
> https://github.com/joelagnel/linux-kernel/commit/db5672dfe548d82625cf40ed688d05ba7cee5c93
This should never be done in production, you should ensure that the
appropriate supplies are provided by the board file or device tree.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/864f0b21/attachment.sig>
^ permalink raw reply
* [PATCH 2/9] ARM: at91: Remove unused struct at91sam9g45_isi_device and its resources
From: Josh Wu @ 2012-11-05 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1351980150-24145-3-git-send-email-lee.jones@linaro.org>
Hi, Lee Jones
On 11/4/2012 6:02 AM, Lee Jones wrote:
> This the at91sam9g45_isi_device structure and its associated resources
> were added in 2008 and have been unused ever since. Let's remove them.
I'm the maintainer of the Atmel ISI driver. Currently the ISI still not
work on at91sam9263 board.
But this task is in my plan. So keep those code and I will enable ISI
support for 9263 in the future. Thanks.
Best Regards,
Josh Wu
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
> arch/arm/mach-at91/at91sam9263_devices.c | 20 --------------------
> 1 file changed, 20 deletions(-)
>
> diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
> index cb85da2..0562a9d 100644
> --- a/arch/arm/mach-at91/at91sam9263_devices.c
> +++ b/arch/arm/mach-at91/at91sam9263_devices.c
> @@ -901,26 +901,6 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
>
> #if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE)
>
> -struct resource isi_resources[] = {
> - [0] = {
> - .start = AT91SAM9263_BASE_ISI,
> - .end = AT91SAM9263_BASE_ISI + SZ_16K - 1,
> - .flags = IORESOURCE_MEM,
> - },
> - [1] = {
> - .start = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI,
> - .end = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI,
> - .flags = IORESOURCE_IRQ,
> - },
> -};
> -
> -static struct platform_device at91sam9263_isi_device = {
> - .name = "at91_isi",
> - .id = -1,
> - .resource = isi_resources,
> - .num_resources = ARRAY_SIZE(isi_resources),
> -};
> -
> void __init at91_add_device_isi(struct isi_platform_data *data,
> bool use_pck_as_mck)
> {
^ permalink raw reply
* [PATCH 2/9] ARM: at91: Remove unused struct at91sam9g45_isi_device and its resources
From: Lee Jones @ 2012-11-05 8:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5097753F.7080307@atmel.com>
> >This the at91sam9g45_isi_device structure and its associated resources
> >were added in 2008 and have been unused ever since. Let's remove them.
>
> I'm the maintainer of the Atmel ISI driver. Currently the ISI still
> not work on at91sam9263 board.
> But this task is in my plan. So keep those code and I will enable
> ISI support for 9263 in the future. Thanks.
No problem at all. Thanks for getting back to me Josh.
Kind regards,
Lee
> >Cc: Russell King <linux@arm.linux.org.uk>
> >Cc: linux-arm-kernel at lists.infradead.org
> >Signed-off-by: Lee Jones <lee.jones@linaro.org>
> >---
> > arch/arm/mach-at91/at91sam9263_devices.c | 20 --------------------
> > 1 file changed, 20 deletions(-)
> >
> >diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
> >index cb85da2..0562a9d 100644
> >--- a/arch/arm/mach-at91/at91sam9263_devices.c
> >+++ b/arch/arm/mach-at91/at91sam9263_devices.c
> >@@ -901,26 +901,6 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
> > #if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE)
> >-struct resource isi_resources[] = {
> >- [0] = {
> >- .start = AT91SAM9263_BASE_ISI,
> >- .end = AT91SAM9263_BASE_ISI + SZ_16K - 1,
> >- .flags = IORESOURCE_MEM,
> >- },
> >- [1] = {
> >- .start = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI,
> >- .end = NR_IRQS_LEGACY + AT91SAM9263_ID_ISI,
> >- .flags = IORESOURCE_IRQ,
> >- },
> >-};
> >-
> >-static struct platform_device at91sam9263_isi_device = {
> >- .name = "at91_isi",
> >- .id = -1,
> >- .resource = isi_resources,
> >- .num_resources = ARRAY_SIZE(isi_resources),
> >-};
> >-
> > void __init at91_add_device_isi(struct isi_platform_data *data,
> > bool use_pck_as_mck)
> > {
>
--
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCHv2 0/7] i2c: omap: updates
From: Shubhrajyoti @ 2012-11-05 8:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121105074607.GA32468@arwen.pp.htv.fi>
On Monday 05 November 2012 01:16 PM, Felipe Balbi wrote:
>> include/linux/i2c-omap.h | 1 -
>> > 4 files changed, 104 insertions(+), 75 deletions(-)
> since I have reviewed your previous version, it would be nice to Cc me
> so I don't loose your series ;-)
OK will do that. thanks :-)
^ permalink raw reply
* [PATCHv2 1/7] i2c: omap: Fix the revision register read
From: Shubhrajyoti @ 2012-11-05 8:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121105075026.GB32468@arwen.pp.htv.fi>
On Monday 05 November 2012 01:20 PM, Felipe Balbi wrote:
> Hi,
>
> On Sun, Nov 04, 2012 at 04:14:27PM +0530, Shubhrajyoti D wrote:
>> The revision register on OMAP4 is a 16-bit lo and a 16-bit
>> hi. Currently the driver reads only the lower 8-bits.
>> Fix the same by preventing the truncating of the rev register
>> for OMAP4.
>>
>> Also use the scheme bit ie bit-14 of the hi register to know if it
>> is OMAP_I2C_IP_VERSION_2.
>>
>> On platforms previous to OMAP4 the offset 0x04 is IE register whose
>> bit-14 reset value is 0, the code uses the same to its advantage.
>>
>> Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done
>> to fetch the revision register.
>>
>> The dev->regs is populated after reading the rev_hi. A NULL check
>> has been added in the resume handler to prevent the access before
>> the setting of the regs.
>>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>> drivers/i2c/busses/i2c-omap.c | 61 ++++++++++++++++++++++++++++++++---------
>> 1 files changed, 48 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>> index db31eae..72fce6d 100644
>> --- a/drivers/i2c/busses/i2c-omap.c
>> +++ b/drivers/i2c/busses/i2c-omap.c
>> @@ -49,9 +49,10 @@
>> #define OMAP_I2C_OMAP1_REV_2 0x20
>>
>> /* I2C controller revisions present on specific hardware */
>> -#define OMAP_I2C_REV_ON_2430 0x36
>> -#define OMAP_I2C_REV_ON_3430_3530 0x3C
>> -#define OMAP_I2C_REV_ON_3630_4430 0x40
>> +#define OMAP_I2C_REV_ON_2430 0x00000036
>> +#define OMAP_I2C_REV_ON_3430_3530 0x0000003C
>> +#define OMAP_I2C_REV_ON_3630 0x00000040
>> +#define OMAP_I2C_REV_ON_4430_PLUS 0x50400002
>>
>> /* timeout waiting for the controller to respond */
>> #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
>> @@ -202,7 +203,7 @@ struct omap_i2c_dev {
>> * fifo_size==0 implies no fifo
>> * if set, should be trsh+1
>> */
>> - u8 rev;
>> + u32 rev;
>> unsigned b_hw:1; /* bad h/w fixes */
>> unsigned receiver:1; /* true when we're in receiver mode */
>> u16 iestate; /* Saved interrupt register */
>> @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
>>
>> omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
>>
>> - if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
>> + if (dev->rev < OMAP_I2C_REV_ON_3630)
>> dev->b_hw = 1; /* Enable hardware fixes */
>>
>> /* calculate wakeup latency constraint for MPU */
>> @@ -1052,6 +1053,16 @@ static const struct of_device_id omap_i2c_of_match[] = {
>> MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
>> #endif
>>
>> +#define OMAP_I2C_SCHEME(rev) ((rev & 0xc000) >> 14)
>> +
>> +#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev >> 4)
>> +#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev & 0xf)
>> +
>> +#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev & 0x0700) >> 7)
>> +#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev & 0x1f)
>> +#define OMAP_I2C_SCHEME_0 0
>> +#define OMAP_I2C_SCHEME_1 1
>> +
>> static int __devinit
>> omap_i2c_probe(struct platform_device *pdev)
>> {
>> @@ -1064,6 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev)
>> const struct of_device_id *match;
>> int irq;
>> int r;
>> + u32 rev;
>> + u16 minor, major;
>>
>> /* NOTE: driver uses the static register mapping */
>> mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> @@ -1117,11 +1130,6 @@ omap_i2c_probe(struct platform_device *pdev)
>>
>> dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
>>
>> - if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
>> - dev->regs = (u8 *)reg_map_ip_v2;
>> - else
>> - dev->regs = (u8 *)reg_map_ip_v1;
>> -
>> pm_runtime_enable(dev->dev);
>> pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT);
>> pm_runtime_use_autosuspend(dev->dev);
>> @@ -1130,7 +1138,31 @@ omap_i2c_probe(struct platform_device *pdev)
>> if (IS_ERR_VALUE(r))
>> goto err_free_mem;
>>
>> - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
>> + /*
>> + * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
>> + * On omap3 Offset 4 is IE Reg the bit [15:14] is XDR_IE which is 0
> comment is wrong. You talk about 2 bits and document only one of them.
> Also, this is valid for all OMAPs until OMAP3, comment should probably
> read: On OMAP1/2/3 offset 0x04 is.....
will fix the comment.
>
>> + * at reset. Also since the omap_i2c_read_reg uses reg_map_ip_* a
>> + * raw_readw is done.
>> + */
>> + rev = __raw_readw(dev->base + 0x04);
>> +
>> + switch (OMAP_I2C_SCHEME(rev)) {
>> + case OMAP_I2C_SCHEME_0:
>> + dev->regs = (u8 *)reg_map_ip_v1;
>> + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
> drop the 0xff. Top byte is supposed to be zero
yes.
> and if it's not, we want
> to know what they hold.
OK. Just thought that the reserved values can wiped off:-)
>
>> + minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
>> + major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
>> + break;
>> + case OMAP_I2C_SCHEME_1:
>> + /* FALLTHROUGH */
>> + default:
>> + dev->regs = (u8 *)reg_map_ip_v2;
>> + rev = (rev << 16) |
>> + omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO);
>> + minor = OMAP_I2C_REV_SCHEME_1_MINOR(rev);
>> + major = OMAP_I2C_REV_SCHEME_1_MAJOR(rev);
>> + dev->rev = rev;
>> + }
>>
>> dev->errata = 0;
>>
>> @@ -1155,7 +1187,7 @@ omap_i2c_probe(struct platform_device *pdev)
>>
>> dev->fifo_size = (dev->fifo_size / 2);
>>
>> - if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
>> + if (dev->rev < OMAP_I2C_REV_ON_3630)
>> dev->b_hw = 1; /* Enable hardware fixes */
> looks like this was applicable to 4430 too, what happened ?
No actually this can be deleted completely once the
start -> transaction -> stop sequence recommendation is followed.
>
^ permalink raw reply
* [PATCH net-next 0/2] cpsw: fix resource leak for v3.8
From: N, Mugunthan V @ 2012-11-05 8:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1351930782.git.richardcochran@gmail.com>
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran at gmail.com]
> Sent: Saturday, November 03, 2012 1:55 PM
> To: netdev at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; David Miller; Chemparathy,
> Cyril; N, Mugunthan V; Hiremath, Vaibhav
> Subject: [PATCH net-next 0/2] cpsw: fix resource leak for v3.8
>
> While looking at the idea of removing all of the register offsets in
> the CPSW's device tree, I noticed that the driver would be leaking IO
> mappings. Although this is, strictly speaking, a bug fix, still it can
> wait to appear in v3.8, since there is no way to use the driver in
> v3.7 (or earlier) anyhow.
>
> Thanks,
> Richard
>
>
> Richard Cochran (2):
> cpsw: rename register banks to match the reference manual, part 2
> cpsw: fix leaking IO mappings
>
> drivers/net/ethernet/ti/cpsw.c | 39 +++++++++++++++++++-------------
> -------
> 1 files changed, 19 insertions(+), 20 deletions(-)
>
> --
> 1.7.2.5
The patches look good to me.
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
^ permalink raw reply
* [PATCHv2 3/7] i2c: omap: remove the dtrev
From: Shubhrajyoti @ 2012-11-05 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121105075320.GD32468@arwen.pp.htv.fi>
On Monday 05 November 2012 01:23 PM, Felipe Balbi wrote:
> Hi,
>
> On Sun, Nov 04, 2012 at 04:14:29PM +0530, Shubhrajyoti D wrote:
>> The dtrev is used only for the comments. Remove the same and use
>> the scheme instead to know if it is version2.
>>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> I would drop dtrev completely and not use scheme to "emulate" it.
However for ver2 ie omap4plus and previous versions the
register map is different.
So the scheme may still be required.
> dtrev
> is wrong and unnecessary; it was only created due to the wrong
> assumption that HW revision register was wrong. Looks like that
> assumption was made based on the driver which is clearly wrong wrt
> revision detection.
>
> Also, when dropping dtrev, also drop it from platform_data and
> omap_hwmod database (could be done on a separate patch).
OK would do that.
>
^ permalink raw reply
* [PATCHv2 1/7] i2c: omap: Fix the revision register read
From: Felipe Balbi @ 2012-11-05 9:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50977A30.6040907@ti.com>
Hi,
On Mon, Nov 05, 2012 at 02:04:56PM +0530, Shubhrajyoti wrote:
> >> @@ -1155,7 +1187,7 @@ omap_i2c_probe(struct platform_device *pdev)
> >>
> >> dev->fifo_size = (dev->fifo_size / 2);
> >>
> >> - if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
> >> + if (dev->rev < OMAP_I2C_REV_ON_3630)
> >> dev->b_hw = 1; /* Enable hardware fixes */
> > looks like this was applicable to 4430 too, what happened ?
> No actually this can be deleted completely once the
> start -> transaction -> stop sequence recommendation is followed.
yes, but we're not there just yet and this patch is changing the
behavior of the driver in ways which don't belong to $SUBJECT.
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/a8bb6ef4/attachment.sig>
^ permalink raw reply
* [PATCHv2 3/7] i2c: omap: remove the dtrev
From: Felipe Balbi @ 2012-11-05 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50977C80.8090000@ti.com>
Hi,
On Mon, Nov 05, 2012 at 02:14:48PM +0530, Shubhrajyoti wrote:
> On Monday 05 November 2012 01:23 PM, Felipe Balbi wrote:
> > Hi,
> >
> > On Sun, Nov 04, 2012 at 04:14:29PM +0530, Shubhrajyoti D wrote:
> >> The dtrev is used only for the comments. Remove the same and use
> >> the scheme instead to know if it is version2.
> >>
> >> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> > I would drop dtrev completely and not use scheme to "emulate" it.
> However for ver2 ie omap4plus and previous versions the
> register map is different.
>
> So the scheme may still be required.
fair enough, but drop it from debugging messages.
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/300244f5/attachment.sig>
^ permalink raw reply
* [PATCH 08/15] ARM: OMAP2+: hwmod: Fix the omap_hwmod_addr_space for CPGMAC0
From: Bedia, Vaibhav @ 2012-11-05 9:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <509543E8.60209@ti.com>
On Sun, Nov 04, 2012 at 20:54:17, Bedia, Vaibhav wrote:
> On Sat, Nov 03, 2012 at 21:48:48, Shilimkar, Santosh wrote:
> > On Friday 02 November 2012 06:02 PM, Vaibhav Bedia wrote:
> > > The first entry for CPGMAC0 should be ADDR_MAP_ON_INIT
> > > instead of ADDR_TYPE_RT to ensure the omap hwmod code
> > > maps the memory space at init and writes to the SYSCONFIG
> > > registers.
> > >
> > > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > > ---
> > Sorry again similar question.
> >
> > Why CPGMAC0 should be mapped and sysconfig updated early ?
> >
>
> Hmm I need to revisit this one. CPGMAC0 was not going to standby
> without this. Maybe something else is wrong in the hwmod data and
> needs fixing.
>
Ok I checked this one. The change I made was indirectly fixing another
issue with the AM33xx hwmod data. am33xx_cpgmac0_addr_space[] has two
entries and the SYSC register is part of the second entry. The function
_find_mpu_rt_addr_space in omap_hwmod.c looks for the first entry with
the flag ADDR_TYPE_RT flag. The change I made indirectly made the second
entry in am33xx_cpgmac0_addr_space[] become the first memory space with
the ADDR_TYPE_RT flag. Due to this the hwmod code wrote to the correct
SYSC address of CPGMAC0 and the IP went to standby during bootup.
After changing the order of the entries in am33xx_cpgmac0_addr_space[]
things work fine.
I'll make the changes in the next version.
Regards,
Vaibhav
^ permalink raw reply
* [PATCH 0/8] Support for AM33xx PWM Susbsytem
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In AM33xx PWM sub modules like ECAP, EHRPWM & EQEP are integrated to
PWM subsystem. All these submodules shares the resources (clock) & has
a clock gating register in PWM Subsystem. This patch series creates a
parent PWM Subsystem driver to handle access synchronization of shared
resources & clock gating from PWM Subsystem configuration space.
Also Device tree nodes populated to support parent child relation
between PWMSS, ECAP & EHRPWM submodules.
In addition EHRPWM module requires explicit clock gating from control
module & is handled by patch #2 & 6.
Patch #4 & 5 submitted is a second revision as suggested by Thierry
for handling clock gating with a global function . This requires config
space handling done independent from driver and is done at parent driver.
So the parent<->child relation adopted to handle
1. pm runtime synchronization
2. PWM subsystem common config space clock gating for PWM submodules.
Patches supports
- Driver support for parent child relation handled patch #1
- Optional EHRPWM tb clock in patch #2
- Parent child in HWMOD handled at patch #3
- Device tree binding support handled in patch #4-6
- DT node populated in patch #7-8.
This patch series based on linux-next/20121102 and tested on AM335x-evm.
It depends on [1]
1. https://lkml.org/lkml/2012/10/29/589
pwm: Device tree support for PWM polarity
Philip, Avinash (8):
PWMSS: Add PWM Subsystem driver for parent<->child relationship
ARM: am33xx: clk: Add optional clock for EHRPWM
ARM: OMAP: AM33xx hwmod: Add parent-child relationship for PWM
subsystem
pwm: pwm-tiecap: Add device-tree binding support for APWM driver
pwm: pwm-tiehrpwm: Add device-tree binding support for EHRPWM driver
pwm: pwm-tiehrpwm: Adding TBCLK gating support.
ARM: dts: AM33XX: Add PWMSS device tree nodes
ARM: dts: AM33XX: Add PWM backlight DT data to am335x-evm
.../devicetree/bindings/pwm/pwm-tiecap.txt | 22 +
.../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 25 ++
Documentation/devicetree/bindings/pwm/tipwmss.txt | 30 ++
arch/arm/boot/dts/am335x-evm.dts | 21 +
arch/arm/boot/dts/am33xx.dtsi | 90 +++++
arch/arm/mach-omap2/clock33xx_data.c | 37 ++
arch/arm/mach-omap2/control.h | 8 +
arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 414 +++++++++++++-------
drivers/pwm/Kconfig | 11 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-tiecap.c | 36 ++-
drivers/pwm/pwm-tiehrpwm.c | 53 +++-
drivers/pwm/tipwmss.c | 136 +++++++
drivers/pwm/tipwmss.h | 8 +
14 files changed, 754 insertions(+), 138 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
create mode 100644 Documentation/devicetree/bindings/pwm/tipwmss.txt
create mode 100644 drivers/pwm/tipwmss.c
create mode 100644 drivers/pwm/tipwmss.h
^ permalink raw reply
* [PATCH 1/8] PWMSS: Add PWM Subsystem driver for parent<->child relationship
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
In some platforms (like am33xx), PWM sub modules (ECAP, EHRPWM, EQEP)
are integrated to PWM subsystem. These PWM submodules has resources
shared and only one register bit-field is provided to control
module/clock enable/disable, makes it difficult to handle common
resources from independent PWMSS submodule drivers.
So the solution here implemented in this patch is, to create driver for
PWMSS and take the role of parent driver for PWM submodules. PWMSS
parent driver enumerates all the child nodes under PWMSS module. Also
symbol "pwmss_submodule_state_change" exported to enable clock gating
for individual PWMSS submodules, and submodule drivers has to enable
clock gating from their drivers.
As this is only supported during DT boot, the parent<->child relationship
is created and populated in DT execution flow. The only required change
is inside DTS file, making EHRPWM & ECAP as a child to PWMSS node.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
:000000 100644 0000000... b6c2814... A Documentation/devicetree/bindings/pwm/tipwmss.txt
:100644 100644 ed81720... 99ebcfa... M drivers/pwm/Kconfig
:100644 100644 acfe482... 1001bdb... M drivers/pwm/Makefile
:000000 100644 0000000... d30a802... A drivers/pwm/tipwmss.c
:000000 100644 0000000... 83fdc29... A drivers/pwm/tipwmss.h
Documentation/devicetree/bindings/pwm/tipwmss.txt | 30 +++++
drivers/pwm/Kconfig | 11 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/tipwmss.c | 136 +++++++++++++++++++++
drivers/pwm/tipwmss.h | 8 ++
5 files changed, 186 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/tipwmss.txt b/Documentation/devicetree/bindings/pwm/tipwmss.txt
new file mode 100644
index 0000000..b6c2814
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/tipwmss.txt
@@ -0,0 +1,30 @@
+TI SOC based PWM Subsystem
+
+Required properties:
+- compatible: Must be "ti,am33xx-pwmss";
+- reg: physical base address and size of the registers map. For am33xx,
+ 4 set of register maps present, PWMSS config space, ECAP register space,
+ EQEP register space, EHRPWM register space.
+- address-cells: Specify the number of u32 entries needed in child nodes.
+ Should set to 1.
+- size-cells: specify inumber of u32 entries needed to specify child nodes size
+ in reg property. Should set to 1.
+- ranges: describes the address mapping of a memory-mapped bus. Should set to empty
+ as parent and child address space is identical.
+
+Also child nodes should also populated under PWMSS DT node.
+Example:
+pwmss0: pwmss at 48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10
+ 0x48300100 0x80
+ 0x48300180 0x80
+ 0x48300200 0x80>;
+ ti,hwmods = "epwmss0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ /* child nodes go here */
+};
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index ed81720..99ebcfa 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -125,6 +125,7 @@ config PWM_TEGRA
config PWM_TIECAP
tristate "ECAP PWM support"
depends on SOC_AM33XX
+ select PWM_TIPWMSS
help
PWM driver support for the ECAP APWM controller found on AM33XX
TI SOC
@@ -135,6 +136,7 @@ config PWM_TIECAP
config PWM_TIEHRPWM
tristate "EHRPWM PWM support"
depends on SOC_AM33XX
+ select PWM_TIPWMSS
help
PWM driver support for the EHRPWM controller found on AM33XX
TI SOC
@@ -142,6 +144,15 @@ config PWM_TIEHRPWM
To compile this driver as a module, choose M here: the module
will be called pwm-tiehrpwm.
+config PWM_TIPWMSS
+ tristate "TI PWM Subsytem parent support"
+ depends on SOC_AM33XX && (PWM_TIEHRPWM || PWM_TIECAP)
+ help
+ PWM Subsystem driver support for AM33xx SOC.
+
+ PWM submodules require PWM config space access from submodule
+ drivers and require common parent driver support.
+
config PWM_TWL6030
tristate "TWL6030 PWM support"
depends on TWL4030_CORE
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index acfe482..1001bdb 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -11,5 +11,6 @@ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
+obj-$(CONFIG_PWM_TIPWMSS) += tipwmss.o
obj-$(CONFIG_PWM_TWL6030) += pwm-twl6030.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
diff --git a/drivers/pwm/tipwmss.c b/drivers/pwm/tipwmss.c
new file mode 100644
index 0000000..d30a802
--- /dev/null
+++ b/drivers/pwm/tipwmss.c
@@ -0,0 +1,136 @@
+/*
+ * TI PWM Subsystem driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+
+#include "tipwmss.h"
+
+struct pwmss_info {
+ void __iomem *mmio_base;
+ struct mutex pwmss_lock;
+};
+
+#define PWMSS_CLKCONFIG 8
+
+void pwmss_submodule_state_change(struct device *dev, int pos, bool enable)
+{
+ struct pwmss_info *info = dev_get_drvdata(dev);
+ u16 val;
+
+ val = readw(info->mmio_base + PWMSS_CLKCONFIG);
+ if (enable)
+ val |= 1 << pos;
+ else
+ val &= ~(1 << pos);
+ mutex_lock(&info->pwmss_lock);
+ writew(val , info->mmio_base + PWMSS_CLKCONFIG);
+ mutex_unlock(&info->pwmss_lock);
+}
+EXPORT_SYMBOL(pwmss_submodule_state_change);
+
+static const struct of_device_id pwmss_of_match[] = {
+ {
+ .compatible = "ti,am33xx-pwmss",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pwmss_of_match);
+
+static int __devinit pwmss_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *r;
+ struct pwmss_info *info;
+ struct device_node *node = pdev->dev.of_node;
+
+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&info->pwmss_lock);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
+
+ info->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
+ if (!info->mmio_base)
+ return -EADDRNOTAVAIL;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ platform_set_drvdata(pdev, info);
+
+ /* Populate all the child nodes here... */
+ ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ if (ret)
+ dev_warn(&pdev->dev, "Doesn't have any child node\n");
+
+ return ret;
+}
+
+static int __devexit pwmss_remove(struct platform_device *pdev)
+{
+ struct pwmss_info *info = platform_get_drvdata(pdev);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ mutex_destroy(&info->pwmss_lock);
+ return 0;
+}
+
+static int pwmss_suspend(struct device *dev)
+{
+ pm_runtime_put_sync(dev);
+ return 0;
+}
+
+static int pwmss_resume(struct device *dev)
+{
+ pm_runtime_get_sync(dev);
+ return 0;
+}
+
+static const struct dev_pm_ops pwmss_pm_ops = {
+ .suspend = pwmss_suspend,
+ .resume = pwmss_resume,
+};
+
+static struct platform_driver pwmss_driver = {
+ .driver = {
+ .name = "pwmss",
+ .owner = THIS_MODULE,
+ .pm = &pwmss_pm_ops,
+ .of_match_table = of_match_ptr(pwmss_of_match),
+ },
+ .probe = pwmss_probe,
+ .remove = __devexit_p(pwmss_remove),
+};
+
+module_platform_driver(pwmss_driver);
+
+MODULE_DESCRIPTION("pwmss driver");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/tipwmss.h b/drivers/pwm/tipwmss.h
new file mode 100644
index 0000000..83fdc29
--- /dev/null
+++ b/drivers/pwm/tipwmss.h
@@ -0,0 +1,8 @@
+#ifdef CONFIG_PWM_TIPWMSS
+extern void pwmss_submodule_state_change(struct device *dev, int pos,
+ bool enable);
+#else
+static inline void pwmss_submodule_state_change(struct device *dev, int pos,
+ bool enable)
+{}
+#endif
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/8] ARM: am33xx: clk: Add optional clock for EHRPWM
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
EHRPWM module requires explicit clock gating from control module.
Hence add clock node in clock tree for EHRPWM modules.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 17e3de5... 833260f... M arch/arm/mach-omap2/clock33xx_data.c
:100644 100644 a89e825... c0e34e6... M arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/clock33xx_data.c | 37 ++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/control.h | 8 +++++++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index 17e3de5..833260f 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -995,6 +995,40 @@ static struct clk wdt1_fck = {
};
/*
+ * PWMSS Time based module clock node. This node is
+ * requred to enable clock gating for EHRPWM TBCLK.
+ */
+static struct clk ehrpwm0_tbclk = {
+ .name = "ehrpwm0_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS0_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ehrpwm1_tbclk = {
+ .name = "ehrpwm1_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS1_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ehrpwm2_tbclk = {
+ .name = "ehrpwm2_tbclk",
+ .clkdm_name = "l4ls_clkdm",
+ .enable_reg = AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+ .enable_bit = AM33XX_PWMSS2_TBCLKEN_SHIFT,
+ .ops = &clkops_omap2_dflt,
+ .parent = &l4ls_gclk,
+ .recalc = &followparent_recalc,
+};
+
+/*
* clkdev
*/
static struct omap_clk am33xx_clks[] = {
@@ -1074,6 +1108,9 @@ static struct omap_clk am33xx_clks[] = {
CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX),
CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX),
CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX),
+ CLK(NULL, "ehrpwm0_tbclk", &ehrpwm0_tbclk, CK_AM33XX),
+ CLK(NULL, "ehrpwm1_tbclk", &ehrpwm1_tbclk, CK_AM33XX),
+ CLK(NULL, "ehrpwm2_tbclk", &ehrpwm2_tbclk, CK_AM33XX),
};
int __init am33xx_clk_init(void)
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a89e825..c0e34e6 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -357,6 +357,14 @@
#define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH 0x2
#define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK (0x3 << 22)
+/* AM33XX PWMSS Control register */
+#define AM33XX_PWMSS_TBCLK_CLKCTRL 0x664
+
+/* AM33XX PWMSS Control bitfields */
+#define AM33XX_PWMSS0_TBCLKEN_SHIFT 0
+#define AM33XX_PWMSS1_TBCLKEN_SHIFT 1
+#define AM33XX_PWMSS2_TBCLKEN_SHIFT 2
+
/* CONTROL OMAP STATUS register to identify OMAP3 features */
#define OMAP3_CONTROL_OMAP_STATUS 0x044c
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/8] ARM: OMAP: AM33xx hwmod: Add parent-child relationship for PWM subsystem
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
As part of PWM subsystem integration, PWM subsystem are sharing
resources like clock across submodules (ECAP, EQEP & EHRPWM).
To handle resource sharing & IP integration
1. Rework on parent child relation between PWMSS and
ECAP, EQEP & EHRPWM child devices to support runtime PM.
2. Add support for opt_clks in EHRPWM HWMOD entry to handle additional
clock gating from control module.
3. Add HWMOD entries for EQEP PWM submodule.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 ad8d43b... c419269... M arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 414 +++++++++++++++++++---------
1 files changed, 278 insertions(+), 136 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index ad8d43b..c419269 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -768,9 +768,7 @@ static struct omap_hwmod am33xx_elm_hwmod = {
},
};
-/*
- * 'epwmss' class: ecap0,1,2, ehrpwm0,1,2
- */
+/* pwmss */
static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
.rev_offs = 0x0,
.sysc_offs = 0x4,
@@ -786,18 +784,23 @@ static struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
.sysc = &am33xx_epwmss_sysc,
};
-/* ehrpwm0 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = {
- { .name = "int", .irq = 86 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 58 + OMAP_INTC_START, },
- { .irq = -1 },
+
+static struct omap_hwmod_class am33xx_ecap_hwmod_class = {
+ .name = "ecap",
};
-static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
- .name = "ehrpwm0",
+static struct omap_hwmod_class am33xx_eqep_hwmod_class = {
+ .name = "eqep",
+};
+
+static struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = {
+ .name = "ehrpwm",
+};
+/* epwmss0 */
+static struct omap_hwmod am33xx_epwmss0_hwmod = {
+ .name = "epwmss0",
.class = &am33xx_epwmss_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm0_irqs,
.main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
@@ -807,63 +810,68 @@ static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
},
};
-/* ehrpwm1 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = {
- { .name = "int", .irq = 87 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 59 + OMAP_INTC_START, },
+/* ecap0 */
+static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = {
+ { .irq = 31 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
- .name = "ehrpwm1",
- .class = &am33xx_epwmss_hwmod_class,
+static struct omap_hwmod am33xx_ecap0_hwmod = {
+ .name = "ecap0",
+ .class = &am33xx_ecap_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm1_irqs,
+ .mpu_irqs = am33xx_ecap0_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
};
-/* ehrpwm2 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = {
- { .name = "int", .irq = 39 + OMAP_INTC_START, },
- { .name = "tzint", .irq = 60 + OMAP_INTC_START, },
+/* eqep0 */
+static struct omap_hwmod_irq_info am33xx_eqep0_irqs[] = {
+ { .irq = 79 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
- .name = "ehrpwm2",
- .class = &am33xx_epwmss_hwmod_class,
+static struct omap_hwmod am33xx_eqep0_hwmod = {
+ .name = "eqep0",
+ .class = &am33xx_eqep_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ehrpwm2_irqs,
+ .mpu_irqs = am33xx_eqep0_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
};
-/* ecap0 */
-static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = {
- { .irq = 31 + OMAP_INTC_START, },
+/* ehrpwm0 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = {
+ { .name = "int", .irq = 86 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 58 + OMAP_INTC_START, },
{ .irq = -1 },
};
-static struct omap_hwmod am33xx_ecap0_hwmod = {
- .name = "ecap0",
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm0_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm0_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
+ .name = "ehrpwm0",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm0_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm0_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm0_opt_clks),
+};
+
+/* epwmss1 */
+static struct omap_hwmod am33xx_epwmss1_hwmod = {
+ .name = "epwmss1",
.class = &am33xx_epwmss_hwmod_class,
.clkdm_name = "l4ls_clkdm",
- .mpu_irqs = am33xx_ecap0_irqs,
.main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET,
+ .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
@@ -877,13 +885,60 @@ static struct omap_hwmod_irq_info am33xx_ecap1_irqs[] = {
static struct omap_hwmod am33xx_ecap1_hwmod = {
.name = "ecap1",
- .class = &am33xx_epwmss_hwmod_class,
+ .class = &am33xx_ecap_hwmod_class,
.clkdm_name = "l4ls_clkdm",
.mpu_irqs = am33xx_ecap1_irqs,
.main_clk = "l4ls_gclk",
+};
+
+/* eqep1 */
+static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = {
+ { .irq = 88 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod am33xx_eqep1_hwmod = {
+ .name = "eqep1",
+ .class = &am33xx_eqep_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_eqep1_irqs,
+ .main_clk = "l4ls_gclk",
+};
+
+/* ehrpwm1 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = {
+ { .name = "int", .irq = 87 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 59 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm1_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm1_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
+ .name = "ehrpwm1",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm1_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm1_opt_clks),
+};
+
+/* epwmss2 */
+static struct omap_hwmod am33xx_epwmss2_hwmod = {
+ .name = "epwmss2",
+ .class = &am33xx_epwmss_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .main_clk = "l4ls_gclk",
.prcm = {
.omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET,
+ .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
.modulemode = MODULEMODE_SWCTRL,
},
},
@@ -897,16 +952,49 @@ static struct omap_hwmod_irq_info am33xx_ecap2_irqs[] = {
static struct omap_hwmod am33xx_ecap2_hwmod = {
.name = "ecap2",
+ .class = &am33xx_ecap_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
.mpu_irqs = am33xx_ecap2_irqs,
- .class = &am33xx_epwmss_hwmod_class,
+ .main_clk = "l4ls_gclk",
+};
+
+/* eqep2 */
+static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = {
+ { .irq = 89 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+static struct omap_hwmod am33xx_eqep2_hwmod = {
+ .name = "eqep2",
+ .class = &am33xx_eqep_hwmod_class,
.clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_eqep2_irqs,
.main_clk = "l4ls_gclk",
- .prcm = {
- .omap4 = {
- .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET,
- .modulemode = MODULEMODE_SWCTRL,
- },
- },
+};
+
+/* ehrpwm2 */
+static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = {
+ { .name = "int", .irq = 39 + OMAP_INTC_START, },
+ { .name = "tzint", .irq = 60 + OMAP_INTC_START, },
+ { .irq = -1 },
+};
+
+/*
+ * Optional clock entry is provided to support additional clock
+ * gating for EHRPWM module from control module.
+ */
+static struct omap_hwmod_opt_clk ehrpwm2_opt_clks[] = {
+ { .role = "tbclk", .clk = "ehrpwm2_tbclk" },
+};
+
+static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
+ .name = "ehrpwm2",
+ .class = &am33xx_ehrpwm_hwmod_class,
+ .clkdm_name = "l4ls_clkdm",
+ .mpu_irqs = am33xx_ehrpwm2_irqs,
+ .main_clk = "l4ls_gclk",
+ .opt_clks = ehrpwm2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(ehrpwm2_opt_clks),
};
/*
@@ -2518,162 +2606,210 @@ static struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = {
{
.pa_start = 0x48300000,
.pa_end = 0x48300000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
- {
- .pa_start = 0x48300200,
- .pa_end = 0x48300200 + SZ_256 - 1,
- .flags = ADDR_TYPE_RT
- },
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm0 = {
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
.master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm0_hwmod,
+ .slave = &am33xx_epwmss0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm0_addr_space,
+ .addr = am33xx_epwmss0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = {
{
- .pa_start = 0x48302000,
- .pa_end = 0x48302000 + SZ_16 - 1,
+ .pa_start = 0x48300100,
+ .pa_end = 0x48300100 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ecap0_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_ecap0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = {
{
- .pa_start = 0x48302200,
- .pa_end = 0x48302200 + SZ_256 - 1,
+ .pa_start = 0x48300180,
+ .pa_end = 0x48300180 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm1 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm1_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_eqep0_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm1_addr_space,
+ .addr = am33xx_eqep0_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = {
{
- .pa_start = 0x48304000,
- .pa_end = 0x48304000 + SZ_16 - 1,
+ .pa_start = 0x48300200,
+ .pa_end = 0x48300200 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
+ .master = &am33xx_epwmss0_hwmod,
+ .slave = &am33xx_ehrpwm0_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_ehrpwm0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = {
{
- .pa_start = 0x48304200,
- .pa_end = 0x48304200 + SZ_256 - 1,
+ .pa_start = 0x48302000,
+ .pa_end = 0x48302000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm2 = {
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
.master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ehrpwm2_hwmod,
+ .slave = &am33xx_epwmss1_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ehrpwm2_addr_space,
+ .addr = am33xx_epwmss1_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = {
- {
- .pa_start = 0x48300000,
- .pa_end = 0x48300000 + SZ_16 - 1,
- .flags = ADDR_TYPE_RT
- },
+static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = {
{
- .pa_start = 0x48300100,
- .pa_end = 0x48300100 + SZ_256 - 1,
+ .pa_start = 0x48302100,
+ .pa_end = 0x48302100 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap0 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ecap0_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_ecap1_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ecap0_addr_space,
+ .addr = am33xx_ecap1_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = {
{
- .pa_start = 0x48302000,
- .pa_end = 0x48302000 + SZ_16 - 1,
+ .pa_start = 0x48302180,
+ .pa_end = 0x48302180 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_eqep1_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_eqep1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = {
{
- .pa_start = 0x48302100,
- .pa_end = 0x48302100 + SZ_256 - 1,
+ .pa_start = 0x48302200,
+ .pa_end = 0x48302200 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap1 = {
- .master = &am33xx_l4_ls_hwmod,
- .slave = &am33xx_ecap1_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
+ .master = &am33xx_epwmss1_hwmod,
+ .slave = &am33xx_ehrpwm1_hwmod,
.clk = "l4ls_gclk",
- .addr = am33xx_ecap1_addr_space,
+ .addr = am33xx_ehrpwm1_addr_space,
.user = OCP_USER_MPU,
};
-/*
- * Splitting the resources to handle access of PWMSS config space
- * and module specific part independently
- */
-static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = {
+static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = {
{
.pa_start = 0x48304000,
.pa_end = 0x48304000 + SZ_16 - 1,
.flags = ADDR_TYPE_RT
},
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am33xx_epwmss2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_epwmss2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = {
{
.pa_start = 0x48304100,
- .pa_end = 0x48304100 + SZ_256 - 1,
+ .pa_end = 0x48304100 + SZ_128 - 1,
.flags = ADDR_TYPE_RT
},
{ }
};
-static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap2 = {
- .master = &am33xx_l4_ls_hwmod,
+static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
+ .master = &am33xx_epwmss2_hwmod,
.slave = &am33xx_ecap2_hwmod,
.clk = "l4ls_gclk",
.addr = am33xx_ecap2_addr_space,
.user = OCP_USER_MPU,
};
+static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = {
+ {
+ .pa_start = 0x48304180,
+ .pa_end = 0x48304180 + SZ_128 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_eqep2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_eqep2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = {
+ {
+ .pa_start = 0x48304200,
+ .pa_end = 0x48304200 + SZ_128 - 1,
+ .flags = ADDR_TYPE_RT
+ },
+ { }
+};
+
+static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
+ .master = &am33xx_epwmss2_hwmod,
+ .slave = &am33xx_ehrpwm2_hwmod,
+ .clk = "l4ls_gclk",
+ .addr = am33xx_ehrpwm2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
/* l3s cfg -> gpmc */
static struct omap_hwmod_addr_space am33xx_gpmc_addr_space[] = {
{
@@ -3356,12 +3492,18 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l4_ls__uart6,
&am33xx_l4_ls__spinlock,
&am33xx_l4_ls__elm,
- &am33xx_l4_ls__ehrpwm0,
- &am33xx_l4_ls__ehrpwm1,
- &am33xx_l4_ls__ehrpwm2,
- &am33xx_l4_ls__ecap0,
- &am33xx_l4_ls__ecap1,
- &am33xx_l4_ls__ecap2,
+ &am33xx_l4_ls__epwmss0,
+ &am33xx_epwmss0__ecap0,
+ &am33xx_epwmss0__eqep0,
+ &am33xx_epwmss0__ehrpwm0,
+ &am33xx_l4_ls__epwmss1,
+ &am33xx_epwmss1__ecap1,
+ &am33xx_epwmss1__eqep1,
+ &am33xx_epwmss1__ehrpwm1,
+ &am33xx_l4_ls__epwmss2,
+ &am33xx_epwmss2__ecap2,
+ &am33xx_epwmss2__eqep2,
+ &am33xx_epwmss2__ehrpwm2,
&am33xx_l3_s__gpmc,
&am33xx_l3_main__lcdc,
&am33xx_l4_ls__mcspi0,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/8] pwm: pwm-tiecap: Add device-tree binding support for APWM driver
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
Add support for device-tree binding for ECAP APWM driver.
Also size of #pwm-cells set to 3 to support PWM channel number, PWM
period & polarity configuration from device tree.
Also enable clock gating in PWM subsystem common config space.
Also when here set .owner member in platform_driver structure to
THIS_MODULE.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
Second version
- Combined with HWMOD changes & DT bindings.
- Remove the custom of_xlate support.
:000000 100644 0000000... fe24cac... A Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
:100644 100644 d6d4cf0... 7ea5bea2.. M drivers/pwm/pwm-tiecap.c
.../devicetree/bindings/pwm/pwm-tiecap.txt | 22 ++++++++++++
drivers/pwm/pwm-tiecap.c | 36 +++++++++++++++++++-
2 files changed, 57 insertions(+), 1 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
new file mode 100644
index 0000000..fe24cac
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
@@ -0,0 +1,22 @@
+TI SOC ECAP based APWM controller
+
+Required properties:
+- compatible: Must be "ti,am33xx-ecap"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+ First cell specifies the per-chip index of the PWM to use, the second
+ cell is the period cycle in nanoseconds and bit 0 in the third cell is
+ used to encode the polarity of PWM output.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the ECAP:
+ "ecap<x>", <x> being the 0-based instance number from the HW spec
+
+Example:
+
+ecap0: ecap at 0 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ ti,hwmods = "ecap0";
+};
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index d6d4cf0..7ea5bea 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -25,6 +25,10 @@
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "tipwmss.h"
/* ECAP registers and bits definitions */
#define CAP1 0x08
@@ -37,6 +41,10 @@
#define ECCTL2_SYNC_SEL_DISA (BIT(7) | BIT(6))
#define ECCTL2_TSCTR_FREERUN BIT(4)
+#define ECAPCLK_EN_SHIFT 0
+
+#define PWM_CELL_SIZE 3
+
struct ecap_pwm_chip {
struct pwm_chip chip;
unsigned int clk_rate;
@@ -184,12 +192,27 @@ static const struct pwm_ops ecap_pwm_ops = {
.owner = THIS_MODULE,
};
+#ifdef CONFIG_OF
+static const struct of_device_id ecap_of_match[] = {
+ {
+ .compatible = "ti,am33xx-ecap",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ecap_of_match);
+#endif
+
static int __devinit ecap_pwm_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
struct clk *clk;
struct ecap_pwm_chip *pc;
+ struct pinctrl *pinctrl;
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "failed to configure pins from driver\n");
pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
if (!pc) {
@@ -211,6 +234,7 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev;
pc->chip.ops = &ecap_pwm_ops;
+ pc->chip.of_pwm_n_cells = PWM_CELL_SIZE;
pc->chip.base = -1;
pc->chip.npwm = 1;
@@ -231,6 +255,10 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev)
}
pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ pwmss_submodule_state_change(pdev->dev.parent, ECAPCLK_EN_SHIFT, true);
+ pm_runtime_put_sync(&pdev->dev);
+
platform_set_drvdata(pdev, pc);
return 0;
}
@@ -239,6 +267,10 @@ static int __devexit ecap_pwm_remove(struct platform_device *pdev)
{
struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
+ pm_runtime_get_sync(&pdev->dev);
+ pwmss_submodule_state_change(pdev->dev.parent, ECAPCLK_EN_SHIFT, false);
+ pm_runtime_put_sync(&pdev->dev);
+
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
@@ -246,7 +278,9 @@ static int __devexit ecap_pwm_remove(struct platform_device *pdev)
static struct platform_driver ecap_pwm_driver = {
.driver = {
- .name = "ecap",
+ .name = "ecap",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ecap_of_match),
},
.probe = ecap_pwm_probe,
.remove = __devexit_p(ecap_pwm_remove),
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/8] pwm: pwm-tiehrpwm: Add device-tree binding support for EHRPWM driver
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
Add support for device-tree binding for EHRWPM driver.
Also size of #pwm-cells set to 3 to support PWM channel number, PWM
period & polarity configuration from device tree.
Also enable clock gating in PWM subsystem common config space.
Also when here set .owner member in platform_driver structure to
THIS_MODULE.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
---
Second version
- Combined with HWMOD changes & DT bindings.
- Remove the custom of_xlate support.
:000000 100644 0000000... aa2ed0a... A Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
:100644 100644 d3c1dff... 1e63652... M drivers/pwm/pwm-tiehrpwm.c
.../devicetree/bindings/pwm/pwm-tiehrpwm.txt | 25 +++++++++++++
drivers/pwm/pwm-tiehrpwm.c | 37 ++++++++++++++++++-
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
new file mode 100644
index 0000000..aa2ed0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt
@@ -0,0 +1,25 @@
+TI SOC EHRPWM based PWM controller
+
+Required properties:
+- compatible : Must be "ti,am33xx-ehrpwm"
+- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
+ First cell specifies the per-chip index of the PWM to use, the second
+ cell is the period cycle in nanoseconds and bit 0 in the third cell is
+ used to encode the polarity of PWM output.
+- reg: physical base address and size of the registers map.
+
+Optional properties:
+- ti,hwmods: Name of the hwmod associated to the EHRPWM:
+ "ehrpwm<x>", <x> being the 0-based instance number from the HW spec
+- tbclkgating: platforms require tbclk gating from control module
+ should populate
+
+Example:
+
+ehrpwm0: ehrpwm at 0 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x100>;
+ ti,hwmods = "ehrpwm0";
+ tbclkgating;
+};
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index d3c1dff..1e63652 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -25,6 +25,10 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "tipwmss.h"
/* EHRPWM registers and bits definitions */
@@ -107,6 +111,10 @@
#define AQCSFRC_CSFA_FRCHIGH BIT(1)
#define AQCSFRC_CSFA_DISSWFRC (BIT(1) | BIT(0))
+#define EPWMCLK_EN_SHIFT 8
+
+#define PWM_CELL_SIZE 3
+
#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */
struct ehrpwm_pwm_chip {
@@ -392,12 +400,27 @@ static const struct pwm_ops ehrpwm_pwm_ops = {
.owner = THIS_MODULE,
};
+#ifdef CONFIG_OF
+static const struct of_device_id ehrpwm_of_match[] = {
+ {
+ .compatible = "ti,am33xx-ehrpwm",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
+#endif
+
static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
struct clk *clk;
struct ehrpwm_pwm_chip *pc;
+ struct pinctrl *pinctrl;
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "failed to configure pins from driver\n");
pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
if (!pc) {
@@ -419,6 +442,7 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev;
pc->chip.ops = &ehrpwm_pwm_ops;
+ pc->chip.of_pwm_n_cells = PWM_CELL_SIZE;
pc->chip.base = -1;
pc->chip.npwm = NUM_PWM_CHANNEL;
@@ -437,8 +461,11 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
-
pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+ pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN_SHIFT, true);
+ pm_runtime_put_sync(&pdev->dev);
+
platform_set_drvdata(pdev, pc);
return 0;
}
@@ -447,6 +474,10 @@ static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
{
struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
+ pm_runtime_get_sync(&pdev->dev);
+ pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN_SHIFT, false);
+ pm_runtime_put_sync(&pdev->dev);
+
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
@@ -454,7 +485,9 @@ static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
static struct platform_driver ehrpwm_pwm_driver = {
.driver = {
- .name = "ehrpwm",
+ .name = "ehrpwm",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ehrpwm_of_match),
},
.probe = ehrpwm_pwm_probe,
.remove = __devexit_p(ehrpwm_pwm_remove),
--
1.7.0.4
^ permalink raw reply related
* [PATCH 6/8] pwm: pwm-tiehrpwm: Adding TBCLK gating support.
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
Some platforms (like AM33XX) requires clock gating from control module
explicitly. So adding optional TBCLK handling if DT node populated with
tbclkgating. This helps the driver can coexist for Davinci platforms.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
:100644 100644 1e63652... cf69da3... M drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-tiehrpwm.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index 1e63652..cf69da3 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -123,6 +123,7 @@ struct ehrpwm_pwm_chip {
void __iomem *mmio_base;
unsigned long period_cycles[NUM_PWM_CHANNEL];
enum pwm_polarity polarity[NUM_PWM_CHANNEL];
+ struct clk *tbclk;
};
static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -461,6 +462,20 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
+
+ /* Some platforms require explicit tbclk gating */
+ if (of_property_read_bool(pdev->dev.of_node, "tbclkgating")) {
+ pc->tbclk = clk_get(&pdev->dev, "tbclk");
+ if (IS_ERR(pc->tbclk)) {
+ dev_err(&pdev->dev, "Could not get EHRPWM TBCLK\n");
+ return PTR_ERR(pc->tbclk);
+ }
+ }
+
+ /* Enable tbclk & leave */
+ if (pc->tbclk)
+ clk_enable(pc->tbclk);
+
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN_SHIFT, true);
@@ -478,6 +493,8 @@ static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev)
pwmss_submodule_state_change(pdev->dev.parent, EPWMCLK_EN_SHIFT, false);
pm_runtime_put_sync(&pdev->dev);
+ if (pc->tbclk)
+ clk_disable(pc->tbclk);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return pwmchip_remove(&pc->chip);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 7/8] ARM: dts: AM33XX: Add PWMSS device tree nodes
From: Philip, Avinash @ 2012-11-05 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352106749-9437-1-git-send-email-avinashphilip@ti.com>
Add PWMSS device tree nodes in relation with ECAP & EHRPWM DT nodes to
AM33XX SoC family. Also populates device tree nodes for ECAP & EHRPWM by
adding necessary properties like pwm-cells, base reg & set disabled as
status.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
---
Second version
- Combined with HWMOD changes & DT bindings.
- Handling Parent<-> child relation ship for PWM subsystem
:100644 100644 bb31bff... cf5e049... M arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am33xx.dtsi | 90 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index bb31bff..cf5e049 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -210,5 +210,95 @@
interrupt-parent = <&intc>;
interrupts = <91>;
};
+
+ epwmss0: epwmss at 48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10
+ 0x48300100 0x80
+ 0x48300180 0x80
+ 0x48300200 0x80>;
+ ti,hwmods = "epwmss0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap0: ecap at 48300100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ ti,hwmods = "ecap0";
+ status = "disabled";
+ };
+
+ ehrpwm0: ehrpwm at 48300200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x80>;
+ ti,hwmods = "ehrpwm0";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
+
+ epwmss1: epwmss at 48302000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48302000 0x10
+ 0x48302100 0x80
+ 0x48302180 0x80
+ 0x48302200 0x80>;
+ ti,hwmods = "epwmss1";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap1: ecap at 48302100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48302100 0x80>;
+ ti,hwmods = "ecap1";
+ status = "disabled";
+ };
+
+ ehrpwm1: ehrpwm at 48302200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48302200 0x80>;
+ ti,hwmods = "ehrpwm1";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
+
+ epwmss2: epwmss at 48304000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48304000 0x10
+ 0x48304100 0x80
+ 0x48304180 0x80
+ 0x48304200 0x80>;
+ ti,hwmods = "epwmss2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+ ranges;
+
+ ecap2: ecap at 48304100 {
+ compatible = "ti,am33xx-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48304100 0x80>;
+ ti,hwmods = "ecap2";
+ status = "disabled";
+ };
+
+ ehrpwm2: ehrpwm at 48304200 {
+ compatible = "ti,am33xx-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48304200 0x80>;
+ ti,hwmods = "ehrpwm2";
+ status = "disabled";
+ tbclkgating;
+ };
+ };
};
};
--
1.7.0.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox