Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] clk: Make the generic clock API available by default
From: Russell King - ARM Linux @ 2012-10-22 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121022132711.GE4477@opensource.wolfsonmicro.com>

On Mon, Oct 22, 2012 at 02:27:11PM +0100, Mark Brown wrote:
> On Mon, Oct 22, 2012 at 02:05:57PM +0100, Russell King - ARM Linux wrote:
> > On Mon, Oct 22, 2012 at 02:02:50PM +0100, Mark Brown wrote:
> > > @@ -327,6 +328,7 @@ config ARCH_AT91
> > >  	select ARCH_REQUIRE_GPIOLIB
> > >  	select CLKDEV_LOOKUP
> > >  	select HAVE_CLK
> > > +	select HAVE_CUSTOM_CLK
> 
> > This is silly.  If you select "HAVE_CUSTOM_CLK" then isn't it true that
> > "HAVE_CLK" should also be selected?  If so, why not have "HAVE_CUSTOM_CLK"
> > do that selection and remove it from all these entries?
> 
> If we're worrying about that there's the larger point that the effect of
> this patch is to make HAVE_CLK meaningless as there will be no platform
> for which it's not true.  I was just leaving HAVE_CLK alone for now
> ready to circle around on it if we ever manage to get the enabling bit
> sorted.

Are you sure that all architectures are fine with having that permanently
enabled?  What about nommu architectures?

^ permalink raw reply

* Which kirkwood does your DT board use?
From: Jason Cooper @ 2012-10-22 13:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121020113800.GC21046@lunn.ch>

On Sat, Oct 20, 2012 at 01:38:00PM +0200, Andrew Lunn wrote:
> Hi Folks
> 
> All of you in the To: have contributed a DT based Kirkwood board port.
> Nearly all the DT files we have declare the CPU to be
> marvell,kirkwood-88f6281. For adding DT based pinctrl, to replace the
> mpp code, we need to know the exact kirkwood being used. It should be
> one of MV88F6180, MV88F6190, MV88F6192, MV88F6281 or MV88F6282.
> 
> You can see what your hardware has a boot time:
> 
> Kirkwood: MV88F6282-Rev-A0, TCLK=200000000.
> 
> Please could you check your hardware and let me know what the correct
> CPU is. I can then fix the .dts files and prepare a first attempt at
> converting boards to pinctrl.

Dreamplug:

Kirkwood: MV88F6281-A1, TCLK=200000000.

hth,

Jason.

^ permalink raw reply

* [PATCH 2/2] ASoC: Ux500: Control apb clock
From: Mark Brown @ 2012-10-22 13:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350909125-20189-2-git-send-email-ulf.hansson@stericsson.com>

On Mon, Oct 22, 2012 at 02:32:05PM +0200, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
> 
> When switching to common clock driver for ux500 this clock needs to
> be handled as well. Before this clock was internally managed by the
> clock driver itself.

Applied but why isn't this a deficiency in the common clock
implementation for the platform?
-------------- 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/20121022/fe94e73f/attachment-0001.sig>

^ permalink raw reply

* [PATCH 0/8] I2C patches for v3.8 merge window
From: Felipe Balbi @ 2012-10-22 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350899218-13624-1-git-send-email-balbi@ti.com>

Hi,

On Mon, Oct 22, 2012 at 12:46:50PM +0300, Felipe Balbi wrote:
> Hi guys,
> 
> 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.
> 
> [1] git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git i2c-transferred-bytes-on-NACK

forgot to mention, with [1] I could veridy suspend to ram with boards
mentioned above.

[1] http://marc.info/?l=linux-arm-kernel&m=135090724817604&w=2

> Felipe Balbi (7):
>   i2c: omap: no need to access platform_device
>   i2c: omap: reorder exit path of omap_i2c_xfer_msg()
>   i2c: omap: fix error checking
>   i2c: omap: also complete() when stat becomes zero
>   i2c: omap: introduce and use OMAP_I2C_IP_VERSION_3
>   i2c: omap: wait for transfer completion before sending STP bit
>   i2c: omap: implement handling for 'transferred' bytes
> 
> Shubhrajyoti D (1):
>   i2c: add 'transferred' field to struct i2c_msg
> 
>  arch/arm/mach-omap2/i2c.c                  |   3 +-
>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   2 +-
>  drivers/i2c/busses/i2c-omap.c              | 156 ++++++++++++++++-------------
>  include/linux/i2c-omap.h                   |   1 +
>  include/uapi/linux/i2c.h                   |   1 +
>  5 files changed, 89 insertions(+), 74 deletions(-)
> 
> -- 
> 1.8.0.rc0
> 

-- 
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/20121022/c344c2db/attachment.sig>

^ permalink raw reply

* [PATCH 1/2] ASoC: Ux500: Fixup use of clocks
From: Mark Brown @ 2012-10-22 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350909125-20189-1-git-send-email-ulf.hansson@stericsson.com>

On Mon, Oct 22, 2012 at 02:32:04PM +0200, Ulf Hansson wrote:
> From: Ulf Hansson <ulf.hansson@linaro.org>
> 
> Make sure clocks are being prepared and unprepared as well
> as enabled and disabled.

Applied, thanks.
-------------- 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/20121022/e8e52d11/attachment.sig>

^ permalink raw reply

* [PATCH] clk: Make the generic clock API available by default
From: Mark Brown @ 2012-10-22 13:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121022130556.GM21164@n2100.arm.linux.org.uk>

On Mon, Oct 22, 2012 at 02:05:57PM +0100, Russell King - ARM Linux wrote:
> On Mon, Oct 22, 2012 at 02:02:50PM +0100, Mark Brown wrote:
> > @@ -327,6 +328,7 @@ config ARCH_AT91
> >  	select ARCH_REQUIRE_GPIOLIB
> >  	select CLKDEV_LOOKUP
> >  	select HAVE_CLK
> > +	select HAVE_CUSTOM_CLK

> This is silly.  If you select "HAVE_CUSTOM_CLK" then isn't it true that
> "HAVE_CLK" should also be selected?  If so, why not have "HAVE_CUSTOM_CLK"
> do that selection and remove it from all these entries?

If we're worrying about that there's the larger point that the effect of
this patch is to make HAVE_CLK meaningless as there will be no platform
for which it's not true.  I was just leaving HAVE_CLK alone for now
ready to circle around on it if we ever manage to get the enabling bit
sorted.

^ permalink raw reply

* [RFC/PATCH] mmc: omap_hsmmc: introduce omap_hsmmc_prepare/complete
From: Felipe Balbi @ 2012-10-22 13:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350910768-8522-1-git-send-email-balbi@ti.com>

On Mon, Oct 22, 2012 at 03:59:28PM +0300, Felipe Balbi wrote:
> prepare() is supposed to prevent new children from
> being registered. On the MMC subsystem, children
> (new cards) registration starts with the card
> detect IRQ.
> 
> Move card detect IRQ disabling to prepare() so that
> no new cards will be registered while we're trying
> to suspend.
> 
> Likewise, move card detect IRQ enabling to complete()
> so we only try to register new children after our MMC
> IP is back up.
> 
> Signed-off-by: Felipe Balbi <balbi@ti.com>
> ---
> 
> Venkat, do you think the patch below makes sense ?

btw, just checked suspend to ram with beagle and panda. We still have
our filesystem after waking up.

ps: you will [1] to test it:

[1] http://marc.info/?l=linux-arm-kernel&m=135090724817604&w=2

> diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
> index 54bfd0c..4c8b41e 100644
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -2022,6 +2022,26 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
>  }
>  
>  #ifdef CONFIG_PM
> +static int omap_hsmmc_prepare(struct device *dev)
> +{
> +	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
> +
> +	if (host->pdata->suspend)
> +		return host->pdata->suspend(dev, host->slot_id);
> +
> +	return 0;
> +}
> +
> +static int omap_hsmmc_complete(struct device *dev)
> +{
> +	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
> +
> +	if (host->pdata->resume)
> +		return host->pdata->resume(dev, host->slot_id);
> +
> +	return 0;
> +}
> +
>  static int omap_hsmmc_suspend(struct device *dev)
>  {
>  	int ret = 0;
> @@ -2035,23 +2055,10 @@ static int omap_hsmmc_suspend(struct device *dev)
>  
>  	pm_runtime_get_sync(host->dev);
>  	host->suspended = 1;
> -	if (host->pdata->suspend) {
> -		ret = host->pdata->suspend(dev, host->slot_id);
> -		if (ret) {
> -			dev_dbg(dev, "Unable to handle MMC board"
> -					" level suspend\n");
> -			host->suspended = 0;
> -			return ret;
> -		}
> -	}
>  	ret = mmc_suspend_host(host->mmc);
>  
>  	if (ret) {
>  		host->suspended = 0;
> -		if (host->pdata->resume) {
> -			if (host->pdata->resume(dev, host->slot_id))
> -				dev_dbg(dev, "Unmask interrupt failed\n");
> -		}
>  		goto err;
>  	}
>  
> @@ -2088,12 +2095,6 @@ static int omap_hsmmc_resume(struct device *dev)
>  	if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
>  		omap_hsmmc_conf_bus_power(host);
>  
> -	if (host->pdata->resume) {
> -		ret = host->pdata->resume(dev, host->slot_id);
> -		if (ret)
> -			dev_dbg(dev, "Unmask interrupt failed\n");
> -	}
> -
>  	omap_hsmmc_protect_card(host);
>  
>  	/* Notify the core to resume the host */
> @@ -2109,8 +2110,10 @@ static int omap_hsmmc_resume(struct device *dev)
>  }
>  
>  #else
> +#define omap_hsmmc_prepare	NULL
> +#define omap_hsmmc_complete	NULL
>  #define omap_hsmmc_suspend	NULL
> -#define omap_hsmmc_resume		NULL
> +#define omap_hsmmc_resume	NULL
>  #endif
>  
>  static int omap_hsmmc_runtime_suspend(struct device *dev)
> @@ -2138,6 +2141,8 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
>  static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
>  	.suspend	= omap_hsmmc_suspend,
>  	.resume		= omap_hsmmc_resume,
> +	.prepare	= omap_hsmmc_prepare,
> +	.complete	= omap_hsmmc_complete,
>  	.runtime_suspend = omap_hsmmc_runtime_suspend,
>  	.runtime_resume = omap_hsmmc_runtime_resume,
>  };
> -- 
> 1.8.0.rc0
> 

-- 
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/20121022/88dfd0e5/attachment.sig>

^ permalink raw reply

* [PATCH] MMCI: fetch pinctrl handle and set default state
From: Ulf Hansson @ 2012-10-22 13:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350892326-5125-1-git-send-email-linus.walleij@stericsson.com>

Acked-by: Ulf Hansson <ulf.hansson@linaro.org>


On 22 October 2012 09:52, Linus Walleij <linus.walleij@stericsson.com> wrote:
> From: Linus Walleij <linus.walleij@linaro.org>
>
> This fetches the pinctrl resource for the MMCI driver, and if
> a "default" state is found, it is activated.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/mmc/host/mmci.c | 18 ++++++++++++++++++
>  drivers/mmc/host/mmci.h |  4 ++++
>  2 files changed, 22 insertions(+)
>
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index edc3e9b..269566d 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -33,6 +33,7 @@
>  #include <linux/amba/mmci.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/types.h>
> +#include <linux/pinctrl/consumer.h>
>
>  #include <asm/div64.h>
>  #include <asm/io.h>
> @@ -1360,6 +1361,23 @@ static int __devinit mmci_probe(struct amba_device *dev,
>                 mmc->f_max = min(host->mclk, fmax);
>         dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
>
> +       host->pinctrl = devm_pinctrl_get(&dev->dev);
> +       if (IS_ERR(host->pinctrl)) {
> +               ret = PTR_ERR(host->pinctrl);
> +               goto clk_disable;
> +       }
> +
> +       host->pins_default = pinctrl_lookup_state(host->pinctrl,
> +                       PINCTRL_STATE_DEFAULT);
> +
> +       /* enable pins to be muxed in and configured */
> +       if (!IS_ERR(host->pins_default)) {
> +               ret = pinctrl_select_state(host->pinctrl, host->pins_default);
> +               if (ret)
> +                       dev_err(&dev->dev, "could not set default pins\n");
> +       } else
> +               dev_err(&dev->dev, "could not get default pinstate\n");
> +
>  #ifdef CONFIG_REGULATOR
>         /* If we're using the regulator framework, try to fetch a regulator */
>         host->vcc = regulator_get(&dev->dev, "vmmc");
> diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
> index d437ccf..d34d8c0 100644
> --- a/drivers/mmc/host/mmci.h
> +++ b/drivers/mmc/host/mmci.h
> @@ -195,6 +195,10 @@ struct mmci_host {
>         unsigned int            size;
>         struct regulator        *vcc;
>
> +       /* pinctrl handles */
> +       struct pinctrl          *pinctrl;
> +       struct pinctrl_state    *pins_default;
> +
>  #ifdef CONFIG_DMA_ENGINE
>         /* DMA stuff */
>         struct dma_chan         *dma_current;
> --
> 1.7.11.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4] ARM: SMP_TWD: make setup()/stop() reentrant
From: Santosh Shilimkar @ 2012-10-22 13:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350911721-3184-1-git-send-email-linus.walleij@stericsson.com>

On Monday 22 October 2012 06:45 PM, Linus Walleij wrote:
> From: Linus Walleij <linus.walleij@linaro.org>
>
> It has been brought to my knowledge that the .setup()/.stop()
> function pair in the SMP TWD is going to be called from atomic
> contexts for CPUs coming and going, and then the
> clk_prepare()/clk_unprepare() calls cannot be called
> on subsequent .setup()/.stop() iterations. This is however
> just the tip of an iceberg as the function pair is not
> designed to be reentrant at all.
>
> This change makes the SMP_TWD clock .setup()/.stop() pair reentrant
> by splitting the .setup() function in three parts:
>
> - One COMMON part that is executed the first time the first CPU
>    in the TWD cluster is initialized. This will fetch the TWD
>    clk for the cluster and prepare+enable it. If no clk is
>    available it will calibrate the rate instead.
>
> - One part that is executed the FIRST TIME a certain CPU is
>    brought on-line. This initializes and sets up the clock event
>    for a certain CPU.
>
> - One part that is executed on every subsequent .setup() call.
>    This will re-initialize the clock event. This is augmented
>    to call the clk_enable()/clk_disable() pair properly.
>
> Cc: Shawn Guo <shawn.guo@linaro.org>
> Reported-by: Peter Chen <peter.chen@freescale.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v3->v4:
> - Skip clk_enable()/clk_disable() in subsequent call after common
>    initialization - there is no way we can turn off the clock that
>    is running us anyway.
> - Move common_setup_called variable assignment into the if-clause
> ---

Looks good now. Thanks for the update.

Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply

* [PATCH 2/2] ASoC: Ux500: Control apb clock
From: Linus Walleij @ 2012-10-22 13:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350909125-20189-2-git-send-email-ulf.hansson@stericsson.com>

On Mon, Oct 22, 2012 at 2:32 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote:

> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> When switching to common clock driver for ux500 this clock needs to
> be handled as well. Before this clock was internally managed by the
> clock driver itself.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Looks correct, Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 1/2] ASoC: Ux500: Fixup use of clocks
From: Linus Walleij @ 2012-10-22 13:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350909125-20189-1-git-send-email-ulf.hansson@stericsson.com>

On Mon, Oct 22, 2012 at 2:32 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote:

> From: Ulf Hansson <ulf.hansson@linaro.org>
>
> Make sure clocks are being prepared and unprepared as well
> as enabled and disabled.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Thanks,
Linus Walleij

^ permalink raw reply

* [PATCH v2 5/8] i2c: omap: in case of VERSION_2 read IRQSTATUS_RAW but write to IRQSTATUS
From: Felipe Balbi @ 2012-10-22 13:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350899218-13624-6-git-send-email-balbi@ti.com>

on OMAP4+ we want to read IRQSTATUS_RAW register,
instead of IRQSTATUS. The reason being that IRQSTATUS
will only contain the bits which were enabled on
IRQENABLE_SET and that will break when we need to
poll for a certain bit which wasn't enabled as an
IRQ source.

