Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] clk: divider: prepare for minimum divider
From: Afzal Mohammed @ 2013-01-23 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

Some of clocks can have a limit on minimum divider value that can be
programmed, prepare for such a support.

Add a new field min_div for the basic divider clock and a new dynamic
clock divider registration function where minimum divider value can
be specified. Keep behaviour of existing divider clock registration
functions, static initialization helpers as was earlier.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v2: create a new registration function for those that needs to
    constrain minimum divider value instead of modifying existing
    registration functions and hence remove modification in other
    clock files.
    

 drivers/clk/clk-divider.c    | 37 ++++++++++++++++++++++++++++++++++---
 include/linux/clk-private.h  |  6 +++++-
 include/linux/clk-provider.h |  7 +++++++
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index a9204c6..4025c5a 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -236,7 +236,7 @@ EXPORT_SYMBOL_GPL(clk_divider_ops);
 
 static struct clk *_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
-		void __iomem *reg, u8 shift, u8 width,
+		void __iomem *reg, u8 shift, u8 width, u8 min_div,
 		u8 clk_divider_flags, const struct clk_div_table *table,
 		spinlock_t *lock)
 {
@@ -244,6 +244,11 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	struct clk *clk;
 	struct clk_init_data init;
 
+	if (!min_div) {
+		pr_err("%s: minimum divider cannot be zero\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
 	/* allocate the divider */
 	div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
 	if (!div) {
@@ -261,6 +266,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 	div->reg = reg;
 	div->shift = shift;
 	div->width = width;
+	div->min_div = min_div;
 	div->flags = clk_divider_flags;
 	div->lock = lock;
 	div->hw.init = &init;
@@ -276,6 +282,29 @@ static struct clk *_register_divider(struct device *dev, const char *name,
 }
 
 /**
+ * clk_register_min_divider - register a divider clock having minimum divider
+ * constraints with clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @min_div: minimum allowable divider
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+struct clk *clk_register_min_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width, u8 min_div,
+		u8 clk_divider_flags, spinlock_t *lock)
+{
+	return _register_divider(dev, name, parent_name, flags, reg, shift,
+			width, min_div, clk_divider_flags, NULL, lock);
+}
+
+/**
  * clk_register_divider - register a divider clock with the clock framework
  * @dev: device registering this clock
  * @name: name of this clock
@@ -293,7 +322,8 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
 		u8 clk_divider_flags, spinlock_t *lock)
 {
 	return _register_divider(dev, name, parent_name, flags, reg, shift,
-			width, clk_divider_flags, NULL, lock);
+			width, CLK_DIVIDER_MIN_DIV_DEFAULT, clk_divider_flags,
+			NULL, lock);
 }
 
 /**
@@ -317,5 +347,6 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 		spinlock_t *lock)
 {
 	return _register_divider(dev, name, parent_name, flags, reg, shift,
-			width, clk_divider_flags, table, lock);
+			width, CLK_DIVIDER_MIN_DIV_DEFAULT, clk_divider_flags,
+			table, lock);
 }
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h
index 9c7f580..942a1be 100644
--- a/include/linux/clk-private.h
+++ b/include/linux/clk-private.h
@@ -105,7 +105,8 @@ struct clk {
 
 #define _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _shift, _width,	\
-				_divider_flags, _table, _lock)	\
+				_min_div, _divider_flags,	\
+				_table, _lock)			\
 	static struct clk _name;				\
 	static const char *_name##_parent_names[] = {		\
 		_parent_name,					\
@@ -120,6 +121,7 @@ struct clk {
 		.reg = _reg,					\
 		.shift = _shift,				\
 		.width = _width,				\
+		.min_div = _min_div,				\
 		.flags = _divider_flags,			\
 		.table = _table,				\
 		.lock = _lock,					\
@@ -132,6 +134,7 @@ struct clk {
 				_divider_flags, _lock)		\
 	_DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _shift, _width,	\
+				CLK_DIVIDER_MIN_DIV_DEFAULT,	\
 				_divider_flags, NULL, _lock)
 
 #define DEFINE_CLK_DIVIDER_TABLE(_name, _parent_name,		\
@@ -140,6 +143,7 @@ struct clk {
 				_table, _lock)			\
 	_DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr,	\
 				_flags, _reg, _shift, _width,	\
+				CLK_DIVIDER_MIN_DIV_DEFAULT,	\
 				_divider_flags, _table, _lock)	\
 
 #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags,	\
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 4989b8a..1c09481 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -248,15 +248,22 @@ struct clk_divider {
 	void __iomem	*reg;
 	u8		shift;
 	u8		width;
+	u8		min_div;
 	u8		flags;
 	const struct clk_div_table	*table;
 	spinlock_t	*lock;
 };
 
+#define	CLK_DIVIDER_MIN_DIV_DEFAULT	1
+
 #define CLK_DIVIDER_ONE_BASED		BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
 
 extern const struct clk_ops clk_divider_ops;
+struct clk *clk_register_min_divider(struct device *dev, const char *name,
+		const char *parent_name, unsigned long flags,
+		void __iomem *reg, u8 shift, u8 width, u8 min_div,
+		u8 clk_divider_flags, spinlock_t *lock);
 struct clk *clk_register_divider(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 shift, u8 width,
-- 
1.7.12

^ permalink raw reply related

* [PATCH] Implements DMA on mmci driver for LPC3250 plateform
From: Roland Stigge @ 2013-01-23 11:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AB1CB712-43B0-4E47-9752-91447BD749B9@precidata.com>

On 01/23/2013 11:11 AM, Gabriele Mondada wrote:
> Signed-off-by: Gabriele Mondada <gabriele@precidata.com>
> 
> UPDATE: Here is the patch cleaned up and validated with scripts/checkpatch.pl. I also add a check to prevent crashing when DMA is disabled.
> 
> ORIGINAL POST:
> Hi,
> Currently, LPC32xx plateform do not enable DMA on the mmci driver. This makes the driver useless because getting out data from a 64 bytes FIFO by interrupt is not fast enough (at standard SD-card data rate).
> 
> DMA is not enabled because LPC32xx has a bug that prevent DMA to work properly with the MMC controller (silicon bug, I guess). NXP did a patch to workaround this, but it has not been commited on the main branch. The patch is for linux 2.6.39.2 and does not use dmaengine.
> 
> So, I reworked this patch to make it compatible with the last kernel (3.7). Here it is. Have I any chance to see this patch be commited on the main branch?
> 
> Thanks a lot,
> Gabriele 
> 

Please consider that when I got this mail, the source/patch formatting
was broken, like this:

drivers/dma/amba-pl08x.c |   20 ++++++
drivers/mmc/host/mmci.c  |  159 =
+++++++++++++++++++++++++++++++++++++++++-----
drivers/mmc/host/mmci.h  |   12 +++-
3 files changed, 174 insertions(+), 17 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index d1cc579..728f65f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1758,6 +1758,26 @@ static void pl08x_free_virtual_channels(struct =
dma_device *dmadev)
	}
}

Please use "git send-email" or sth. where code is included unchanged.

Thanks,

Roland

^ permalink raw reply related

* [PATCH] [ARM] spitz/pxa: Refactor i2c init code in spitz.c
From: Marko Katić @ 2013-01-23 11:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAN1soZy4zXmZKUK0CAi-DndYvZhJqeJTkP1rfpti=v8Ns=HNVg@mail.gmail.com>

On Wed, Jan 23, 2013 at 10:00 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:
> On Wed, Dec 12, 2012 at 4:27 AM,  <dromede@gmail.com> wrote:
>> From: Marko Katic <dromede.gmail.com>
>>
>> This patch changes the way i2c devices are defined
>> and registered.
>>
>> I2c devices that are present in all spitz
>> variants are always defined and registered while the max7310
>> gpio expander specific to the akita variant is defined
>> and registered only when building the kernel for akita variants.
>>
>> spitz_i2c_init() is simplified and is now more readable.
>>
>> Signed-off-by: Marko Katic <dromede@gmail.com>
>> ---
>>  arch/arm/mach-pxa/spitz.c |   38 ++++++++++++++++++--------------------
>>  1 file changed, 18 insertions(+), 20 deletions(-)
>>
>> diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
>> index 0cc9dc7..1c7dc2b 100644
>> --- a/arch/arm/mach-pxa/spitz.c
>> +++ b/arch/arm/mach-pxa/spitz.c
>> @@ -865,17 +865,6 @@ static struct pca953x_platform_data akita_pca953x_pdata = {
>>         .gpio_base              = AKITA_IOEXP_GPIO_BASE,
>>  };
>>
>> -static struct i2c_board_info spitz_i2c_devs[] = {
>> -       {
>> -               .type           = "wm8750",
>> -               .addr           = 0x1b,
>> -       }, {
>> -               .type           = "max7310",
>> -               .addr           = 0x18,
>> -               .platform_data  = &akita_pca953x_pdata,
>> -       },
>> -};
>> -
>>  static struct regulator_consumer_supply isl6271a_consumers[] = {
>>         REGULATOR_SUPPLY("vcc_core", NULL),
>>  };
>> @@ -894,26 +883,35 @@ static struct regulator_init_data isl6271a_info[] = {
>>         }
>>  };
>>
>> -static struct i2c_board_info spitz_pi2c_devs[] = {
>> +static struct i2c_board_info spitz_i2c_devs[2] = {
>>         {
>> +               .type           = "wm8750",
>> +               .addr           = 0x1b,
>> +       }, {
>>                 .type           = "isl6271a",
>>                 .addr           = 0x0c,
>>                 .platform_data  = &isl6271a_info,
>>         },
>>  };
>>
> spitz_i2c_devs[] are in i2c0 bus. spitz_pi2c_devs[] are in i2c1 bus.
> Why do you move wm8750 from i2c0 bus to i2c1 bus?

Only the isl6271a is located on the i2c1 bus. WM8750 and MAX7310 are
on i2c0 bus.
Please examine my patch again. You will find that WM8750 is correctly
registered on
i2c0 bus with this line:

 i2c_register_board_info(0, &spitz_i2c_devs[0], 1);

^ permalink raw reply

* [PATCH 8/8] ARM: ux500: Remove traces of the ios_handler from platform code
From: Lee Jones @ 2013-01-23 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdZnDi8F7Zu646CPEt9SAx5gA=v0CJ-Rq1eJqKS_s2EHvw@mail.gmail.com>

On Wed, 23 Jan 2013, Linus Walleij wrote:

> On Wed, Jan 23, 2013 at 11:04 AM, Linus Walleij
> <linus.walleij@linaro.org> wrote:
> > On Thu, Dec 13, 2012 at 2:22 PM, Lee Jones <lee.jones@linaro.org> wrote:
> >
> >> Now MMCI on/off functionality is using the regulator framework
> >> from the MMCI driver, there is no need to keep the ios_handler
> >> laying around, duplicating functionality. So we're removing it.
> >>
> >> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> >> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> >
> > Applied to my ux500-cleanups branch.
> 
> Or no, wait, that is dependent or Russell's tree so will not
> be bisectable.
> 
> Either submit sequel patches to [1/8] through Russell's
> patch tracker (based on his tree I guess) or wait for these
> to hit mainline and push them after that.
> 
> Acked-by anway, on all of the cleanups following [1/8].

I have this queued already, with the MMCI patch in as a dependency.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v2 2/4] ARM: OMAP: devices: create device for usb part of control module
From: Felipe Balbi @ 2013-01-23 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358777308-2409-3-git-send-email-kishon@ti.com>

Hi,

On Mon, Jan 21, 2013 at 07:38:26PM +0530, Kishon Vijay Abraham I wrote:
> A seperate driver has been added to handle the usb part of control
> module. A device for the above driver is created here, using the register
> address information to be used by the driver for powering on the PHY and
> for writing to the mailbox.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Tony ? Without this we won't have the control module driver.

-- 
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/20130123/e5736514/attachment.sig>

^ permalink raw reply

* [PATCH V2 2/2] mmc: mmci: Move ios_handler functionality into the driver
From: Lee Jones @ 2013-01-23 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123101748.GO23505@n2100.arm.linux.org.uk>

On Wed, 23 Jan 2013, Russell King - ARM Linux wrote:

> On Wed, Jan 23, 2013 at 10:13:49AM +0000, Lee Jones wrote:
> > On Tue, 22 Jan 2013, Lee Jones wrote:
> > > Are you saying that you won't do it? :)
> > > 
> > > Is there anything I can do to make the process easier?
> > 
> > Thinking about this a little more. Is it easier to remove it from your
> > tree altogether? Only I have a small "ARM: ux500: " patch-set which
> > directly relies on this patch. I could take it in via ARM-SoC without
> > any fear of ordering issues.
> 
> Thankfully, the patch doesn't conflict with any of the others I have, so
> we can do that (and it's actually easier to do that.)
> 
> Done.

Brilliant, that's 2 birds with one stone. I'll queue it up for ARM-SoC.

Thanks Russell.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Santosh Shilimkar @ 2013-01-23 11:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123.125851.1450151123804323961.hdoyu@nvidia.com>

On Wednesday 23 January 2013 04:28 PM, Hiroshi Doyu wrote:
> Santosh Shilimkar <santosh.shilimkar@ti.com> wrote @ Wed, 23 Jan 2013 09:58:08 +0100:
>
>> On Tuesday 22 January 2013 10:34 PM, Olof Johansson wrote:
>>> On Tue, Jan 22, 2013 at 8:57 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>>> On 01/21/2013 11:07 PM, Santosh Shilimkar wrote:
>>>>> On Tuesday 22 January 2013 11:22 AM, Hiroshi Doyu wrote:
>>>>>> Skip scu_enable(scu_base) if CPU is not Cortex A9 with SCU.

[..]

>> Btw, I noticed the build error with patch 1/1. Since I wasn't using
>> the first interface in OMAP code, I just bypassed it for testing.
>> I might be missing some dependent patch which added
>> read_cpuid_part_number().
>
> The following one, which is in "next-20130123", is also necessary.
>
> commit 59530adc3f1b802c275f0197fc3ac72dc014267a
> Author: Christoffer Dall <c.dall@virtualopensystems.com>
> Date:   Tue Dec 18 04:06:37 2012 +0000
>
>      ARM: Define CPU part numbers and implementors
>
Thanks for the pointer Hiroshi.

Regards,
Santosh

^ permalink raw reply

* [PATCH v5 00/14] DMA Engine support for AM33XX
From: Santosh Shilimkar @ 2013-01-23 11:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358281974-8411-1-git-send-email-mporter@ti.com>

Matt,

On Wednesday 16 January 2013 02:02 AM, Matt Porter wrote:

[..]

> This series adds DMA Engine support for AM33xx, which uses
> an EDMA DMAC. The EDMA DMAC has been previously supported by only
> a private API implementation (much like the situation with OMAP
> DMA) found on the DaVinci family of SoCs.
>
> The series applies on top of 3.8-rc3 and the following patches:
>
> 	- TPS65910 REGMAP_IRQ build fix:
> 	  https://patchwork.kernel.org/patch/1857701/
> 	- dmaengine DT support from Vinod's dmaengine_dt branch in
> 	  git://git.infradead.org/users/vkoul/slave-dma.git since
> 	  027478851791df751176398be02a3b1c5f6aa824
> 	- edma dmaengine driver fix:
> 	  https://patchwork.kernel.org/patch/1961521/
> 	- dmaengine dma_get_channel_caps v2:
> 	  https://patchwork.kernel.org/patch/1961601/
> 	- dmaengine edma driver channel caps support v2:
> 	  https://patchwork.kernel.org/patch/1961591/
>
> The approach taken is similar to how OMAP DMA is being converted to
> DMA Engine support. With the functional EDMA private API already
> existing in mach-davinci/dma.c, we first move that to an ARM common
> area so it can be shared. Adding DT and runtime PM support to the
> private EDMA API implementation allows it to run on AM33xx. AM33xx
> *only* boots using DT so we leverage Jon's generic DT DMA helpers to
> register EDMA DMAC with the of_dma framework and then add support
> for calling the dma_request_slave_channel() API to both the mmc
> and spi drivers.
>
> With this series both BeagleBone and the AM335x EVM have working
> MMC and SPI support.
>
> This is tested on BeagleBone with a SPI framebuffer driver and MMC
> rootfs. A trivial gpio DMA event misc driver was used to test the
> crossbar DMA event support. It is also tested on the AM335x EVM
> with the onboard SPI flash and MMC rootfs. The branch at
> https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v4
> has the complete series, dependencies, and some test
> drivers/defconfigs.
>
> Regression testing was done on AM180x-EVM (which also makes use
> of the EDMA dmaengine driver and the EDMA private API) using SD,
> SPI flash, and the onboard audio supported by the ASoC Davinci
> driver. Regression testing was also done on a BeagleBoard xM
> booting from the legacy board file using MMC rootfs.
>
> Matt Porter (14):
>    ARM: davinci: move private EDMA API to arm/common
>    ARM: edma: remove unused transfer controller handlers
>    ARM: edma: add AM33XX support to the private EDMA API
>    dmaengine: edma: enable build for AM33XX
>    dmaengine: edma: Add TI EDMA device tree binding
>    ARM: dts: add AM33XX EDMA support
>    dmaengine: add dma_request_slave_channel_compat()
>    mmc: omap_hsmmc: convert to dma_request_slave_channel_compat()
>    mmc: omap_hsmmc: set max_segs based on dma engine limitations
>    mmc: omap_hsmmc: add generic DMA request support to the DT binding
>    ARM: dts: add AM33XX MMC support
>    spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
>    spi: omap2-mcspi: add generic DMA request support to the DT binding
>    ARM: dts: add AM33XX SPI DMA support
>
While going through the series and testing it out, I observed an issue
with MMC driver. You need patch in the end of the email to avoid the
issue. Same is attached in case mailer damages it. Can you please
add it with your series if you agree ?

Overall the series looks good to my eyes.
Acked-tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

Regards,
Santosh

 From 2dcc90b7a4b2dcdb52ddd052ca7f3e88a78e83e4 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Wed, 23 Jan 2013 16:04:32 +0530
Subject: [PATCH] mmc: omap_hsmmc: Skip platform_get_resource_byname() for dt
  case

MMC driver probe will abort for DT case because of failed
platform_get_resource_byname() lookup. Fix it by skipping resource
byname lookup for device tree build.

Issue is hidden because hwmod popullates the IO resources which
helps to succeed platform_get_resource_byname() and probe.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
  drivers/mmc/host/omap_hsmmc.c |   28 +++++++++++++++-------------
  1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f74bd69..d4655e7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1897,21 +1897,23 @@ static int omap_hsmmc_probe(struct 
platform_device *pdev)

  	omap_hsmmc_conf_bus_power(host);

-	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-	if (!res) {
-		dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
-		ret = -ENXIO;
-		goto err_irq;
-	}
-	tx_req = res->start;
+	if (!pdev->dev.of_node) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+		if (!res) {
+			dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
+			ret = -ENXIO;
+			goto err_irq;
+		}
+		tx_req = res->start;

-	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-	if (!res) {
-		dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
-		ret = -ENXIO;
-		goto err_irq;
+		res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+		if (!res) {
+			dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
+			ret = -ENXIO;
+			goto err_irq;
+		}
+		rx_req = res->start;
  	}
-	rx_req = res->start;

  	dma_cap_zero(mask);
  	dma_cap_set(DMA_SLAVE, mask);
-- 
1.7.9.5




-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mmc-omap_hsmmc-Skip-platform_get_resource_byname-for.patch
Type: text/x-patch
Size: 1942 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130123/d9dea110/attachment-0001.bin>

^ permalink raw reply related

* [v3 2/2] ARM: tegra: Skip scu_enable(scu_base) if not Cortex A9
From: Hiroshi Doyu @ 2013-01-23 10:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FFA620.50008@ti.com>

Santosh Shilimkar <santosh.shilimkar@ti.com> wrote @ Wed, 23 Jan 2013 09:58:08 +0100:

> On Tuesday 22 January 2013 10:34 PM, Olof Johansson wrote:
> > On Tue, Jan 22, 2013 at 8:57 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> >> On 01/21/2013 11:07 PM, Santosh Shilimkar wrote:
> >>> On Tuesday 22 January 2013 11:22 AM, Hiroshi Doyu wrote:
> >>>> Skip scu_enable(scu_base) if CPU is not Cortex A9 with SCU.
> >>>>
> >>>> Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
> >>>> ---
> >>> Looks fine. I will also update OMAP code with the new
> >>> interface. Thanks.
> >>
> >> OK, so patch 1/2 at least needs to get into a stable arm-soc branch
> >> then. Unless there are violent objections, I'll forward patch 1/2 to
> >> arm-soc and request it be added into a branch so that Tegra and OMAP can
> >> both merge it into their branches as a dependency. I guess patch 2/2
> >> could also be included; I don't think it has any complex dependencies
> >> that'd prevent that, and would help to show how patch 1/2 gets used.
> >>
> >> Hiroshi, is this series the only dependency you need for your Tegra114
> >> series? So, I could merge your Tegra114 series once this series is applied?
> >
> > For something like this, it might make more sense for us to just apply
> > the patches for OMAP on top, i.e. we'll pull the short branch from
> > you, and then we can just apply patches (with maintainer acks) on top,
> > instead of doing a bunch of single-patch pulls.
> >
> In case you decide to apply patches, you can use patch in the end
> of the email for OMAP. Attached the same in case mailer damages it.
> 
> Btw, I noticed the build error with patch 1/1. Since I wasn't using
> the first interface in OMAP code, I just bypassed it for testing.
> I might be missing some dependent patch which added
> read_cpuid_part_number().

The following one, which is in "next-20130123", is also necessary.

commit 59530adc3f1b802c275f0197fc3ac72dc014267a
Author: Christoffer Dall <c.dall@virtualopensystems.com>
Date:   Tue Dec 18 04:06:37 2012 +0000

    ARM: Define CPU part numbers and implementors

^ permalink raw reply

* [PATCH] clk: Add axi-clkgen driver
From: Russell King - ARM Linux @ 2013-01-23 10:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FFC02C.9000109@metafoo.de>

On Wed, Jan 23, 2013 at 11:49:16AM +0100, Lars-Peter Clausen wrote:
> On 01/23/2013 11:27 AM, Russell King - ARM Linux wrote:
> > On Wed, Jan 23, 2013 at 11:00:56AM +0100, Lars-Peter Clausen wrote:
> >> I think I read somewhere at some point that ioread{8,16,32} is preferred
> >> over write{b,h,l} in new code.
> > 
> > But... there's *no* point using ioread*() if you don't only use the
> > ioremap() interface.
> > 
> > ioread*() is there to allow PC IO and PC MMIO accesses through one
> > accessor depending on the cookie.  ioremap() only ever returns cookies
> > for MMIO accesses.
> 
> So your point is, if you know that it is MMIO memory only ever use readl and
> friends?

My point is... if you're going to stick with using ioremap(), then don't
bother with the potential overhead from ioread*() - you don't gain
anything but you have a few extra CPU cycles per access.  You might as
well just stick with read*() which aren't going anywhere anytime soon.

Sure, if you need stuff to work on both IO and MMIO accesses, then use
ioread*() but you'd also need the driver to:
- accept IORESOURCE_IO resource types.
- request these resources in the IO resource tree rather than the MMIO
  resource tree.
- use ioport_map() to "map" these resource types.

So, I don't mind seeing ioread*() in a driver _if_ it also uses IO resources
and handles them correctly, but it's pointless to use this accessor in any
driver which doesn't.

^ permalink raw reply

* [PATCH] ARM: dts: specify all the per-cpu interrupts of arch timer for exynos5440
From: Santosh Shilimkar @ 2013-01-23 10:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123103614.GD32237@e106331-lin.cambridge.arm.com>

Looping Marc, Benoit

On Wednesday 23 January 2013 04:06 PM, Mark Rutland wrote:
> On Tue, Jan 22, 2013 at 10:05:18PM +0000, Kukjin Kim wrote:
>> Mark Rutland wrote:
>>>
>> + devicetree-discuss, Grant Likely, Rob Herring and Tony Lindgren
>>
>>> On Tue, Jan 22, 2013 at 01:41:27AM +0000, Kukjin Kim wrote:
>>>> From: Thomas Abraham <thomas.ab@samsung.com>
>>>>
>>>> Need to be changed requirements in the 'cpus' node for exynos5440
>>>> to specify all the per-cpu interrupts of arch timer.
>>>
>>> The node(s) for the arch timer should not be in the cpus/cpu at N nodes.
>>> Instead, there should be one node (in the root of the tree).
>>>
>> Well, I don't think so. As per my understanding, the local timers are
>> attached to every ARM cores (cpus) and it generates certain interrupt to the
>> GIC. So the correct representation for this in device tree is to include the
>> interrupts in the cpu nodes in dts file. Your comments  refer to a
>> limitation in the Linux kernel implementation of the arch_timer and it
>> should not result in representing the hardware details incorrectly in the
>> dts file.
>
> I disagree. The "correct representation" is whatever the devicetree binding
> documentation describes. It does not describe placing timer nodes in the cpu
> nodes.
>
This seems to be exact same topic what is getting discussed here [1]
Technically DT is suppose to represent how the hardware is rather than
how the bindings are done.

But as Marc pointed out, the approach taken currently is to not 
duplicate the banked information. The thread [1] isn't concluded
yet but looks like we might want to avoid duplicating the information
considering, more of such duplication needs to follow. e.g gic i/f

Am still waiting on what Benoit has to say ?

Regards,
Santosh

[1] http://www.spinics.net/lists/linux-omap/msg85110.html

^ permalink raw reply

* [PATCH 7/7] clk: vexpress: Use common of_clk_init() function
From: Pawel Moll @ 2013-01-23 10:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1357282858-2112-7-git-send-email-pgaikwad@nvidia.com>

On Fri, 2013-01-04 at 07:00 +0000, Prashant Gaikwad wrote:
> Use common of_clk_init() function for clock initialization.
> 
> Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>

Just tested on VE, looks good to me.

So for this patch and the "[1/7] clk: add common of_clk_init() function"
one:

Tested-by: Pawel Moll <pawel.moll@arm.com>

Cheers!

Pawel

^ permalink raw reply

* [PATCH v5 00/14] DMA Engine support for AM33XX
From: Sekhar Nori @ 2013-01-23 10:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123022133.GA5727@opensource.wolfsonmicro.com>

Hi Mark,

On 1/23/2013 7:51 AM, Mark Brown wrote:
> On Tue, Jan 22, 2013 at 09:26:34PM +0530, Sekhar Nori wrote:
>> On 1/16/2013 2:02 AM, Matt Porter wrote:
> 
>>> This series adds DMA Engine support for AM33xx, which uses
>>> an EDMA DMAC. The EDMA DMAC has been previously supported by only
>>> a private API implementation (much like the situation with OMAP
>>> DMA) found on the DaVinci family of SoCs.
> 
>> Will you take this series through the OMAP tree? Only 1/14 touches
>> mach-davinci and I am mostly okay with it except some changes I just
>> requested Matt to make in another thread.
> 
> Is this series somewhere near actually getting merged then? It seemed
> like there was lots of stuff going on.

I don't think there is a lot of churn on this now. 5 of the patches have
already been acked by Tony. I had a look at the first two patches (from
davinci perspective) and they mostly look good to me.

That said, I was not intending to suggest the entire series was ready
for merging. Since the series touches multiple areas of the kernel, I
wanted to make sure we have one person shepherding the series towards
mainline.

Patch 1/14 has some changes in sound/ can you please take a look and ack
them?

Thanks,
Sekhar

^ permalink raw reply

* [PATCH] clk: Add axi-clkgen driver
From: Lars-Peter Clausen @ 2013-01-23 10:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130123102755.GP23505@n2100.arm.linux.org.uk>

On 01/23/2013 11:27 AM, Russell King - ARM Linux wrote:
> On Wed, Jan 23, 2013 at 11:00:56AM +0100, Lars-Peter Clausen wrote:
>> I think I read somewhere at some point that ioread{8,16,32} is preferred
>> over write{b,h,l} in new code.
> 
> But... there's *no* point using ioread*() if you don't only use the
> ioremap() interface.
> 
> ioread*() is there to allow PC IO and PC MMIO accesses through one
> accessor depending on the cookie.  ioremap() only ever returns cookies
> for MMIO accesses.

So your point is, if you know that it is MMIO memory only ever use readl and
friends?

- Lars

^ permalink raw reply

* [PATCH v9 20/20] mdf: omap-usb-host: get rid of build warning
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

Fixes the below build warning when driver is built-in.

drivers/mfd/omap-usb-host.c:750:12: warning:
?usbhs_omap_remove? defined but not used [-Wunused-function]

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index b21ca76..6b5edf6 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -791,7 +791,7 @@ static struct platform_driver usbhs_omap_driver = {
 		.owner		= THIS_MODULE,
 		.pm		= &usbhsomap_dev_pm_ops,
 	},
-	.remove		= __exit_p(usbhs_omap_remove),
+	.remove		= usbhs_omap_remove,
 };
 
 MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 19/20] mfd: omap-usb-host: Don't spam console on clk_set_parent failure
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

clk_set_parent is expected to fail on OMAP3 platforms. We don't
consider that as fatal so don't spam console.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 7f9c386..b21ca76 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -671,32 +671,32 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
-		/* for OMAP3 , the clk set paretn fails */
+		/* for OMAP3, clk_set_parent fails */
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->xclk60mhsp1_ck);
 		if (ret != 0)
-			dev_err(dev, "xclk60mhsp1_ck set parent"
-				"failed error:%d\n", ret);
+			dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
+					ret);
 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->init_60m_fclk);
 		if (ret != 0)
-			dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
+			dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
+					ret);
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 					omap->xclk60mhsp2_ck);
 		if (ret != 0)