One such case is after we finish converting to
deferred stop bit, we will have to poll for ARDY
bit before returning control for the client driver
in order to prevent us from trying to start a
transfer on a bus which is already busy.

Note, however, that omap-i2c.c needs a big rework
on register definition and register access. Such
work will be done in a separate series of patches.

Cc: Benoit Cousson <b-cousson@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6219522..ba4e910 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -271,8 +271,18 @@ static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
 
 static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 {
-	return __raw_readw(i2c_dev->base +
+	/* if we are OMAP_I2C_IP_VERSION_2, we need to read from
+	 * IRQSTATUS_RAW, but write to IRQSTATUS
+	 */
+	if ((i2c_dev->dtrev == OMAP_I2C_IP_VERSION_2) &&
+			(reg == OMAP_I2C_STAT_REG)) {
+		return __raw_readw(i2c_dev->base +
+				((i2c_dev->regs[reg] - 0x04)
+				 << i2c_dev->reg_shift));
+	} else {
+		return __raw_readw(i2c_dev->base +
 				(i2c_dev->regs[reg] << i2c_dev->reg_shift));
+	}
 }
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
-- 
1.8.0.rc0

^ permalink raw reply related

* [PATCH v4] ARM: SMP_TWD: make setup()/stop() reentrant
From: Linus Walleij @ 2012-10-22 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

From: Linus Walleij <linus.walleij@linaro.org>

It has been brought to my knowledge that the .setup()/.stop()
function pair in the SMP TWD is going to be called from atomic
contexts for CPUs coming and going, and then the
clk_prepare()/clk_unprepare() calls cannot be called
on subsequent .setup()/.stop() iterations. This is however
just the tip of an iceberg as the function pair is not
designed to be reentrant at all.

This change makes the SMP_TWD clock .setup()/.stop() pair reentrant
by splitting the .setup() function in three parts:

- One COMMON part that is executed the first time the first CPU
  in the TWD cluster is initialized. This will fetch the TWD
  clk for the cluster and prepare+enable it. If no clk is
  available it will calibrate the rate instead.

- One part that is executed the FIRST TIME a certain CPU is
  brought on-line. This initializes and sets up the clock event
  for a certain CPU.

- One part that is executed on every subsequent .setup() call.
  This will re-initialize the clock event. This is augmented
  to call the clk_enable()/clk_disable() pair properly.

Cc: Shawn Guo <shawn.guo@linaro.org>
Reported-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Skip clk_enable()/clk_disable() in subsequent call after common
  initialization - there is no way we can turn off the clock that
  is running us anyway.
- Move common_setup_called variable assignment into the if-clause
---
 arch/arm/kernel/smp_twd.c | 42 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index b92d524..ff07879 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -31,6 +31,8 @@ static void __iomem *twd_base;
 
 static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
+static bool common_setup_called;
+static DEFINE_PER_CPU(bool, percpu_setup_called);
 
 static struct clock_event_device __percpu **twd_evt;
 static int twd_ppi;
@@ -264,15 +266,45 @@ static struct clk *twd_get_clock(void)
 static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
 	struct clock_event_device **this_cpu_clk;
+	int cpu = smp_processor_id();
 
-	if (!twd_clk)
+	/*
+	 * If the basic setup for this CPU has been done before don't
+	 * bother with the below.
+	 */
+	if (per_cpu(percpu_setup_called, cpu)) {
+		__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+		clockevents_register_device(*__this_cpu_ptr(twd_evt));
+		enable_percpu_irq(clk->irq, 0);
+		return 0;
+	}
+	per_cpu(percpu_setup_called, cpu) = true;
+
+	/*
+	 * This stuff only need to be done once for the entire TWD cluster
+	 * during the runtime of the system.
+	 */
+	if (!common_setup_called) {
 		twd_clk = twd_get_clock();
 
-	if (!IS_ERR_OR_NULL(twd_clk))
-		twd_timer_rate = clk_get_rate(twd_clk);
-	else
-		twd_calibrate_rate();
+		/*
+		 * We use IS_ERR_OR_NULL() here, because if the clock stubs
+		 * are active we will get a valid clk reference which is
+		 * however NULL and will return the rate 0. In that case we
+		 * need to calibrate the rate instead.
+		 */
+		if (!IS_ERR_OR_NULL(twd_clk))
+			twd_timer_rate = clk_get_rate(twd_clk);
+		else
+			twd_calibrate_rate();
+
+		common_setup_called = true;
+	}
 
+	/*
+	 * The following is done once per CPU the first time .setup() is
+	 * called.
+	 */
 	__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
 
 	clk->name = "local_timer";
-- 
1.7.11.3

^ permalink raw reply related

* [PATCHv2] arm: dts: omap4-sdp: pinmux configuration for keypad
From: Sourav Poddar @ 2012-10-22 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, omap4 keypad mux settings are done in the board file.
Populate the mux settings in the dts file for the keypad to
work via dt.

Tested on omap4430 sdp with 3.7-rc1.

Cc: Felipe Balbi <balbi@ti.com>
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
---
v1->v2
change the hex letter to lower case.
 arch/arm/boot/dts/omap4-sdp.dts |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 5b7e04f..27d16a8 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -194,6 +194,27 @@
 			0xbc 0x100	/* abe_mcbsp2_fsx.abe_mcbsp2_fsx INPUT | MODE0 */
 		>;
 	};
+
+	keypad_pins: pinmux_keypad_pins {
+		pinctrl-single,pins = <
+			0x24 0x4119   /* gpmc_a18.kpd_row6 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x26 0x4119   /* gpmc_a19.kpd_row6 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x2c 0x4001   /* gpmc_a22.kpd_col6 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x2e 0x4001   /* gpmc_a23.kpd_col7 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x13c 0x4001  /* kpd_col0.kpd_col0 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x13e 0x4001  /* kpd_col1.kpd_col1 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x140 0x4001  /* kpd_col2.kpd_col2 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x142 0x10f   /* kpd_col3.kpd_col3 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x144 0x4001  /* kpd_col4.kpd_col4 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x146 0x4001  /* kpd_col5.kpd_col5 OMAP_WAKEUP_EN | OMAP_MUX_MODE1 */
+			0x148 0xc119  /* kpd_row0.kpd_row0 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x14a 0x4119  /* kpd_row1.kpd_row1 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x14c 0x4119  /* kpd_row2.kpd_row2 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x14e 0x4119  /* kpd_row3.kpd_row3 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x150 0x4119  /* kpd_row4.kpd_row4 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+			0x152 0x4119  /* kpd_row5.kpd_row5 OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN | OMAP_MUX_MODE1 | OMAP_INPUT_EN */
+		>;
+	};
 };
 
 &i2c1 {
@@ -406,3 +427,8 @@
 &mcbsp3 {
 	status = "disabled";
 };
+
+&keypad {
+        pinctrl-names = "default";
+        pinctrl-0 = <&keypad_pins>;
+};
-- 
1.7.1

^ permalink raw reply related

* [PATCHv2] Input: omap4-keypad: Add pinctrl support
From: Sourav Poddar @ 2012-10-22 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

Adapt keypad to use pinctrl framework.

Tested on omap4430 sdp with 3.7-rc1 kernel.

Cc: Felipe Balbi <balbi@ti.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
---
v1->v2
- Added "PROBE_DEFER" check 
 drivers/input/keyboard/omap4-keypad.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
index c05f98c..502b832 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -31,6 +31,7 @@
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/platform_data/omap4-keypad.h>
 
@@ -76,6 +77,7 @@ enum {
 
 struct omap4_keypad {
 	struct input_dev *input;
+	struct pinctrl	*pins;
 
 	void __iomem *base;
 	unsigned int irq;
@@ -298,6 +300,15 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev)
 		goto err_release_mem;
 	}
 
+	keypad_data->pins = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(keypad_data->pins)) {
+		if (PTR_ERR(keypad_data->pins) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_warn(&pdev->dev, "did not get pins for keypad error: %li\n",
+					PTR_ERR(keypad_data->pins));
+		keypad_data->pins = NULL;
+	}
 
 	/*
 	 * Enable clocks for the keypad module so that we can read
-- 
1.7.1

^ permalink raw reply related

* [PATCH 5/8] i2c: omap: introduce and use OMAP_I2C_IP_VERSION_3
From: Felipe Balbi @ 2012-10-22 13:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50854490.4060306@ti.com>

Hi,

On Mon, Oct 22, 2012 at 03:05:20PM +0200, Benoit Cousson wrote:
> On 10/22/2012 02:28 PM, Felipe Balbi wrote:
> > Hi,
> > 
> > On Mon, Oct 22, 2012 at 02:27:20PM +0200, Benoit Cousson wrote:
> >> Hi Felipe,
> >>
> >> On 10/22/2012 11:46 AM, Felipe Balbi wrote:
> >>> on OMAP4+ we want to read IRQSTATUS_RAW register,
> >>> instead of IRQSTATUS. The reason being that IRQSTATUS
> >>> will only contain the bits which were enabled on
> >>> IRQENABLE_SET and that will break when we need to
> >>> poll for a certain bit which wasn't enabled as an
> >>> IRQ source.
> >>>
> >>> One such case is after we finish converting to
> >>> deferred stop bit, we will have to poll for ARDY
> >>> bit before returning control for the client driver
> >>> in order to prevent us from trying to start a
> >>> transfer on a bus which is already busy.
> >>>
> >>> Note, however, that omap-i2c.c needs a big rework
> >>> on register definition and register access. Such
> >>> work will be done in a separate series of patches.
> >>
> >> Do you need OMAP_I2C_IP_VERSION_3 for OMAP4?
> >>
> >> OMAP_I2C_IP_VERSION_2 was already introduced to detect OMAP3630 vs
> >> omap4430 because they were sharing the same IP version..
> >>
> >> /* 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
> >>
> >> So in theory you should not need an extra version.
> > 
> > are you sure that's how they're used ? Looking at the code where we
> > choose reg_map_ip_v1 and reg_map_ip_v2:
> > 
> > 1120         if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
> > 1121                 dev->regs = (u8 *)reg_map_ip_v2;
> > 1122         else
> > 1123                 dev->regs = (u8 *)reg_map_ip_v1;
> > 
> > And looking at reg_map_ip_v1:
> > 
> >  218 static const u8 reg_map_ip_v1[] = {
> >  219         [OMAP_I2C_REV_REG] = 0x00,
> >  220         [OMAP_I2C_IE_REG] = 0x01,
> >  221         [OMAP_I2C_STAT_REG] = 0x02,
> >  222         [OMAP_I2C_IV_REG] = 0x03,
> >  223         [OMAP_I2C_WE_REG] = 0x03,
> >  224         [OMAP_I2C_SYSS_REG] = 0x04,
> >  225         [OMAP_I2C_BUF_REG] = 0x05,
> >  226         [OMAP_I2C_CNT_REG] = 0x06,
> >  227         [OMAP_I2C_DATA_REG] = 0x07,
> >  228         [OMAP_I2C_SYSC_REG] = 0x08,
> >  229         [OMAP_I2C_CON_REG] = 0x09,
> >  230         [OMAP_I2C_OA_REG] = 0x0a,
> >  231         [OMAP_I2C_SA_REG] = 0x0b,
> >  232         [OMAP_I2C_PSC_REG] = 0x0c,
> >  233         [OMAP_I2C_SCLL_REG] = 0x0d,
> >  234         [OMAP_I2C_SCLH_REG] = 0x0e,
> >  235         [OMAP_I2C_SYSTEST_REG] = 0x0f,
> >  236         [OMAP_I2C_BUFSTAT_REG] = 0x10,
> >  237 };
> > 
> > that's really not the register map on OMAP3. That only looks valid for
> > OMAP1.
> 
> No that should be valid as well for OMAP2&3 thanks to the
> OMAP_I2C_FLAG_BUS_SHIFT_2.

aha.. I see. What a hack!

> It was introduced during DT adaptation:
> 
> #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 |
>                  OMAP_I2C_FLAG_BUS_SHIFT_2,
> };
> 
> static struct omap_i2c_bus_platform_data omap4_pdata = {
>         .rev = OMAP_I2C_IP_VERSION_2,
> };
> 
> static const struct of_device_id omap_i2c_of_match[] = {
>         {
>                 .compatible = "ti,omap4-i2c",
>                 .data = &omap4_pdata,
>         },
>         {
>                 .compatible = "ti,omap3-i2c",
>                 .data = &omap3_pdata,
>         },
>         { },
> };
> MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
> #endif
> 
> 
> > -ECONFUSED
> 
> Well, it is confusing...

Tell me about it... in that case, $SUBJECT can be dropped silently, I
will respin next patch so that it checks for VERSION_2 instead of
VERSION_3.

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/20121022/fb9efdd5/attachment.sig>

^ permalink raw reply

* [PATCH v3] ARM: SMP_TWD: make setup()/stop() reentrant
From: Linus Walleij @ 2012-10-22 13:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50853DE3.7050204@ti.com>

On Mon, Oct 22, 2012 at 2:36 PM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:

>> @@ -93,6 +95,8 @@ static void twd_timer_stop(struct clock_event_device
>> *clk)
>>   {
>>         twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
>>         disable_percpu_irq(clk->irq);
>> +       if (!IS_ERR(twd_clk))
>> +               clk_disable(twd_clk);
>
> Is this really needed? This clock disable is bogus since it
> can not really disable the clock.

Hm yeah I see the point, the CPU is running on that clock at this
point :-/

I'll drop this stuff then.

>> @@ -264,15 +268,46 @@ static struct clk *twd_get_clock(void)
>>   static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
>>   {
>>         struct clock_event_device **this_cpu_clk;
>> +       int cpu = smp_processor_id();
>>
>> -       if (!twd_clk)
>> +       /*
>> +        * If the basic setup for this CPU has been done before don't
>> +        * bother with the below.
>> +        */
>> +       if (per_cpu(percpu_setup_called, cpu)) {
>> +               if (!IS_ERR(twd_clk))
>> +                       clk_enable(twd_clk);
>> +               __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
>> +               clockevents_register_device(*__this_cpu_ptr(twd_evt));
>> +               enable_percpu_irq(clk->irq, 0);
>> +               return 0;
>> +       }
>> +       per_cpu(percpu_setup_called, cpu) = true;
>> +
>> +       /*
>> +        * This stuff only need to be done once for the entire TWD cluster
>> +        * during the runtime of the system.
>> +        */
>> +       if (!common_setup_called) {
>>                 twd_clk = twd_get_clock();
>>
> Moving the 'common_setup_called' code under one helper
> might be cleaner. No strong preference though.

I'll see what I can do. I could merge with the twd_get_clock
and call the result twd_get_rate or something.

>> +       common_setup_called = true;
>>
> So "common_setup_called" will get updated every time the
> twd_timer_setup() gets called. You can move this inside
> the if loop.

Will fix.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH] clk: Make the generic clock API available by default
From: Russell King - ARM Linux @ 2012-10-22 13:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350910970-9095-1-git-send-email-broonie@opensource.wolfsonmicro.com>

On Mon, Oct 22, 2012 at 02:02:50PM +0100, Mark Brown wrote:
> @@ -327,6 +328,7 @@ config ARCH_AT91
>  	select ARCH_REQUIRE_GPIOLIB
>  	select CLKDEV_LOOKUP
>  	select HAVE_CLK
> +	select HAVE_CUSTOM_CLK

This is silly.  If you select "HAVE_CUSTOM_CLK" then isn't it true that
"HAVE_CLK" should also be selected?  If so, why not have "HAVE_CUSTOM_CLK"
do that selection and remove it from all these entries?

^ permalink raw reply

* [PATCH 5/8] i2c: omap: introduce and use OMAP_I2C_IP_VERSION_3
From: Benoit Cousson @ 2012-10-22 13:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121022122853.GW14033@arwen.pp.htv.fi>

On 10/22/2012 02:28 PM, Felipe Balbi wrote:
> Hi,
> 
> On Mon, Oct 22, 2012 at 02:27:20PM +0200, Benoit Cousson wrote:
>> Hi Felipe,
>>
>> On 10/22/2012 11:46 AM, Felipe Balbi wrote:
>>> on OMAP4+ we want to read IRQSTATUS_RAW register,
>>> instead of IRQSTATUS. The reason being that IRQSTATUS
>>> will only contain the bits which were enabled on
>>> IRQENABLE_SET and that will break when we need to
>>> poll for a certain bit which wasn't enabled as an
>>> IRQ source.
>>>
>>> One such case is after we finish converting to
>>> deferred stop bit, we will have to poll for ARDY
>>> bit before returning control for the client driver
>>> in order to prevent us from trying to start a
>>> transfer on a bus which is already busy.
>>>
>>> Note, however, that omap-i2c.c needs a big rework
>>> on register definition and register access. Such
>>> work will be done in a separate series of patches.
>>
>> Do you need OMAP_I2C_IP_VERSION_3 for OMAP4?
>>
>> OMAP_I2C_IP_VERSION_2 was already introduced to detect OMAP3630 vs
>> omap4430 because they were sharing the same IP version..
>>
>> /* 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
>>
>> So in theory you should not need an extra version.
> 
> are you sure that's how they're used ? Looking at the code where we
> choose reg_map_ip_v1 and reg_map_ip_v2:
> 
> 1120         if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
> 1121                 dev->regs = (u8 *)reg_map_ip_v2;
> 1122         else
> 1123                 dev->regs = (u8 *)reg_map_ip_v1;
> 
> And looking at reg_map_ip_v1:
> 
>  218 static const u8 reg_map_ip_v1[] = {
>  219         [OMAP_I2C_REV_REG] = 0x00,
>  220         [OMAP_I2C_IE_REG] = 0x01,
>  221         [OMAP_I2C_STAT_REG] = 0x02,
>  222         [OMAP_I2C_IV_REG] = 0x03,
>  223         [OMAP_I2C_WE_REG] = 0x03,
>  224         [OMAP_I2C_SYSS_REG] = 0x04,
>  225         [OMAP_I2C_BUF_REG] = 0x05,
>  226         [OMAP_I2C_CNT_REG] = 0x06,
>  227         [OMAP_I2C_DATA_REG] = 0x07,
>  228         [OMAP_I2C_SYSC_REG] = 0x08,
>  229         [OMAP_I2C_CON_REG] = 0x09,
>  230         [OMAP_I2C_OA_REG] = 0x0a,
>  231         [OMAP_I2C_SA_REG] = 0x0b,
>  232         [OMAP_I2C_PSC_REG] = 0x0c,
>  233         [OMAP_I2C_SCLL_REG] = 0x0d,
>  234         [OMAP_I2C_SCLH_REG] = 0x0e,
>  235         [OMAP_I2C_SYSTEST_REG] = 0x0f,
>  236         [OMAP_I2C_BUFSTAT_REG] = 0x10,
>  237 };
> 
> that's really not the register map on OMAP3. That only looks valid for
> OMAP1.

No that should be valid as well for OMAP2&3 thanks to the
OMAP_I2C_FLAG_BUS_SHIFT_2.

It was introduced during DT adaptation:

#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 |
                 OMAP_I2C_FLAG_BUS_SHIFT_2,
};

static struct omap_i2c_bus_platform_data omap4_pdata = {
        .rev = OMAP_I2C_IP_VERSION_2,
};

static const struct of_device_id omap_i2c_of_match[] = {
        {
                .compatible = "ti,omap4-i2c",
                .data = &omap4_pdata,
        },
        {
                .compatible = "ti,omap3-i2c",
                .data = &omap3_pdata,
        },
        { },
};
MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
#endif


> -ECONFUSED

Well, it is confusing...

Benoit

^ permalink raw reply

* [PATCH] clk: Make the generic clock API available by default
From: Mark Brown @ 2012-10-22 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than requiring platforms to select the generic clock API to make
it available make the API available as a user selectable option unless the
user either selects HAVE_CUSTOM_CLK (if they have their own implementation)
or selects COMMON_CLK (if they depend on the generic implementation).

All current architectures that HAVE_CLK but don't use the common clock
framework have selects of HAVE_CUSTOM_CLK added.

This allows drivers to use the generic API on platforms which have no need
for the clock API at platform level.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Mike, the patch to provide a defualt clkdev.h went in during the merge
window so it should now be safe to merge this.

 arch/arm/Kconfig            |   13 +++++++++++++
 arch/avr32/Kconfig          |    1 +
 arch/mips/Kconfig           |    4 ++++
 arch/mips/loongson/Kconfig  |    1 +
 arch/mips/loongson1/Kconfig |    1 +
 arch/mips/txx9/Kconfig      |    1 +
 arch/powerpc/Kconfig        |    1 +
 arch/unicore32/Kconfig      |    1 +
 drivers/clk/Kconfig         |   13 ++++++++++---
 9 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fe90e60..2248940 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -314,6 +314,7 @@ config ARCH_VERSATILE
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select HAVE_MACH_CLKDEV
+	select HAVE_CUSTOM_CLK
 	select ICST
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE_CLCD
@@ -327,6 +328,7 @@ config ARCH_AT91
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select IRQ_DOMAIN
 	select NEED_MACH_GPIO_H
 	select NEED_MACH_IO_H if PCCARD
@@ -632,6 +634,7 @@ config ARCH_TEGRA
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select SPARSE_IRQ
@@ -666,6 +669,7 @@ config ARCH_MSM
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	help
 	  Support for Qualcomm MSM/QSD based systems.  This runs on the
 	  apps processor of the MSM/QSD and depends on a shared memory
@@ -678,6 +682,7 @@ config ARCH_SHMOBILE
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_MACH_CLKDEV
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
@@ -728,10 +733,12 @@ config ARCH_SA1100
 config ARCH_S3C24XX
 	bool "Samsung S3C24XX SoCs"
 	select ARCH_HAS_CPUFREQ
+	select CLKDEV_LOOKUP
 	select ARCH_USES_GETTIMEOFFSET
 	select CLKDEV_LOOKUP
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
@@ -752,6 +759,7 @@ config ARCH_S3C64XX
 	select CLKDEV_LOOKUP
 	select CPU_V6
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_TCM
@@ -775,6 +783,7 @@ config ARCH_S5P64X0
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
@@ -790,6 +799,7 @@ config ARCH_S5PC100
 	select CPU_V7
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
@@ -808,6 +818,7 @@ config ARCH_S5PV210
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
@@ -826,6 +837,7 @@ config ARCH_EXYNOS
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
@@ -928,6 +940,7 @@ config ARCH_OMAP
 	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select NEED_MACH_GPIO_H
 	help
 	  Support for TI's OMAP platform (OMAP1/2/3/4).
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 06e73bf..bfeb9cc 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -4,6 +4,7 @@ config AVR32
 	# that we usually don't need on AVR32.
 	select EXPERT
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
 	select HAVE_GENERIC_HARDIRQS
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ce6c9a6..e0be02f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -85,6 +85,7 @@ config AR7
 	select ARCH_REQUIRE_GPIOLIB
 	select VLYNQ
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	help
 	  Support for the Texas Instruments AR7 System-on-a-Chip
 	  family: TNETD7100, 7200 and 7300.
@@ -97,6 +98,7 @@ config ATH79
 	select CSRC_R4K
 	select DMA_NONCOHERENT
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select IRQ_CPU
 	select MIPS_MACHINE
 	select SYS_HAS_CPU_MIPS32_R2
@@ -134,6 +136,7 @@ config BCM63XX
 	select SWAP_IO_SPACE
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	help
 	 Support for BCM63XX based boards
 
@@ -229,6 +232,7 @@ config MACH_JZ4740
 	select SYS_HAS_EARLY_PRINTK
 	select HAVE_PWM
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select GENERIC_IRQ_CHIP
 
 config LANTIQ
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 263beb9..ed42be1 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -42,6 +42,7 @@ config LEMOTE_MACH2F
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA_SUPPORT_BROKEN
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select HW_HAS_PCI
 	select I8259
 	select IRQ_CPU
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig
index a9a14d6..ddaa7d0 100644
--- a/arch/mips/loongson1/Kconfig
+++ b/arch/mips/loongson1/Kconfig
@@ -16,6 +16,7 @@ config LOONGSON1_LS1B
 	select SYS_SUPPORTS_HIGHMEM
 	select SYS_HAS_EARLY_PRINTK
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 
 endchoice
 
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 6d40bc7..04e3cdb 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -21,6 +21,7 @@ config MACH_TXX9
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 
 config TOSHIBA_JMR3927
 	bool "Toshiba JMR-TX3927 board"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5af5aa7..da4ea6c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1028,6 +1028,7 @@ config PPC_CLOCK
 	bool
 	default n
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 
 config PPC_LIB_RHEAP
 	bool
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index fda37c9..8247d69 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -89,6 +89,7 @@ config ARCH_PUV3
 	select CPU_UCV2
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
+	select HAVE_CUSTOM_CLK
 	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_HAS_CPUFREQ
 
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index bace9e9..8dc8391 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -9,16 +9,23 @@ config HAVE_CLK_PREPARE
 config HAVE_MACH_CLKDEV
 	bool
 
-config COMMON_CLK
+config HAVE_CUSTOM_CLK
 	bool
+	---help---
+	  Architectures which provide a custom clk API should select
+	  this to disable the common clock API.
+
+config COMMON_CLK
+	bool "Common clock framework"
+	depends on !HAVE_CUSTOM_CLK
 	select HAVE_CLK_PREPARE
 	select CLKDEV_LOOKUP
 	---help---
 	  The common clock framework is a single definition of struct
 	  clk, useful across many platforms, as well as an
 	  implementation of the clock API in include/linux/clk.h.
-	  Architectures utilizing the common struct clk should select
-	  this option.
+	  This provides a generic way for drivers to provide and use
+	  clocks without hard coded relationships in the drivers.
 
 menu "Common Clock Framework"
 	depends on COMMON_CLK
-- 
1.7.10.4

^ permalink raw reply related

* [RFC/PATCH] mmc: omap_hsmmc: introduce omap_hsmmc_prepare/complete
From: Felipe Balbi @ 2012-10-22 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

prepare() is supposed to prevent new children from
being registered. On the MMC subsystem, children
(new cards) registration starts with the card
detect IRQ.

Move card detect IRQ disabling to prepare() so that
no new cards will be registered while we're trying
to suspend.

Likewise, move card detect IRQ enabling to complete()
so we only try to register new children after our MMC
IP is back up.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---

Venkat, do you think the patch below makes sense ?

cheers

 drivers/mmc/host/omap_hsmmc.c | 45 ++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 54bfd0c..4c8b41e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2022,6 +2022,26 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
+static int omap_hsmmc_prepare(struct device *dev)
+{
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+	if (host->pdata->suspend)
+		return host->pdata->suspend(dev, host->slot_id);
+
+	return 0;
+}
+
+static int omap_hsmmc_complete(struct device *dev)
+{
+	struct omap_hsmmc_host *host = dev_get_drvdata(dev);
+
+	if (host->pdata->resume)
+		return host->pdata->resume(dev, host->slot_id);
+
+	return 0;
+}
+
 static int omap_hsmmc_suspend(struct device *dev)
 {
 	int ret = 0;
@@ -2035,23 +2055,10 @@ static int omap_hsmmc_suspend(struct device *dev)
 
 	pm_runtime_get_sync(host->dev);
 	host->suspended = 1;
-	if (host->pdata->suspend) {
-		ret = host->pdata->suspend(dev, host->slot_id);
-		if (ret) {
-			dev_dbg(dev, "Unable to handle MMC board"
-					" level suspend\n");
-			host->suspended = 0;
-			return ret;
-		}
-	}
 	ret = mmc_suspend_host(host->mmc);
 
 	if (ret) {
 		host->suspended = 0;
-		if (host->pdata->resume) {
-			if (host->pdata->resume(dev, host->slot_id))
-				dev_dbg(dev, "Unmask interrupt failed\n");
-		}
 		goto err;
 	}
 
@@ -2088,12 +2095,6 @@ static int omap_hsmmc_resume(struct device *dev)
 	if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
 		omap_hsmmc_conf_bus_power(host);
 
-	if (host->pdata->resume) {
-		ret = host->pdata->resume(dev, host->slot_id);
-		if (ret)
-			dev_dbg(dev, "Unmask interrupt failed\n");
-	}
-
 	omap_hsmmc_protect_card(host);
 
 	/* Notify the core to resume the host */
@@ -2109,8 +2110,10 @@ static int omap_hsmmc_resume(struct device *dev)
 }
 
 #else