-			dev_err(dev, "xclk60mhsp2_ck set parent"
-					"failed error:%d\n", ret);
+			dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
+					ret);
 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 						omap->init_60m_fclk);
 		if (ret != 0)
-			dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
+			dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
+					ret);
 	}
 
 	omap_usbhs_init(dev);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 18/20] mfd: omap-usb-host: clean up omap_usbhs_init()
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

We split initializing revision 1 and revision 2 into different
functions. Initialization is now done dynamically so that only
the number of ports available on the system are initialized.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |  129 +++++++++++++++++++++++++++----------------
 1 files changed, 81 insertions(+), 48 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 0740c68..7f9c386 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -358,6 +358,75 @@ static int usbhs_runtime_suspend(struct device *dev)
 	return 0;
 }
 
+static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap,
+						unsigned reg)
+{
+	struct usbhs_omap_platform_data	*pdata = omap->pdata;
+	int i;
+
+	for (i = 0; i < omap->nports; i++) {
+		switch (pdata->port_mode[i]) {
+		case OMAP_USBHS_PORT_MODE_UNUSED:
+			reg &= ~(OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS << i);
+			break;
+		case OMAP_EHCI_PORT_MODE_PHY:
+			if (pdata->single_ulpi_bypass)
+				break;
+
+			if (i == 0)
+				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
+			else
+				reg &= ~(OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
+								<< (i-1));
+			break;
+		default:
+			if (pdata->single_ulpi_bypass)
+				break;
+
+			if (i == 0)
+				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
+			else
+				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
+								<< (i-1);
+			break;
+		}
+	}
+
+	if (pdata->single_ulpi_bypass) {
+		/* bypass ULPI only if none of the ports use PHY mode */
+		reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
+
+		for (i = 0; i < omap->nports; i++) {
+			if (is_ehci_phy_mode(pdata->port_mode[i])) {
+				reg &= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
+				break;
+			}
+		}
+	}
+
+	return reg;
+}
+
+static unsigned omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap *omap,
+						unsigned reg)
+{
+	struct usbhs_omap_platform_data	*pdata = omap->pdata;
+	int i;
+
+	for (i = 0; i < omap->nports; i++) {
+		/* Clear port mode fields for PHY mode */
+		reg &= ~(OMAP4_P1_MODE_CLEAR << 2 * i);
+
+		if (is_ehci_tll_mode(pdata->port_mode[i]) ||
+				(is_ohci_port(pdata->port_mode[i])))
+			reg |= OMAP4_P1_MODE_TLL << 2 * i;
+		else if (is_ehci_hsic_mode(pdata->port_mode[i]))
+			reg |= OMAP4_P1_MODE_HSIC << 2 * i;
+	}
+
+	return reg;
+}
+
 static void omap_usbhs_init(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
@@ -389,54 +458,18 @@ static void omap_usbhs_init(struct device *dev)
 	reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
 	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
 
-	if (is_omap_usbhs_rev1(omap)) {
-		if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED)
-			reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
-		if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED)
-			reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
-		if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED)
-			reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
-
-		/* Bypass the TLL module for PHY mode operation */
-		if (pdata->single_ulpi_bypass) {
-			dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
-			if (is_ehci_phy_mode(pdata->port_mode[0]) ||
-				is_ehci_phy_mode(pdata->port_mode[1]) ||
-					is_ehci_phy_mode(pdata->port_mode[2]))
-				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
-			else
-				reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
-		} else {
-			dev_dbg(dev, "OMAP3 ES version > ES2.1\n");
-			if (is_ehci_phy_mode(pdata->port_mode[0]))
-				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
-			else
-				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
-			if (is_ehci_phy_mode(pdata->port_mode[1]))
-				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
-			else
-				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
-			if (is_ehci_phy_mode(pdata->port_mode[2]))
-				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
-			else
-				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
-		}
-	} else if (is_omap_usbhs_rev2(omap)) {
-		/* Clear port mode fields for PHY mode*/
-		reg &= ~OMAP4_P1_MODE_CLEAR;
-		reg &= ~OMAP4_P2_MODE_CLEAR;
-
-		if (is_ehci_tll_mode(pdata->port_mode[0]) ||
-			(is_ohci_port(pdata->port_mode[0])))
-			reg |= OMAP4_P1_MODE_TLL;
-		else if (is_ehci_hsic_mode(pdata->port_mode[0]))
-			reg |= OMAP4_P1_MODE_HSIC;
-
-		if (is_ehci_tll_mode(pdata->port_mode[1]) ||
-			(is_ohci_port(pdata->port_mode[1])))
-			reg |= OMAP4_P2_MODE_TLL;
-		else if (is_ehci_hsic_mode(pdata->port_mode[1]))
-			reg |= OMAP4_P2_MODE_HSIC;
+	switch (omap->usbhs_rev) {
+	case OMAP_USBHS_REV1:
+		omap_usbhs_rev1_hostconfig(omap, reg);
+		break;
+
+	case OMAP_USBHS_REV2:
+		omap_usbhs_rev2_hostconfig(omap, reg);
+		break;
+
+	default:	/* newer revisions */
+		omap_usbhs_rev2_hostconfig(omap, reg);
+		break;
 	}
 
 	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 17/20] mfd: omap-usb-host: Get rid of unnecessary spinlock
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