+#define omap_hsmmc_prepare	NULL
+#define omap_hsmmc_complete	NULL
 #define omap_hsmmc_suspend	NULL
-#define omap_hsmmc_resume		NULL
+#define omap_hsmmc_resume	NULL
 #endif
 
 static int omap_hsmmc_runtime_suspend(struct device *dev)
@@ -2138,6 +2141,8 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
 static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
 	.suspend	= omap_hsmmc_suspend,
 	.resume		= omap_hsmmc_resume,
+	.prepare	= omap_hsmmc_prepare,
+	.complete	= omap_hsmmc_complete,
 	.runtime_suspend = omap_hsmmc_runtime_suspend,
 	.runtime_resume = omap_hsmmc_runtime_resume,
 };
-- 
1.8.0.rc0

^ permalink raw reply related

* [PATCH 3/4] ARM/dts: omap5: Update UART with address space and interrupts
From: Sourav @ 2012-10-22 12:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508540FC.4090107@ti.com>

On Monday 22 October 2012 06:20 PM, Benoit Cousson wrote:
> On 10/22/2012 02:27 PM, Sourav wrote:
>> Hi Benoit,
>> On Monday 22 October 2012 05:37 PM, Benoit Cousson wrote:
>>> On 10/22/2012 01:57 PM, Benoit Cousson wrote:
>>>> Hi Sourav,
>>>>
>>>> On 10/22/2012 01:16 PM, Sourav wrote:
>>>>> Hi Sebastien,
>>>>> On Monday 22 October 2012 03:52 PM, Sebastien Guiriec wrote:
>>>>>> Add base address and interrupt line inside Device Tree data for
>>>>> Incomplete sentence!
>>>>>> Signed-off-by: Sebastien Guiriec <s-guiriec@ti.com>
>>>>>> ---
>>>>>>     arch/arm/boot/dts/omap5.dtsi |   16 ++++++++++++++--
>>>>>>     1 file changed, 14 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm/boot/dts/omap5.dtsi
>>>>>> b/arch/arm/boot/dts/omap5.dtsi
>>>>>> index 6c22e1b..413df94 100644
>>>>>> --- a/arch/arm/boot/dts/omap5.dtsi
>>>>>> +++ b/arch/arm/boot/dts/omap5.dtsi
>>>>>> @@ -237,36 +237,48 @@
>>>>>>               uart1: serial at 4806a000 {
>>>>>>                 compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x4806a000 0x100>;
>>>>>> +            interrupts = <0 72 0x4>;
>>>>>>                 ti,hwmods = "uart1";
>>>>>>                 clock-frequency = <48000000>;
>>>>>>             };
>>>>>>               uart2: serial at 4806c000 {
>>>>>>                 compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x4806c000 0x100>;
>>>>>> +            interrupts = <0 73 0x4>;
>>>>>>                 ti,hwmods = "uart2";
>>>>>>                 clock-frequency = <48000000>;
>>>>>>             };
>>>>>>               uart3: serial at 48020000 {
>>>>>>                 compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x48020000 0x100>;
>>>>>> +            interrupts = <0 74 0x4>;
>>>>>>                 ti,hwmods = "uart3";
>>>>>>                 clock-frequency = <48000000>;
>>>>>>             };
>>>>>>               uart4: serial at 4806e000 {
>>>>>>                 compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x4806e000 0x100>;
>>>>>> +            interrupts = <0 70 0x4>;
>>>>>>                 ti,hwmods = "uart4";
>>>>>>                 clock-frequency = <48000000>;
>>>>>>             };
>>>>>>               uart5: serial at 48066000 {
>>>>>> -            compatible = "ti,omap5-uart";
>>>>>> +            compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x48066000 0x100>;
>>>>>> +            interrupts = <0 105 0x4>;
>>>>> In Omap5 TRM, the interrupt number mentioned for uart5 is 138. How is
>>>>> 105 coming?
>>>> It is from hwmod and thus from the HW spec. It looks like the TRM is
>>>> wrong... or the HW spec :-)
>>>>
>>>>>>                 ti,hwmods = "uart5";
>>>>>>                 clock-frequency = <48000000>;
>>>>>>             };
>>>>>>               uart6: serial at 48068000 {
>>>>>> -            compatible = "ti,omap6-uart";
>>>>>> +            compatible = "ti,omap4-uart";
>>>>>> +            reg = <0x48068000 0x100>;
>>>>>> +            interrupts = <0 106 0x4>;
>>>>> Same here, TRM shows this number to be 139 ?
>>> In fact, even the TRM (ES1.0 NDA vM) is aligned with these data.
>>> Where did you see 138 and 139?
>> I looked at Page 6300 of the above TRM, Figure 24-60. Is this place not
>> correct to look
>> up for these data?
> Nope. Well it should be accurate but since it is a diagram, it does not
> necessarily reflect the latest integration data like IRQ line.
>
> You'd better use the table that list all the IRQ per CPU:
>
> 18.3.2 Interrupt Requests to INTC_MPU
Ahh. True. The table does show the numbers to be 105 and 106.
Thanks for the pointer.

~Sourav
> Regards,
> Benoit
>

^ permalink raw reply

* [PATCH 2/2] ARM: dts: cfa10049: Add the i2c muxer buses to the CFA-10049
From: Maxime Ripard @ 2012-10-22 12:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350910413-23925-1-git-send-email-maxime.ripard@free-electrons.com>

This will allow to add the 3 Nuvoton NAU7802 ADCs and the NXP PCA9555
GPIO expander eventually.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/imx28-cfa10049.dts |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/imx28-cfa10049.dts b/arch/arm/boot/dts/imx28-cfa10049.dts
index 97ee098..2cda823 100644
--- a/arch/arm/boot/dts/imx28-cfa10049.dts
+++ b/arch/arm/boot/dts/imx28-cfa10049.dts
@@ -76,6 +76,30 @@
 				status = "okay";
 			};
 
+			i2cmux {
+				compatible = "i2c-mux-gpio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				mux-gpios = <&gpio1 22 0 &gpio1 23 0>;
+				i2c-parent = <&i2c1>;
+
+				i2c at 0 {
+					reg = <0>;
+				};
+
+				i2c at 1 {
+					reg = <1>;
+				};
+
+				i2c at 2 {
+					reg = <2>;
+				};
+
+				i2c at 3 {
+					reg = <3>;
+				};
+			};
+
 			usbphy1: usbphy at 8007e000 {
 				status = "okay";
 			};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/2] i2c: mux: Add dt support to i2c-mux-gpio driver
From: Maxime Ripard @ 2012-10-22 12:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350910413-23925-1-git-send-email-maxime.ripard@free-electrons.com>

Allow the i2c-mux-gpio to be used by a device tree enabled device. The
bindings are inspired by the one found in the i2c-mux-pinctrl driver.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 .../devicetree/bindings/i2c/i2c-mux-gpio.txt       |   81 ++++++++++
 drivers/i2c/muxes/i2c-mux-gpio.c                   |  169 +++++++++++++++-----
 2 files changed, 211 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt
new file mode 100644
index 0000000..335fc4e
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt
@@ -0,0 +1,81 @@
+GPIO-based I2C Bus Mux
+
+This binding describes an I2C bus multiplexer that uses GPIOs to
+route the I2C signals.
+
+                                  +-----+  +-----+
+                                  | dev |  | dev |
+    +------------+                +-----+  +-----+
+    | SoC        |                   |        |
+    |            |          /--------+--------+
+    |   +------+ |  +------+    child bus A, on GPIO value set to 0
+    |   | I2C  |-|--| Mux  |
+    |   +------+ |  +--+---+    child bus B, on GPIO value set to 1
+    |            |     |    \----------+--------+--------+
+    |   +------+ |     |               |        |        |
+    |   | GPIO |-|-----+            +-----+  +-----+  +-----+
+    |   +------+ |                  | dev |  | dev |  | dev |
+    +------------+                  +-----+  +-----+  +-----+
+
+Required properties:
+- compatible: i2c-mux-gpio
+- i2c-parent: The phandle of the I2C bus that this multiplexer's master-side
+  port is connected to.
+- mux-gpios: list of gpios to use to control the muxer
+* Standard I2C mux properties. See mux.txt in this directory.
+* I2C child bus nodes. See mux.txt in this directory.
+
+Optional properties:
+- idle-state: value to set to the muxer when idle. When no value is
+  given, it defaults to the last value used.
+
+For each i2c child node, an I2C child bus will be created. They will
+be numbered based on the reg property of each node.
+
+Whenever an access is made to a device on a child bus, the value set
+in the revelant node's reg property will be output using the list of
+GPIOs, the first in the list holding the most-significant value.
+
+If an idle state is defined, using the idle-state (optional) property,
+whenever an access is not being made to a device on a child bus, the
+idle value will be programmed into the GPIOs.
+
+If an idle state is not defined, the most recently used value will be
+left programmed into hardware whenever no access is being made of a
+device on a child bus.
+
+Example:
+	i2cmux {
+		compatible = "i2c-mux-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		mux-gpios = <&gpio1 22 0 &gpio1 23 0>;
+		i2c-parent = <&i2c1>;
+
+		i2c at 1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			ssd1307: oled at 3c {
+				compatible = "solomon,ssd1307fb-i2c";
+				reg = <0x3c>;
+				pwms = <&pwm 4 3000>;
+				reset-gpios = <&gpio2 7 1>;
+				reset-active-low;
+			};
+		};
+
+		i2c at 3 {
+			reg = <3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pca9555: pca9555 at 20 {
+				compatible = "nxp,pca9555";
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x20>;
+			};
+		};
+	};
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 566a675..7ebef01 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -16,11 +16,13 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/of_i2c.h>
+#include <linux/of_gpio.h>
 
 struct gpiomux {
 	struct i2c_adapter *parent;
 	struct i2c_adapter **adap; /* child busses */
-	struct i2c_mux_gpio_platform_data data;
+	struct i2c_mux_gpio_platform_data *data;
 	unsigned gpio_base;
 };
 