The driver does not have an interrupt handler and
we don't really need a spinlock, so get rid of it.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   16 ----------------
 1 files changed, 0 insertions(+), 16 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index bdfc8b7..0740c68 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
-#include <linux/spinlock.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-omap.h>
@@ -108,7 +107,6 @@ struct usbhs_hcd_omap {
 	struct usbhs_omap_platform_data	*pdata;
 
 	u32				usbhs_rev;
-	spinlock_t			lock;
 };
 /*-------------------------------------------------------------------------*/
 
@@ -276,13 +274,11 @@ static int usbhs_runtime_resume(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
-	unsigned long			flags;
 	int i, r;
 
 	dev_dbg(dev, "usbhs_runtime_resume\n");
 
 	omap_tll_enable();
-	spin_lock_irqsave(&omap->lock, flags);
 
 	if (!IS_ERR(omap->ehci_logic_fck))
 		clk_enable(omap->ehci_logic_fck);
@@ -324,8 +320,6 @@ static int usbhs_runtime_resume(struct device *dev)
 		}
 	}
 
-	spin_unlock_irqrestore(&omap->lock, flags);
-
 	return 0;
 }
 
@@ -333,13 +327,10 @@ static int usbhs_runtime_suspend(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
-	unsigned long			flags;
 	int i;
 
 	dev_dbg(dev, "usbhs_runtime_suspend\n");
 
-	spin_lock_irqsave(&omap->lock, flags);
-
 	for (i = 0; i < omap->nports; i++) {
 		switch (pdata->port_mode[i]) {
 		case OMAP_EHCI_PORT_MODE_HSIC:
@@ -362,7 +353,6 @@ static int usbhs_runtime_suspend(struct device *dev)
 	if (!IS_ERR(omap->ehci_logic_fck))
 		clk_disable(omap->ehci_logic_fck);
 
-	spin_unlock_irqrestore(&omap->lock, flags);
 	omap_tll_disable();
 
 	return 0;
@@ -372,7 +362,6 @@ static void omap_usbhs_init(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
-	unsigned long			flags;
 	unsigned			reg;
 
 	dev_dbg(dev, "starting TI HSUSB Controller\n");
@@ -391,7 +380,6 @@ static void omap_usbhs_init(struct device *dev)
 	}
 
 	pm_runtime_get_sync(dev);
-	spin_lock_irqsave(&omap->lock, flags);
 
 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 	/* setup ULPI bypass and burst configurations */
@@ -454,8 +442,6 @@ static void omap_usbhs_init(struct device *dev)
 	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
 	dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
 
-	spin_unlock_irqrestore(&omap->lock, flags);
-
 	pm_runtime_put_sync(dev);
 	if (pdata->phy_reset) {
 		/* Hold the PHY in RESET for enough time till
@@ -521,8 +507,6 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		return -EADDRNOTAVAIL;
 	}
 
-	spin_lock_init(&omap->lock);
-
 	omap->pdata = pdata;
 
 	pm_runtime_enable(dev);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 16/20] mfd: omap-usb-host: Manage HSIC clocks for HSIC mode
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

Enable the optional HSIC clocks (60MHz and 480MHz) for the ports
that are configured in HSIC mode.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   97 ++++++++++++++++++++++++++++++++++++------
 1 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 9fa0215..bdfc8b7 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -93,6 +93,8 @@
 struct usbhs_hcd_omap {
 	int				nports;
 	struct clk			**utmi_clk;
+	struct clk			**hsic60m_clk;
+	struct clk			**hsic480m_clk;
 
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
@@ -286,13 +288,40 @@ static int usbhs_runtime_resume(struct device *dev)
 		clk_enable(omap->ehci_logic_fck);
 
 	for (i = 0; i < omap->nports; i++) {
-		if (!is_ehci_tll_mode(pdata->port_mode[i]) ||
-				IS_ERR(omap->utmi_clk[i]))
-			continue;
-
-		r = clk_enable(omap->utmi_clk[i]);
-		if (r)
-			dev_err(dev, "Can't enable port %d clk : %d\n", i, r);
+		switch (pdata->port_mode[i]) {
+		case OMAP_EHCI_PORT_MODE_HSIC:
+			if (!IS_ERR(omap->hsic60m_clk[i])) {
+				r = clk_enable(omap->hsic60m_clk[i]);
+				if (r) {
+					dev_err(dev,
+					 "Can't enable port %d hsic60m clk:%d\n",
+					 i, r);
+				}
+			}
+
+			if (!IS_ERR(omap->hsic480m_clk[i])) {
+				r = clk_enable(omap->hsic480m_clk[i]);
+				if (r) {
+					dev_err(dev,
+					 "Can't enable port %d hsic480m clk:%d\n",
+					 i, r);
+				}
+			}
+		/* Fall through as HSIC mode needs utmi_clk */
+
+		case OMAP_EHCI_PORT_MODE_TLL:
+			if (!IS_ERR(omap->utmi_clk[i])) {
+				r = clk_enable(omap->utmi_clk[i]);
+				if (r) {
+					dev_err(dev,
+					 "Can't enable port %d clk : %d\n",
+					 i, r);
+				}
+			}
+			break;
+		default:
+			break;
+		}
 	}
 
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -312,9 +341,22 @@ static int usbhs_runtime_suspend(struct device *dev)
 	spin_lock_irqsave(&omap->lock, flags);
 
 	for (i = 0; i < omap->nports; i++) {
-		if (is_ehci_tll_mode(pdata->port_mode[i]) &&
-				!IS_ERR(omap->utmi_clk[i]))
-			clk_disable(omap->utmi_clk[i]);
+		switch (pdata->port_mode[i]) {
+		case OMAP_EHCI_PORT_MODE_HSIC:
+			if (!IS_ERR(omap->hsic60m_clk[i]))
+				clk_disable(omap->hsic60m_clk[i]);
+
+			if (!IS_ERR(omap->hsic480m_clk[i]))
+				clk_disable(omap->hsic480m_clk[i]);
+		/* Fall through as utmi_clks were used in HSIC mode */
+
+		case OMAP_EHCI_PORT_MODE_TLL:
+			if (!IS_ERR(omap->utmi_clk[i]))
+				clk_disable(omap->utmi_clk[i]);
+			break;
+		default:
+			break;
+		}
 	}
 
 	if (!IS_ERR(omap->ehci_logic_fck))
@@ -520,7 +562,10 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 	i = sizeof(struct clk *) * omap->nports;
 	omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
-	if (!omap->utmi_clk) {
+	omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+	omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+
+	if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
 		dev_err(dev, "Memory allocation failed\n");
 		ret = -ENOMEM;
 		goto err_mem;
@@ -578,7 +623,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	}
 
 	for (i = 0; i < omap->nports; i++) {
-		char clkname[] = "usb_host_hs_utmi_px_clk";
+		char clkname[30];
 
 		/* clock names are indexed from 1*/
 		snprintf(clkname, sizeof(clkname),
@@ -592,6 +637,20 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		if (IS_ERR(omap->utmi_clk[i]))
 			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
 				clkname, PTR_ERR(omap->utmi_clk[i]));
+
+		snprintf(clkname, sizeof(clkname),
+				"usb_host_hs_hsic480m_p%d_clk", i + 1);
+		omap->hsic480m_clk[i] = clk_get(dev, clkname);
+		if (IS_ERR(omap->hsic480m_clk[i]))
+			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
+				clkname, PTR_ERR(omap->hsic480m_clk[i]));
+
+		snprintf(clkname, sizeof(clkname),
+				"usb_host_hs_hsic60m_p%d_clk", i + 1);
+		omap->hsic60m_clk[i] = clk_get(dev, clkname);
+		if (IS_ERR(omap->hsic60m_clk[i]))
+			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
+				clkname, PTR_ERR(omap->hsic60m_clk[i]));
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -635,9 +694,14 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 err_alloc:
 	omap_usbhs_deinit(&pdev->dev);
 
-	for (i = 0; i < omap->nports; i++)
+	for (i = 0; i < omap->nports; i++) {
 		if (!IS_ERR(omap->utmi_clk[i]))
 			clk_put(omap->utmi_clk[i]);
+		if (!IS_ERR(omap->hsic60m_clk[i]))
+			clk_put(omap->hsic60m_clk[i]);
+		if (!IS_ERR(omap->hsic480m_clk[i]))
+			clk_put(omap->hsic480m_clk[i]);
+	}
 
 	clk_put(omap->init_60m_fclk);
 
@@ -676,9 +740,14 @@ static int usbhs_omap_remove(struct platform_device *pdev)
 
 	omap_usbhs_deinit(&pdev->dev);
 
-	for (i = 0; i < omap->nports; i++)
+	for (i = 0; i < omap->nports; i++) {
 		if (!IS_ERR(omap->utmi_clk[i]))
 			clk_put(omap->utmi_clk[i]);
+		if (!IS_ERR(omap->hsic60m_clk[i]))
+			clk_put(omap->hsic60m_clk[i]);
+		if (!IS_ERR(omap->hsic480m_clk[i]))
+			clk_put(omap->hsic480m_clk[i]);
+	}
 
 	clk_put(omap->init_60m_fclk);
 	clk_put(omap->utmi_p1_gfclk);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 15/20] mfd: omap-usb-host: cleanup clock management code
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