@@ -28,8 +30,8 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
 {
 	int i;
 
-	for (i = 0; i < mux->data.n_gpios; i++)
-		gpio_set_value(mux->gpio_base + mux->data.gpios[i],
+	for (i = 0; i < mux->data->n_gpios; i++)
+		gpio_set_value(mux->gpio_base + mux->data->gpios[i],
 			       val & (1 << i));
 }
 
@@ -37,7 +39,7 @@ static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
 {
 	struct gpiomux *mux = data;
 
-	i2c_mux_gpio_set(mux, mux->data.values[chan]);
+	i2c_mux_gpio_set(mux, mux->data->values[chan]);
 
 	return 0;
 }
@@ -46,7 +48,7 @@ static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan)
 {
 	struct gpiomux *mux = data;
 
-	i2c_mux_gpio_set(mux, mux->data.idle);
+	i2c_mux_gpio_set(mux, mux->data->idle);
 
 	return 0;
 }
@@ -57,29 +59,118 @@ static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
 	return !strcmp(chip->label, data);
 }
 
+#ifdef CONFIG_OF
+static int __devinit i2c_mux_gpio_probe_dt(struct gpiomux *mux,
+					struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *adapter_np, *child;
+	struct i2c_adapter *adapter;
+	unsigned *values, *gpios;
+	int i = 0;
+
+	if (!np)
+		return 0;
+
+	mux->data = devm_kzalloc(&pdev->dev, sizeof(*mux->data),
+				GFP_KERNEL);
+	if (!mux->data) {
+		dev_err(&pdev->dev, "Cannot allocate platform_data");
+		return -ENOMEM;
+	}
+
+	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
+	if (!adapter_np) {
+		dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
+		return -ENODEV;
+	}
+	adapter = of_find_i2c_adapter_by_node(adapter_np);
+	if (!adapter) {
+		dev_err(&pdev->dev, "Cannot find parent bus\n");
+		return -ENODEV;
+	}
+	mux->data->parent = i2c_adapter_id(adapter);
+	put_device(&adapter->dev);
+
+	mux->data->n_values = of_get_child_count(np);
+
+	values = devm_kzalloc(&pdev->dev,
+			      sizeof(*mux->data->values) * mux->data->n_values,
+			      GFP_KERNEL);
+	if (!values) {
+		dev_err(&pdev->dev, "Cannot allocate values array");
+		return -ENOMEM;
+	}
+
+	for_each_child_of_node(np, child) {
+		of_property_read_u32(child, "reg", values + i);
+		i++;
+	}
+	mux->data->values = values;
+
+	if (of_property_read_u32(np, "idle-state", &mux->data->idle))
+		mux->data->idle = I2C_MUX_GPIO_NO_IDLE;
+
+	mux->data->n_gpios = of_gpio_named_count(np, "mux-gpios");
+	if (mux->data->n_gpios < 0) {
+		dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n");
+		return -EINVAL;
+	}
+
+	gpios = devm_kzalloc(&pdev->dev,
+			     sizeof(*mux->data->gpios) * mux->data->n_gpios,
+                             GFP_KERNEL);
+	if (!gpios) {
+		dev_err(&pdev->dev, "Cannot allocate gpios array");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < mux->data->n_gpios; i++)
+		gpios[i] = of_get_named_gpio(np, "mux-gpios", i);
+
+	mux->data->gpios = gpios;
+
+	return 0;
+}
+#else
+static int __devinit i2c_mux_gpio_probe_dt(struct gpiomux *mux,
+					struct platform_device *pdev)
+{
+	return 0;
+}
+#endif
+
 static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
 {
 	struct gpiomux *mux;
-	struct i2c_mux_gpio_platform_data *pdata;
 	struct i2c_adapter *parent;
 	int (*deselect) (struct i2c_adapter *, void *, u32);
 	unsigned initial_state, gpio_base;
 	int i, ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "Missing platform data\n");