All ports have similarly named port clocks so we can
bunch them into a port data structure and use for loop
to enable/disable the clocks.

Dynamically allocate and get clocks based on number of ports
available on the platform

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |  186 ++++++++++++++++++++++++------------------
 1 files changed, 106 insertions(+), 80 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 779588b..9fa0215 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -92,13 +92,12 @@
 
 struct usbhs_hcd_omap {
 	int				nports;
+	struct clk			**utmi_clk;
 
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
-	struct clk			*utmi_p1_fck;
-	struct clk			*usbhost_p1_fck;
-	struct clk			*utmi_p2_fck;
-	struct clk			*usbhost_p2_fck;
+	struct clk			*utmi_p1_gfclk;
+	struct clk			*utmi_p2_gfclk;
 	struct clk			*init_60m_fclk;
 	struct clk			*ehci_logic_fck;
 
@@ -276,22 +275,25 @@ static int usbhs_runtime_resume(struct device *dev)
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
 	unsigned long			flags;
+	int i, r;
 
 	dev_dbg(dev, "usbhs_runtime_resume\n");
 
 	omap_tll_enable();
 	spin_lock_irqsave(&omap->lock, flags);
 
-	if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
+	if (!IS_ERR(omap->ehci_logic_fck))
 		clk_enable(omap->ehci_logic_fck);
 
-	if (is_ehci_tll_mode(pdata->port_mode[0]))
-		clk_enable(omap->usbhost_p1_fck);
-	if (is_ehci_tll_mode(pdata->port_mode[1]))
-		clk_enable(omap->usbhost_p2_fck);
+	for (i = 0; i < omap->nports; i++) {
+		if (!is_ehci_tll_mode(pdata->port_mode[i]) ||
+				IS_ERR(omap->utmi_clk[i]))
+			continue;
 
-	clk_enable(omap->utmi_p1_fck);
-	clk_enable(omap->utmi_p2_fck);
+		r = clk_enable(omap->utmi_clk[i]);
+		if (r)
+			dev_err(dev, "Can't enable port %d clk : %d\n", i, r);
+	}
 
 	spin_unlock_irqrestore(&omap->lock, flags);
 
@@ -303,20 +305,19 @@ static int usbhs_runtime_suspend(struct device *dev)
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = omap->pdata;
 	unsigned long			flags;
+	int i;
 
 	dev_dbg(dev, "usbhs_runtime_suspend\n");
 
 	spin_lock_irqsave(&omap->lock, flags);
 
-	if (is_ehci_tll_mode(pdata->port_mode[0]))
-		clk_disable(omap->usbhost_p1_fck);
-	if (is_ehci_tll_mode(pdata->port_mode[1]))
-		clk_disable(omap->usbhost_p2_fck);
-
-	clk_disable(omap->utmi_p2_fck);
-	clk_disable(omap->utmi_p1_fck);
+	for (i = 0; i < omap->nports; i++) {
+		if (is_ehci_tll_mode(pdata->port_mode[i]) &&
+				!IS_ERR(omap->utmi_clk[i]))
+			clk_disable(omap->utmi_clk[i]);
+	}
 
-	if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
+	if (!IS_ERR(omap->ehci_logic_fck))
 		clk_disable(omap->ehci_logic_fck);
 
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -458,6 +459,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	struct resource			*res;
 	int				ret = 0;
 	int				i;
+	bool				need_logic_fck;
 
 	if (!pdata) {
 		dev_err(dev, "Missing platform data\n");
@@ -516,76 +518,91 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		}
 	}
 
-	for (i = 0; i < omap->nports; i++)
+	i = sizeof(struct clk *) * omap->nports;
+	omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
+	if (!omap->utmi_clk) {
+		dev_err(dev, "Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	need_logic_fck = false;
+	for (i = 0; i < omap->nports; i++) {
 		if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
-			is_ehci_hsic_mode(i)) {
-			omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
-			if (IS_ERR(omap->ehci_logic_fck)) {
-				ret = PTR_ERR(omap->ehci_logic_fck);
-				dev_warn(dev, "ehci_logic_fck failed:%d\n",
-					 ret);
-			}
-			break;
+			is_ehci_hsic_mode(i))
+				need_logic_fck |= true;
+	}
+
+	omap->ehci_logic_fck = ERR_PTR(-EINVAL);
+	if (need_logic_fck) {
+		omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
+		if (IS_ERR(omap->ehci_logic_fck)) {
+			ret = PTR_ERR(omap->ehci_logic_fck);
+			dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
 		}
+	}
 
-	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
-	if (IS_ERR(omap->utmi_p1_fck)) {
-		ret = PTR_ERR(omap->utmi_p1_fck);
-		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
-		goto err_end;
+	omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk");
+	if (IS_ERR(omap->utmi_p1_gfclk)) {
+		ret = PTR_ERR(omap->utmi_p1_gfclk);
+		dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
+		goto err_p1_gfclk;
+	}
+
+	omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk");
+	if (IS_ERR(omap->utmi_p2_gfclk)) {
+		ret = PTR_ERR(omap->utmi_p2_gfclk);
+		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
+		goto err_p2_gfclk;
 	}
 
 	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
 	if (IS_ERR(omap->xclk60mhsp1_ck)) {
 		ret = PTR_ERR(omap->xclk60mhsp1_ck);
 		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-		goto err_utmi_p1_fck;
-	}
-
-	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
-	if (IS_ERR(omap->utmi_p2_fck)) {
-		ret = PTR_ERR(omap->utmi_p2_fck);
-		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-		goto err_xclk60mhsp1_ck;
+		goto err_xclk60mhsp1;
 	}
 
 	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
 	if (IS_ERR(omap->xclk60mhsp2_ck)) {
 		ret = PTR_ERR(omap->xclk60mhsp2_ck);
 		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-		goto err_utmi_p2_fck;
-	}
-
-	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
-	if (IS_ERR(omap->usbhost_p1_fck)) {
-		ret = PTR_ERR(omap->usbhost_p1_fck);
-		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
-		goto err_xclk60mhsp2_ck;
-	}
-
-	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
-	if (IS_ERR(omap->usbhost_p2_fck)) {
-		ret = PTR_ERR(omap->usbhost_p2_fck);
-		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
-		goto err_usbhost_p1_fck;
+		goto err_xclk60mhsp2;
 	}
 
 	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
 	if (IS_ERR(omap->init_60m_fclk)) {
 		ret = PTR_ERR(omap->init_60m_fclk);
 		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-		goto err_usbhost_p2_fck;
+		goto err_init60m;
+	}
+
+	for (i = 0; i < omap->nports; i++) {
+		char clkname[] = "usb_host_hs_utmi_px_clk";
+
+		/* clock names are indexed from 1*/
+		snprintf(clkname, sizeof(clkname),
+				"usb_host_hs_utmi_p%d_clk", i + 1);
+
+		/* If a clock is not found we won't bail out as not all
+		 * platforms have all clocks and we can function without
+		 * them
+		 */
+		omap->utmi_clk[i] = clk_get(dev, clkname);
+		if (IS_ERR(omap->utmi_clk[i]))
+			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
+				clkname, PTR_ERR(omap->utmi_clk[i]));
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
 		/* for OMAP3 , the clk set paretn fails */
-		ret = clk_set_parent(omap->utmi_p1_fck,
+		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->xclk60mhsp1_ck);
 		if (ret != 0)
 			dev_err(dev, "xclk60mhsp1_ck set parent"
 				"failed error:%d\n", ret);
 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
-		ret = clk_set_parent(omap->utmi_p1_fck,
+		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->init_60m_fclk);
 		if (ret != 0)
 			dev_err(dev, "init_60m_fclk set parent"
@@ -593,13 +610,13 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
-		ret = clk_set_parent(omap->utmi_p2_fck,
+		ret = clk_set_parent(omap->utmi_p2_gfclk,
 					omap->xclk60mhsp2_ck);
 		if (ret != 0)
 			dev_err(dev, "xclk60mhsp2_ck set parent"
 					"failed error:%d\n", ret);
 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
-		ret = clk_set_parent(omap->utmi_p2_fck,
+		ret = clk_set_parent(omap->utmi_p2_gfclk,
 						omap->init_60m_fclk);
 		if (ret != 0)
 			dev_err(dev, "init_60m_fclk set parent"
@@ -617,28 +634,30 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 err_alloc:
 	omap_usbhs_deinit(&pdev->dev);
-	clk_put(omap->init_60m_fclk);
 
-err_usbhost_p2_fck:
-	clk_put(omap->usbhost_p2_fck);
+	for (i = 0; i < omap->nports; i++)
+		if (!IS_ERR(omap->utmi_clk[i]))
+			clk_put(omap->utmi_clk[i]);
 
-err_usbhost_p1_fck:
-	clk_put(omap->usbhost_p1_fck);
+	clk_put(omap->init_60m_fclk);
 
-err_xclk60mhsp2_ck:
+err_init60m:
 	clk_put(omap->xclk60mhsp2_ck);
 
-err_utmi_p2_fck:
-	clk_put(omap->utmi_p2_fck);
-
-err_xclk60mhsp1_ck:
+err_xclk60mhsp2:
 	clk_put(omap->xclk60mhsp1_ck);
 
-err_utmi_p1_fck:
-	clk_put(omap->utmi_p1_fck);
+err_xclk60mhsp1:
+	clk_put(omap->utmi_p2_gfclk);
 
-err_end:
-	clk_put(omap->ehci_logic_fck);
+err_p2_gfclk:
+	clk_put(omap->utmi_p1_gfclk);
+
+err_p1_gfclk:
+	if (!IS_ERR(omap->ehci_logic_fck))
+		clk_put(omap->ehci_logic_fck);
+
+err_mem:
 	pm_runtime_disable(dev);
 
 	return ret;
@@ -653,16 +672,23 @@ err_end:
 static int usbhs_omap_remove(struct platform_device *pdev)
 {
 	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
+	int i;
 
 	omap_usbhs_deinit(&pdev->dev);
+
+	for (i = 0; i < omap->nports; i++)
+		if (!IS_ERR(omap->utmi_clk[i]))
+			clk_put(omap->utmi_clk[i]);
+
 	clk_put(omap->init_60m_fclk);
-	clk_put(omap->usbhost_p2_fck);
-	clk_put(omap->usbhost_p1_fck);
+	clk_put(omap->utmi_p1_gfclk);
+	clk_put(omap->utmi_p2_gfclk);
 	clk_put(omap->xclk60mhsp2_ck);
-	clk_put(omap->utmi_p2_fck);
 	clk_put(omap->xclk60mhsp1_ck);
-	clk_put(omap->utmi_p1_fck);
-	clk_put(omap->ehci_logic_fck);
+
+	if (!IS_ERR(omap->ehci_logic_fck))
+		clk_put(omap->ehci_logic_fck);
+
 	pm_runtime_disable(&pdev->dev);
 
 	return 0;
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 14/20] mfd: omap-usb-host: override number of ports from platform data
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

Both OMAP4 and 5 exhibit the same revision ID in the REVISION register
but they have different number of ports i.e. 2 and 3 respectively.
So we can't rely on REVISION register for number of ports on OMAP5
and depend on platform data (or device tree) instead.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c            |   34 +++++++++++++++++++------------
 include/linux/platform_data/usb-omap.h |    1 +
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 26319ca..779588b 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -493,19 +493,27 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	 */
 	pm_runtime_put_sync(dev);
 
-	switch (omap->usbhs_rev) {
-	case OMAP_USBHS_REV1:
-		omap->nports = 3;
-		break;
-	case OMAP_USBHS_REV2:
-		omap->nports = 2;
-		break;
-	default:
-		omap->nports = OMAP3_HS_USB_PORTS;
-		dev_dbg(dev,
-		  "USB HOST Rev : 0x%d not recognized, assuming %d ports\n",
-		   omap->usbhs_rev, omap->nports);
-		break;
+	/*
+	 * If platform data contains nports then use that
+	 * else make out number of ports from USBHS revision
+	 */
+	if (pdata->nports) {
+		omap->nports = pdata->nports;
+	} else {
+		switch (omap->usbhs_rev) {
+		case OMAP_USBHS_REV1:
+			omap->nports = 3;
+			break;
+		case OMAP_USBHS_REV2:
+			omap->nports = 2;
+			break;
+		default:
+			omap->nports = OMAP3_HS_USB_PORTS;
+			dev_dbg(dev,
+			 "USB HOST Rev:0x%d not recognized, assuming %d ports\n",
+			 omap->usbhs_rev, omap->nports);
+			break;
+		}
 	}
 
 	for (i = 0; i < omap->nports; i++)
diff --git a/include/linux/platform_data/usb-omap.h b/include/linux/platform_data/usb-omap.h
index 04c7537..925a4a7 100644
--- a/include/linux/platform_data/usb-omap.h
+++ b/include/linux/platform_data/usb-omap.h
@@ -39,6 +39,7 @@ enum usbhs_omap_port_mode {
 };
 
 struct usbhs_omap_platform_data {
+	int				nports;
 	enum usbhs_omap_port_mode	port_mode[OMAP3_HS_USB_PORTS];
 	int				reset_gpio_port[OMAP3_HS_USB_PORTS];
 	struct regulator		*regulator[OMAP3_HS_USB_PORTS];
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 13/20] mfd: omap-usb-host: know about number of ports from revision register
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

The revision register should tell us how many ports are present.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   33 ++++++++++++++++++++++++++++-----
 1 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 310aaa9..26319ca 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -91,6 +91,8 @@
 
 
 struct usbhs_hcd_omap {
+	int				nports;
+
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
 	struct clk			*utmi_p1_fck;
@@ -347,8 +349,6 @@ static void omap_usbhs_init(struct device *dev)
 
 	pm_runtime_get_sync(dev);
 	spin_lock_irqsave(&omap->lock, flags);
-	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
-	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 	/* setup ULPI bypass and burst configurations */
@@ -483,7 +483,32 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
-	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
+	platform_set_drvdata(pdev, omap);
+	pm_runtime_get_sync(dev);
+
+	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
+
+	/* we need to call runtime suspend before we update omap->nports
+	 * to prevent unbalanced clk_disable()
+	 */
+	pm_runtime_put_sync(dev);
+
+	switch (omap->usbhs_rev) {
+	case OMAP_USBHS_REV1:
+		omap->nports = 3;
+		break;
+	case OMAP_USBHS_REV2:
+		omap->nports = 2;
+		break;
+	default:
+		omap->nports = OMAP3_HS_USB_PORTS;
+		dev_dbg(dev,
+		  "USB HOST Rev : 0x%d not recognized, assuming %d ports\n",
+		   omap->usbhs_rev, omap->nports);
+		break;
+	}
+
+	for (i = 0; i < omap->nports; i++)
 		if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
 			is_ehci_hsic_mode(i)) {
 			omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
@@ -573,8 +598,6 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 				"failed error:%d\n", ret);
 	}
 
-	platform_set_drvdata(pdev, omap);
-
 	omap_usbhs_init(dev);
 	ret = omap_usbhs_alloc_children(pdev);
 	if (ret) {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 12/20] mfd: omap-usb-host: Use devm_kzalloc() and devm_request_and_ioremap()
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

Use devm_ variants of kzalloc and ioremap. Also clean up error path.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   38 +++++++++++---------------------------
 1 files changed, 11 insertions(+), 27 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 061366d..310aaa9 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -461,15 +461,20 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 	if (!pdata) {
 		dev_err(dev, "Missing platform data\n");
-		ret = -ENOMEM;
-		goto end_probe;
+		return -ENODEV;
 	}
 
-	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
 		dev_err(dev, "Memory allocation failed\n");
-		ret = -ENOMEM;
-		goto end_probe;
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
+	omap->uhh_base = devm_request_and_ioremap(dev, res);
+	if (!omap->uhh_base) {
+		dev_err(dev, "Resource request/ioremap failed\n");
+		return -EADDRNOTAVAIL;
 	}
 
 	spin_lock_init(&omap->lock);
@@ -568,20 +573,6 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 				"failed error:%d\n", ret);
 	}
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_init_60m_fclk;
-	}
-
-	omap->uhh_base = ioremap(res->start, resource_size(res));
-	if (!omap->uhh_base) {
-		dev_err(dev, "UHH ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_init_60m_fclk;
-	}
-
 	platform_set_drvdata(pdev, omap);
 
 	omap_usbhs_init(dev);
@@ -591,13 +582,10 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		goto err_alloc;
 	}
 
-	goto end_probe;
+	return 0;
 
 err_alloc:
 	omap_usbhs_deinit(&pdev->dev);
-	iounmap(omap->uhh_base);
-
-err_init_60m_fclk:
 	clk_put(omap->init_60m_fclk);
 
 err_usbhost_p2_fck:
@@ -621,9 +609,7 @@ err_utmi_p1_fck:
 err_end:
 	clk_put(omap->ehci_logic_fck);
 	pm_runtime_disable(dev);
-	kfree(omap);
 
-end_probe:
 	return ret;
 }
 
@@ -638,7 +624,6 @@ static int usbhs_omap_remove(struct platform_device *pdev)
 	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
 
 	omap_usbhs_deinit(&pdev->dev);
-	iounmap(omap->uhh_base);
 	clk_put(omap->init_60m_fclk);
 	clk_put(omap->usbhost_p2_fck);
 	clk_put(omap->usbhost_p1_fck);
@@ -648,7 +633,6 @@ static int usbhs_omap_remove(struct platform_device *pdev)
 	clk_put(omap->utmi_p1_fck);
 	clk_put(omap->ehci_logic_fck);
 	pm_runtime_disable(&pdev->dev);
-	kfree(omap);
 
 	return 0;
 }
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 11/20] mfd: omap_usb_host: Avoid missing platform data checks in suspend/resume
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

Get rid of the unnecessary missing platform data checks
in runtime_suspend/resume. We are already checking for missing
platform data in probe.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-host.c |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index d6e6b8c..061366d 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -277,11 +277,6 @@ static int usbhs_runtime_resume(struct device *dev)
 
 	dev_dbg(dev, "usbhs_runtime_resume\n");
 
-	if (!pdata) {
-		dev_dbg(dev, "missing platform_data\n");
-		return  -ENODEV;
-	}
-
 	omap_tll_enable();
 	spin_lock_irqsave(&omap->lock, flags);
 
@@ -309,11 +304,6 @@ static int usbhs_runtime_suspend(struct device *dev)
 
 	dev_dbg(dev, "usbhs_runtime_suspend\n");
 
-	if (!pdata) {
-		dev_dbg(dev, "missing platform_data\n");
-		return  -ENODEV;
-	}
-
 	spin_lock_irqsave(&omap->lock, flags);
 
 	if (is_ehci_tll_mode(pdata->port_mode[0]))
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v9 10/20] mfd: omap-usb-tll: Add OMAP5 revision and HSIC support
From: Roger Quadros @ 2013-01-23 10:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358937492-8129-1-git-send-email-rogerq@ti.com>

The TLL module on OMAP5 has 3 channels.
HSIC mode requires the TLL channel to be in Transparent UTMI mode.

Signed-off-by: Roger Quadros <rogerq@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
---
 drivers/mfd/omap-usb-tll.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index 55c85c7..0aef1a7 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -54,10 +54,13 @@
 
 #define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
 #define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT		24
+#define OMAP_TLL_CHANNEL_CONF_DRVVBUS			(1 << 16)
+#define OMAP_TLL_CHANNEL_CONF_CHRGVBUS			(1 << 15)
 #define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
 #define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
 #define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
 #define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
+#define OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI	(2 << 1)
 #define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS		(1 << 1)
 #define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
 
@@ -92,6 +95,7 @@
 #define OMAP_USBTLL_REV1		0x00000015	/* OMAP3 */
 #define OMAP_USBTLL_REV2		0x00000018	/* OMAP 3630 */
 #define OMAP_USBTLL_REV3		0x00000004	/* OMAP4 */
+#define OMAP_USBTLL_REV4		0x00000006	/* OMAP5 */
 
 #define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)
 
@@ -245,6 +249,7 @@ static int usbtll_omap_probe(struct platform_device *pdev)
 	ver =  usbtll_read(base, OMAP_USBTLL_REVISION);
 	switch (ver) {
 	case OMAP_USBTLL_REV1:
+	case OMAP_USBTLL_REV4:
 		tll->nch = OMAP_TLL_CHANNEL_COUNT;
 		break;
 	case OMAP_USBTLL_REV2:
@@ -310,6 +315,15 @@ static int usbtll_omap_probe(struct platform_device *pdev)
 				reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
 					| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
 					| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
+			} else if (pdata->port_mode[i] ==
+					OMAP_EHCI_PORT_MODE_HSIC) {
+				/*
+				 * HSIC Mode requires UTMI port configurations
+				 */
+				reg |= OMAP_TLL_CHANNEL_CONF_DRVVBUS
+				 | OMAP_TLL_CHANNEL_CONF_CHRGVBUS
+				 | OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI
+				 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;
 			} else {
 				continue;
 			}
-- 
1.7.4.1

^ permalink raw reply related


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