-		return -ENODEV;
+	mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
+	if (!mux) {
+		dev_err(&pdev->dev, "Cannot allocate gpiomux structure");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, mux);
+
+	mux->data = pdev->dev.platform_data;
+	if (!mux->data) {
+		ret = i2c_mux_gpio_probe_dt(mux, pdev);
+		if (ret < 0)
+			return ret;
 	}
 
 	/*
 	 * If a GPIO chip name is provided, the GPIO pin numbers provided are
 	 * relative to its base GPIO number. Otherwise they are absolute.
 	 */
-	if (pdata->gpio_chip) {
+	if (mux->data->gpio_chip) {
 		struct gpio_chip *gpio;
 
-		gpio = gpiochip_find(pdata->gpio_chip,
+		gpio = gpiochip_find(mux->data->gpio_chip,
 				     match_gpio_chip_by_label);
 		if (!gpio)
 			return -EPROBE_DEFER;
@@ -89,49 +180,44 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
 		gpio_base = 0;
 	}
 
-	parent = i2c_get_adapter(pdata->parent);
+	parent = i2c_get_adapter(mux->data->parent);
 	if (!parent) {
 		dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
-			pdata->parent);
+			mux->data->parent);
 		return -ENODEV;
 	}
 
-	mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
-	if (!mux) {
-		ret = -ENOMEM;
-		goto alloc_failed;
-	}
-
 	mux->parent = parent;
-	mux->data = *pdata;
 	mux->gpio_base = gpio_base;
+
 	mux->adap = devm_kzalloc(&pdev->dev,
-				 sizeof(*mux->adap) * pdata->n_values,
+				 sizeof(*mux->adap) * mux->data->n_values,
 				 GFP_KERNEL);
 	if (!mux->adap) {
+		dev_err(&pdev->dev, "Cannot allocate i2c_adapter structure");
 		ret = -ENOMEM;
 		goto alloc_failed;
 	}
 
-	if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) {
-		initial_state = pdata->idle;
+	if (mux->data->idle != I2C_MUX_GPIO_NO_IDLE) {
+		initial_state = mux->data->idle;
 		deselect = i2c_mux_gpio_deselect;
 	} else {
-		initial_state = pdata->values[0];
+		initial_state = mux->data->values[0];
 		deselect = NULL;
 	}
 
-	for (i = 0; i < pdata->n_gpios; i++) {
-		ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
+	for (i = 0; i < mux->data->n_gpios; i++) {
+		ret = gpio_request(gpio_base + mux->data->gpios[i], "i2c-mux-gpio");
 		if (ret)
 			goto err_request_gpio;
-		gpio_direction_output(gpio_base + pdata->gpios[i],
+		gpio_direction_output(gpio_base + mux->data->gpios[i],
 				      initial_state & (1 << i));
 	}
 
-	for (i = 0; i < pdata->n_values; i++) {
-		u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
-		unsigned int class = pdata->classes ? pdata->classes[i] : 0;
+	for (i = 0; i < mux->data->n_values; i++) {
+		u32 nr = mux->data->base_nr ? (mux->data->base_nr + i) : 0;
+		unsigned int class = mux->data->classes ? mux->data->classes[i] : 0;
 
 		mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
 						   i, class,
@@ -144,19 +230,17 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
 	}
 
 	dev_info(&pdev->dev, "%d port mux on %s adapter\n",
-		 pdata->n_values, parent->name);
-
-	platform_set_drvdata(pdev, mux);
+		 mux->data->n_values, parent->name);
 
 	return 0;
 
 add_adapter_failed:
 	for (; i > 0; i--)
 		i2c_del_mux_adapter(mux->adap[i - 1]);
-	i = pdata->n_gpios;
+	i = mux->data->n_gpios;
 err_request_gpio:
 	for (; i > 0; i--)
-		gpio_free(gpio_base + pdata->gpios[i - 1]);
+		gpio_free(gpio_base + mux->data->gpios[i - 1]);
 alloc_failed:
 	i2c_put_adapter(parent);
 
@@ -168,11 +252,11 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
 	struct gpiomux *mux = platform_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < mux->data.n_values; i++)
+	for (i = 0; i < mux->data->n_values; i++)
 		i2c_del_mux_adapter(mux->adap[i]);
 
-	for (i = 0; i < mux->data.n_gpios; i++)
-		gpio_free(mux->gpio_base + mux->data.gpios[i]);
+	for (i = 0; i < mux->data->n_gpios; i++)
+		gpio_free(mux->gpio_base + mux->data->gpios[i]);
 
 	platform_set_drvdata(pdev, NULL);
 	i2c_put_adapter(mux->parent);
@@ -180,12 +264,19 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id i2c_mux_gpio_of_match[] __devinitconst = {
+	{ .compatible = "i2c-mux-gpio", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match);
+
 static struct platform_driver i2c_mux_gpio_driver = {
 	.probe	= i2c_mux_gpio_probe,
 	.remove	= __devexit_p(i2c_mux_gpio_remove),
 	.driver	= {
 		.owner	= THIS_MODULE,
 		.name	= "i2c-mux-gpio",
+		.of_match_table = of_match_ptr(i2c_mux_gpio_of_match),
 	},
 };
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCHv5 0/2] ARM: I2C: Add device tree bindings to i2c-mux-gpio
From: Maxime Ripard @ 2012-10-22 12:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,

This patchset adds the device tree entry to the CFA-10049 board of its i2c
muxer. This muxer controls sub-buses that contains three Nuvoton NAU7802
ADCs and a NXP PCA955 GPIO expander. Support for these will be added
eventually.

Thanks,
Maxime

Changes from v4:
  - Fixed a wrong sentence in the bindings documentation, stating a false
    behavoiour

Maxime Ripard (2):
  i2c: mux: Add dt support to i2c-mux-gpio driver
  ARM: dts: cfa10049: Add the i2c muxer buses to the CFA-10049

 .../devicetree/bindings/i2c/i2c-mux-gpio.txt       |   81 ++++++++++
 arch/arm/boot/dts/imx28-cfa10049.dts               |   24 +++
 drivers/i2c/muxes/i2c-mux-gpio.c                   |  169 +++++++++++++++-----
 3 files changed, 235 insertions(+), 39 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt

-- 
1.7.9.5

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox