Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [v2 1/1] ARM: Add API to detect SCU base address from CP15
From: Russell King - ARM Linux @ 2013-01-21 15:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358754175-15484-1-git-send-email-hdoyu@nvidia.com>

On Mon, Jan 21, 2013 at 09:42:55AM +0200, Hiroshi Doyu wrote:
> Add API to detect SCU base address from CP15.
> 
> Signed-off-by: Hiroshi Doyu <hdoyu@nvidia.com>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> For usage: http://patchwork.ozlabs.org/patch/212013/
> ---
>  arch/arm/include/asm/smp_scu.h |   12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
> index 4eb6d00..1733ec7 100644
> --- a/arch/arm/include/asm/smp_scu.h
> +++ b/arch/arm/include/asm/smp_scu.h
> @@ -6,6 +6,18 @@
>  #define SCU_PM_POWEROFF	3
>  
>  #ifndef __ASSEMBLER__
> +
> +#include <asm/cputype.h>
> +
> +static inline phys_addr_t scu_get_base(void)
> +{
> +	if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) {
> +		phys_addr_t pa;
> +		asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));
> +		return pa;
> +	}
> +	return 0;
> +}
>  unsigned int scu_get_core_count(void __iomem *);
>  void scu_enable(void __iomem *);
>  int scu_power_mode(void __iomem *, unsigned int);

Not sure what iteration this patch is at but... it's easy to avoid more
iterations when you review the patch yourself before sending.

Reasonable coding style suggests there should be a blank line after the
new } and before the prototypes.

However, as I _am_ commenting on this patch because of the above, I'll
also suggest that we don't do it like this.  And actually, the above
code is buggy.  If phys_addr_t is 64-bit, the upper half of 'pa' won't
be set.

I'd suggest this instead:

static inline bool scu_a9_has_base(void)
{
	return read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
}

static inline unsigned long scu_a9_get_base(void)
{
	unsigned long pa;

	asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));

	return pa;
}

and let the user of these functions decide whether to read it using
scu_a9_has_base().

And why 'unsigned long' ?  Well, it could also be u32, but on 32-bit
ARM, it's been more conventional to use unsigned long for phys addresses
which can't be larger than 32-bit - which this one can't because the
mrc instruction is limited to writing one 32-bit register.

^ permalink raw reply

* [GIT PULL] Renesas ARM-based SoC v3.9
From: Laurent Pinchart @ 2013-01-21 15:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130116234310.GA411@quad.lixom.net>

Hi Olof,

On Wednesday 16 January 2013 15:43:10 Olof Johansson wrote:
> On Wed, Jan 16, 2013 at 03:37:53PM +0900, Simon Horman wrote:
> > Hi Olof, Hi Arnd,
> > 
> > I have some complex dependencies for mach-shmobile for v3.9 and as such I
> > am sending this email outline the dependencies of branches on each other.
> > I have also included the multiple pull requests below though I am happy to
> > post them individually including the patches they comprise if you have no
> > objections to the way the branch dependencies are arranged.
> > 
> > I would also be happy to supply a single branch with all changes with or
> > without merge commits.
> 
> Hmm, complex indeed.
> 
> Is there any way to avoid this sequence of ARM -> sh/pinctrl -> ARM ->
> sh/pinctrl dependencies? That's what really makes things look complicated
> here. If you could move the final cleanup/code removal pieces out of
> the sh/pinctrl branches such that you have a less iterative chain of:
> 
> sh/pinctrl -> ARM -> final sh/pinctrl cleanup (removal of struct members,
> etc)
> 
> ... but I haven't looked in detail at the per-patch dependencies to see how
> tough that would be to arrange.
> 
> > All branches are present in the renesas tree
> > git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git
> > 
> > 1. Branch: sh-soc
> > 
> >    Description: Pre-requisites for pfc changes for SH SoCs
> >    Based on: v3.8-rc1
> > 
> > 2. Branch: clocksource
> > 
> >    Description: Pre-requisite clocksource change for soc branch
> >    Based on: v3.8-rc1
> > 
> > 3. Branch: pfc
> > 
> >    Description: PFC Updates
> >    Based on: sh-soc
> > 
> > 4. Branch: sh-soc2
> > 
> >    Description: Further PFC changes for SH SoCs
> >    Based on: pfc
> > 
> > 5. Branch: soc
> > 
> >    Description: shmobile (ARM) SoCs updates, including PFC changes.
> >    Based on: a merge of clocksource and pfc
> > 
> > 6. Branch: boards
> > 
> >    Description: Board changes, including PFC changes.
> >    Based on: A merge of timer/cleanup (present in the arm-soc tree) and
> >    soc
> > 
> > 7. Branch: pfc2
> > 
> >    Description: Further PFC changes which depend on SoC changes
> >    Based on: A merge of sh-soc2 and soc
> > 
> > 8. Branch: sh-soc3
> > 
> >    Description: Further PFC changes for SH SoCs
> >    Based on: pfc2
> > 
> > 9. Branch: soc2
> > 
> >    Description: Further PFC changes for shmobile (ARM) SoCs
> >    Based on: A merge of timer/cleanup (present in the arm-soc tree) and
> >    pfc2
> > 
> > 10. Branch: pfc3
> > 
> >     Description: Description: Further PFC changes which depend on SoC
> >     changes
> >     Based on: A merge of sh-soc3 and soc2
> 
> Looking at it from the end here, 10 contains only arch/sh and global
> changes, and depends on 8 and 9. 8 also contains only sh changes. So it
> looks like 8 and 10 could be pruned from this pull request and go through
> either SH or pinctrl.
> 
> What pieces from branch 7 are stronly needed? A couple of the added pinctrl
> modules are used by mach-shmobile boards, it seems. And the structure rename
> might also be needed.

7 prepares for the move of PFC data from board code to drivers/. The branch 
mostly adds a pinctrl module for each of the supported SoCs, to allow later 
removal of PFC data from board code (in branches 8 and 9).

> Not having to pull in the bulk of 7, 8 and 10 would make a pretty big
> difference.

One way or the other all patches will need to be pulled. If they go through 
multiple trees we'll have to synchronize the multiple pull requests during the 
merge window, which looks pretty error-prone to me (but I might be wrong on 
this).

Sure, we could push 1-6 through the ARM tree, wait until it reaches mainline, 
then push 7 through the pinctrl tree, wait until it reaches mainline, push 8 
through the SH tree and 9 through the ARM tree, wait until they reach 
mainline, and finally push 10 through the pinctrl tree again. We could even 
push each branch through the tree it belongs to, but I doubt we'll be able to 
push everything during a single merge window.

I might be able to move 1 after 7, in which case we would have a single branch 
that would combine both and touch pinctrl only. The other dependencies seem 
pretty difficult to avoid.

What are the main issues with merging the branches in their current state (or 
possibly with 5 and 6 moved aside) through the ARM tree ?

> For branch 2 (clocksource include order), I'd like to see an ack from John
> or Thomas. Does it really make sense to base that on an ifdef instead of
> always initialize early?
> 
> Branch 4 seems to be mostly sh-specific updates. With some of the later
> dependencies avoided, maybe this branch can be dropped too, not sure?

4 moves platform device registration from the sh-pfc module to board code. 
Later pinctrl patches then remove platform device registration from the sh-pfc 
module completely and continue with the rework of the sh-pfc code. 7 thus 
strongly depends on 4.

> About half of branch 5 looks like it's generic SoC-updates unrelated
> to the pinctrl rework, and branch 6 looks like mostly regular
> patches/updates, is that stronly dependent on all the pinctrl
> rework? Doesn't look like it should be?

You're right here. The non-pinctrl patches in 5 could go through a separate 
branch, they shouldn't depend on the pinctrl rework. 6 also has no dependency 
on the pinctrl rework.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Compilation problem with drivers/staging/zsmalloc when !SMP on ARM
From: Russell King - ARM Linux @ 2013-01-21 15:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130119043725.GB5391@phenom.dumpdata.com>

On Fri, Jan 18, 2013 at 11:37:25PM -0500, Konrad Rzeszutek Wilk wrote:
> On Fri, Jan 18, 2013 at 01:45:27PM -0800, Greg Kroah-Hartman wrote:
> > On Fri, Jan 18, 2013 at 09:08:59PM +0000, Russell King - ARM Linux wrote:
> > > On Fri, Jan 18, 2013 at 02:24:15PM -0600, Matt Sealey wrote:
> > > > Hello all,
> > > > 
> > > > I wonder if anyone can shed some light on this linking problem I have
> > > > right now. If I configure my kernel without SMP support (it is a very
> > > > lean config for i.MX51 with device tree support only) I hit this error
> > > > on linking:
> > > 
> > > Yes, I looked at this, and I've decided that I will _not_ fix this export,
> > > neither will I accept a patch to add an export.
> > > 
> > > As far as I can see, this code is buggy in a SMP environment.  There's
> > > apparantly no guarantee that:
> > > 
> > > 1. the mapping will be created on a particular CPU.
> > > 2. the mapping will then be used only on this specific CPU.
> > > 3. no guarantee that another CPU won't speculatively prefetch from this
> > >    region.
> 
> I thought the code had per_cpu for it - so that you wouldn't do that unless
> you really went out the way to do it.

Actually, yes, you're right - that negates point (4) and possibly (2),
but (3) is still a concern.  (3) shouldn't be that much of an issue
_provided_ that the virtual addresses aren't explicitly made use of by
other CPUs.  Is that guaranteed by the zsmalloc code?  (IOW, does it
own the virtual region it places these mappings in?)

What is the performance difference between having and not having this
optimization?  Can you provide some measurements please?

Lastly, as you hold per_cpu stuff across this, that means preemption
is disabled - and any kind of scheduling is also a bug.  Is there
any reason the kmap stuff can't be used?  Has this been tried?  How
does it compare numerically with the existing solutions?

^ permalink raw reply

* [PATCH v7 03/15] gpio: use pinctrl device name for add range
From: Haojian Zhuang @ 2013-01-21 15:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdZoW0Pa9nMJin8_V+0_XVND4-hU=_SLkVEpskSfiYcyvg@mail.gmail.com>

On 21 January 2013 22:20, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>
>> gpiochip_add_pin_range() needs pinctrl device name as parameter.
>> Currently the parameter is pinctrl description name. So fix it.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>>  drivers/gpio/gpiolib-of.c |    2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
>> index d542a14..25b1dbe 100644
>> --- a/drivers/gpio/gpiolib-of.c
>> +++ b/drivers/gpio/gpiolib-of.c
>> @@ -250,7 +250,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
>>                  * on the same GPIO chip.
>>                  */
>>                 ret = gpiochip_add_pin_range(chip,
>> -                                            pinctrl_dev_get_name(pctldev),
>> +                                            pinctrl_dev_get_devname(pctldev),
>>                                              0, /* offset in gpiochip */
>>                                              pinspec.args[0],
>>                                              pinspec.args[1]);
>
> Hm looks like the right thing to do!
>
> Patch applied.
>
> It must be such that everyone using this so far has just
> set the name to be identical to the device name.
>
> Maybe we should just drop the name in the descriptor
> if it's causing problems like this?
>
> Yours,
> Linus Walleij

It seems that dropping the name won't impact any problem.
I'll try to drop it in new patches.

Regards
Haojian

^ permalink raw reply

* [GIT PULL] ste_dma40 updates for 3.9
From: Vinod Koul @ 2013-01-21 15:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130115085500.GA18406@balto.lan>

On Tue, Jan 15, 2013 at 09:55:00AM +0100, Fabio Baltieri wrote:
> Vinod, would you please consider pulling these into dmaengine's next
> tree?
Yes merged thanks

--
~Vinod

^ permalink raw reply

* [PATCH 08/10] ARM: OMAP5: hwmod data: Create initial OMAP5 SOC hwmod data
From: Santosh Shilimkar @ 2013-01-21 15:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FCF838.6000105@ti.com>

On Monday 21 January 2013 01:41 PM, Santosh Shilimkar wrote:
> On Friday 18 January 2013 10:45 PM, Tony Lindgren wrote:
>> Hi,
>>
>> * Santosh Shilimkar <santosh.shilimkar@ti.com> [130118 07:30]:
>>> From: Benoit Cousson <b-cousson@ti.com>
>>>
>>> Adding the hwmod data for OMAP54xx platforms.
>>> --- /dev/null
>>> +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
>>> +/* bb2d */
>>> +static struct omap_hwmod_irq_info omap54xx_bb2d_irqs[] = {
>>> +    { .irq = 125 + OMAP54XX_IRQ_GIC_START },
>>> +    { .irq = -1 }
>>> +};
>> ...
>>
>>> +/* c2c */
>>> +static struct omap_hwmod_irq_info omap54xx_c2c_irqs[] = {
>>> +    { .irq = 88 + OMAP54XX_IRQ_GIC_START },
>>> +    { .irq = -1 }
>>> +};
>> ...
>>
>>
>>> +static struct omap_hwmod_dma_info omap54xx_c2c_sdma_reqs[] = {
>>> +    { .dma_req = 68 + OMAP54XX_DMA_REQ_START },
>>> +    { .dma_req = -1 }
>>> +};
>>
>>
>>
>>> +static struct omap_hwmod_addr_space omap54xx_elm_addrs[] = {
>>> +    {
>>> +        .pa_start    = 0x48078000,
>>> +        .pa_end        = 0x48078fff,
>>> +        .flags        = ADDR_TYPE_RT
>>> +    },
>>> +    { }
>>> +};
>> ...
>>
>>> +static struct omap_hwmod_addr_space omap54xx_emif1_addrs[] = {
>>> +    {
>>> +        .pa_start    = 0x4c000000,
>>> +        .pa_end        = 0x4c0003ff,
>>> +        .flags        = ADDR_TYPE_RT
>>> +    },
>>> +    { }
>>> +};
>>
>> As discussed earlier on this list, let's not duplicate the standard
>> resources here as they already are supposed to come from device tree.
>>
>> Whatever issues prevent us from dropping the duplicate data here need
>> to be fixed. I believe Benoit already had some scripts/patches for
>> that and was just waiting for the DMA binding to get merged?
>>
> Will have a loot at it. DMA binding pull request narrowly missed
> 3.8 but should get into 3.9.
>
So I looked at this one with help of Rajendra. We can get rid of the
IRQ and DMA data(needs DMA biding updates) easily. The address
space though is needed since hwmod code uses it to setup the
sysconfig registers.

Extracting that from DT code seems to be really expensive and
ugly [1]. I am yet to try out DMA lines removal but that seems
to be doable by pulling Vinod'd DMA engine branch and updating
DT file.

Whats your suggestion on address space part ?

Regards,
Santosh

[1] HACK address extraction with DT.

---
  arch/arm/mach-omap2/omap_hwmod.c |   31 +++++++++++++++++++++++++++----
  1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c 
b/arch/arm/mach-omap2/omap_hwmod.c
index 4653efb..f54b9d4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -138,6 +138,7 @@
  #include <linux/spinlock.h>
  #include <linux/slab.h>
  #include <linux/bootmem.h>
+#include <linux/of.h>

  #include "clock.h"
  #include "omap_hwmod.h"
@@ -2335,7 +2336,12 @@ static int _shutdown(struct omap_hwmod *oh)
  static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
  {
  	struct omap_hwmod_addr_space *mem;
-	void __iomem *va_start;
+	void __iomem *va_start = NULL;
+	struct device_node *np;
+	unsigned long start = 0, size = 0;
+	const void *reg_prop;
+	const char *p;
+

  	if (!oh)
  		return;
@@ -2349,15 +2355,32 @@ static void __init _init_mpu_rt_base(struct 
omap_hwmod *oh, void *data)
  	if (!mem) {
  		pr_debug("omap_hwmod: %s: no MPU register target found\n",
  			 oh->name);
-		return;
+		/*Check in Device Tree blob*/
+		for_each_child_of_node(of_find_node_by_name(NULL, "ocp"), np) {
+			printk("np-name=%s\n", np->name);
+			if(of_find_property(np, "ti,hwmods", NULL)) {
+				p = of_get_property(np, "ti,hwmods", NULL);
+				if (!strcmp(p, oh->name)) {
+				reg_prop = of_get_property(np, "reg", NULL);
+				start = of_read_number(reg_prop, 1);
+				size = of_read_number(reg_prop + 4, 1);
+				}
+			}
+		}
+	} else {
+		start = mem->pa_start;
+		size = mem->pa_end - mem->pa_start;
  	}

-	va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
+	if (!start)
+		return;
+
+	va_start = ioremap(start, size);
  	if (!va_start) {
  		pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
  		return;
  	}
-
+	
  	pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
  		 oh->name, va_start);

-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v8 19/22] ARM: OMAP3: clock data: get rid of unused USB host clock aliases and dummies
From: Paul Walmsley @ 2013-01-21 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FD0BEF.9000007@ti.com>

Hi

On Mon, 21 Jan 2013, Roger Quadros wrote:

> On 01/18/2013 10:27 PM, Paul Walmsley wrote:
> > On Fri, 18 Jan 2013, Roger Quadros wrote:
> > 
> >> We don't need multiple aliases for the OMAP USB host clocks and neither
> >> the dummy clocks so remove them.
> >>
> >> CC: Paul Walmsley <paul@pwsan.com>
> >> CC: Rajendra Nayak <rnayak@ti.com>
> >> CC: Benoit Cousson <b-cousson@ti.com>
> >> CC: Mike Turquette <mturquette@linaro.com>
> >>
> >> Signed-off-by: Roger Quadros <rogerq@ti.com>
> >> Reviewed-by: Felipe Balbi <balbi@ti.com>
> >> Acked-by: Paul Walmsley <paul@pwsan.com>
> > 
> > Per Tony's earlier request, you can drop this patch and patch 20 from your 
> > series now.  I've got them queued for 3.10 or late 3.9 merge window.
> > 
> 
> Should have mentioned it earlier, but just this patch without the rest
> of the cleanup patches will break USB Host on OMAP3, as the old driver
> bails out if optional clock nodes are missing.
> 
> Including patch 20 doesn't seem to cause a problem with OMAP4 though.

I've got these two patches queued for merging after your other patches go 
upstream -- e.g., probably 3.10.  Do you foresee any problems with that?

- Paul

^ permalink raw reply

* [PATCH v2] mm: dmapool: use provided gfp flags for all dma_alloc_coherent() calls
From: Soeren Moch @ 2013-01-21 15:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201301192005.20093.arnd@arndb.de>

On 01/19/13 21:05, Arnd Bergmann wrote:
> I found at least one source line that incorrectly uses an atomic
> allocation, in ehci_mem_init():
>
>                  dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
>                          ehci->periodic_size * sizeof(__le32),
>                          &ehci->periodic_dma, 0);
>
> The last argument is the GFP_ flag, which should never be zero, as
> that is implicit !wait. This function is called only once, so it
> is not the actual culprit, but there could be other instances
> where we accidentally allocate something as GFP_ATOMIC.
>
> The total number of allocations I found for each type are
>
> sata_mv: 66 pages (270336 bytes)
> mv643xx_eth: 4 pages == (16384 bytes)
> orion_ehci: 154 pages (630784 bytes)
> orion_ehci (atomic): 256 pages (1048576 bytes)
>
> from the distribution of the numbers, it seems that there is exactly 1 MB
> of data allocated between bus addresses 0x1f90000 and 0x1f9ffff, allocated
> in individual pages. This matches the size of your pool, so it's definitely
> something coming from USB, and no single other allocation, but it does not
> directly point to a specific line of code.
Very interesting, so this is no fragmentation problem nor something 
caused by sata or ethernet.
> One thing I found was that the ARM dma-mapping code seems buggy in the way
> that it does a bitwise and between the gfp mask and GFP_ATOMIC, which does
> not work because GFP_ATOMIC is defined by the absence of __GFP_WAIT.
>
> I believe we need the patch below, but it is not clear to me if that issue
> is related to your problem or now.
Out of curiosity I checked include/linux/gfp.h. GFP_ATOMIC is defined as 
__GFP_HIGH (which means 'use emergency pool', and no wait), so this 
patch should not make any difference for "normal" (GPF_ATOMIC / 
GFP_KERNEL) allocations, only for gfp_flags accidentally set to zero. 
So, can a new test with this patch help to debug the pool exhaustion?
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 6b2fb87..c57975f 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -640,7 +641,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
>   
>   	if (is_coherent || nommu())
>   		addr = __alloc_simple_buffer(dev, size, gfp, &page);
> -	else if (gfp & GFP_ATOMIC)
> +	else if (!(gfp & __GFP_WAIT))
>   		addr = __alloc_from_pool(size, &page);
>   	else if (!IS_ENABLED(CONFIG_CMA))
>   		addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
> @@ -1272,7 +1273,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>   	*handle = DMA_ERROR_CODE;
>   	size = PAGE_ALIGN(size);
>   
> -	if (gfp & GFP_ATOMIC)
> +	if (!(gfp & __GFP_WAIT))
>   		return __iommu_alloc_atomic(dev, size, handle);
>   
>   	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
> 8<-------
>
> There is one more code path I could find, which is usb_submit_urb() =>
> usb_hcd_submit_urb => ehci_urb_enqueue() => submit_async() =>
> qh_append_tds() => qh_make(GFP_ATOMIC) => ehci_qh_alloc() =>
> dma_pool_alloc() => pool_alloc_page() => dma_alloc_coherent()
>
> So even for a GFP_KERNEL passed into usb_submit_urb, the ehci driver
> causes the low-level allocation to be GFP_ATOMIC, because
> qh_append_tds() is called under a spinlock. If we have hundreds
> of URBs in flight, that will exhaust the pool rather quickly.
>
Maybe there are hundreds of URBs in flight in my application, I have no 
idea how to check this. It seems to me that bad reception conditions 
(lost lock / regained lock messages for some dvb channels) accelerate 
the buffer exhaustion. But even with a 4MB coherent pool I see the 
error. Is there any chance to fix this in the usb or dvb subsystem (or 
wherever)? Should I try to further increase the pool size, or what else 
can I do besides using an older kernel?

   Soeren

^ permalink raw reply

* [PATCH 0/4] add ux500_wdt support
From: Linus Walleij @ 2013-01-21 14:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358509214-22407-1-git-send-email-fabio.baltieri@linaro.org>

On Fri, Jan 18, 2013 at 12:40 PM, Fabio Baltieri
<fabio.baltieri@linaro.org> wrote:

> this set adds support for the ux500_wdt timer, implemented in the PRCMU
> unit of ST-Ericsson ux500 architecture.
>
> The first two patches add the necessary definitions and function export
> to the PRCMU driver currently in mainline, while the third an fourth
> patches add the actual watchdog driver and mfd_cell definition to make
> it probe when PRCMU is compiled in.
>
> As the patches touches files in both mfd and watchdog subsystems, what do
> you think is the best way to handle this set?

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

As the majority touch the MFD parts, can Wim ack this so Sam can
take it through the MFD tree?

Yours,
Linus Walleij

^ permalink raw reply

* [kvmarm] [PATCH v6 14/15] KVM: ARM: Power State Coordination Interface implementation
From: Christoffer Dall @ 2013-01-21 14:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <75f43582106716efe7c8f1360e58732e@localhost>

On Mon, Jan 21, 2013 at 5:04 AM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Sun, 20 Jan 2013 18:35:51 -0500, Christoffer Dall
> <c.dall@virtualopensystems.com> wrote:
>> On Thu, Jan 17, 2013 at 10:55 AM, Marc Zyngier <marc.zyngier@arm.com>
>> wrote:
>>> On 16/01/13 17:59, Christoffer Dall wrote:
>>>> From: Marc Zyngier <marc.zyngier@arm.com>
>>>>
>>>> Implement the PSCI specification (ARM DEN 0022A) to control
>>>> virtual CPUs being "powered" on or off.
>>>>
>>>> PSCI/KVM is detected using the KVM_CAP_ARM_PSCI capability.
>>>>
>>>> A virtual CPU can now be initialized in a "powered off" state,
>>>> using the KVM_ARM_VCPU_POWER_OFF feature flag.
>>>>
>>>> The guest can use either SMC or HVC to execute a PSCI function.
>>>>
>>>> Reviewed-by: Will Deacon <will.deacon@arm.com>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
>>>
>>> A few bits went wrong when you reworked this patch. See below.
>
> [...]
>
>>>> @@ -443,13 +445,17 @@ static int handle_hvc(struct kvm_vcpu *vcpu,
>>>> struct kvm_run *run)
>>>>       trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
>>>>                     vcpu->arch.hsr & HSR_HVC_IMM_MASK);
>>>>
>>>> +     if (kvm_psci_call(vcpu))
>>>> +             return 1;
>>>> +
>>>>       return 1;
>>>
>>> No undef injection if there is no PSCI match?
>
> You haven't addressed this issue in you patch.
>
right, well, it's actually quite nice not having it give you an
undefined exception when it logs the trace event. The psci protocol
relies on a confirmation in form of a return value anyhow, so it was
actually on purpose to remove it, so you can do things like easily
measure exit times or probe places in the guest.

Let me know what you think.

^ permalink raw reply

* [PATCH v7 11/15] pinctrl: generic: add slew rate config parameter
From: Linus Walleij @ 2013-01-21 14:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-12-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> Add PIN_CONFIG_SLEW_RATE parameter into pinconf-generic driver.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Aha you need this.

Patch applied!

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v7 09/15] gpio: pl061: set initcall level to module init
From: Linus Walleij @ 2013-01-21 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-10-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> Replace subsys initcall by module initcall level. Since pinctrl
> driver is already launched before gpio driver. It's unnecessary
> to set gpio driver in subsys init call level.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

On you platform maybe it works, but have you made sure that nobody
else will be affected?

SPEAr of course, then these:

arch/arm/mach-realview/core.c:           * GPIO on PL061 is active,
which is the proper
arch/arm/mach-socfpga/Kconfig:  select GPIO_PL061 if GPIOLIB

Pawel, Dinh: are you OK with this change?

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v7 08/15] gpio: pl061: bind pinctrl by gpio request
From: Linus Walleij @ 2013-01-21 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-9-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> Add the pl061_gpio_request() to request pinctrl. Create the logic
> between pl061 gpio driver and pinctrl (pinctrl-single) driver.
>
> While a gpio pin is requested, it will request pinctrl driver to
> set that pin with gpio function mode. So pinctrl driver should
> append .gpio_request_enable() in pinmux_ops.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
(...)
> +static int pl061_gpio_request(struct gpio_chip *chip, unsigned offset)
> +{
> +       /*
> +        * Map back to global GPIO space and request muxing, the direction
> +        * parameter does not matter for this controller.
> +        */
> +       int gpio = chip->base + offset;
> +
> +       /*
> +        * Do NOT check the return value at here. Since sometimes the gpio
> +        * pin needn't to be configured in pinmux controller. So it's
> +        * impossible to find the matched gpio range.
> +        */
> +       pinctrl_request_gpio(gpio);

Handling of error code?

(Maybe I should add a __must_check on this function.)

> +       return 0;
> +}
> +
>  static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
>  {
>         struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
> @@ -251,6 +269,7 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
>
>         spin_lock_init(&chip->lock);
>
> +       chip->gc.request = pl061_gpio_request;
>         chip->gc.direction_input = pl061_direction_input;
>         chip->gc.direction_output = pl061_direction_output;
>         chip->gc.get = pl061_get_value;

What happens on a platform that has a PL061
GPIO block but no pinctrl related to it?

But still has some other pinctrl driver in the platform ....

Right, it'll return -EPROBE_DEFER from pinctrl_request_gpio().

This may happen on for example a combined SPEAr
kernel where some platforms have PL061 and others us
a pin controller, so both will be enabled.

I think, add a field like this to struct pl061_gpio:

bool has_pinctrl_backend;

The only call that from pl061_gpio_request() if this is
set:

if (pl061->has_pinctrl_backend)
   ret = pinctrl_request_gpio(gpio);

Then assign it in some clever way. For DT I think the
proper way would be so add a cross-binding to the
pin controller, like:

gpio2: gpio at d8100000 {
    #gpio-cells = <2>;
    compatible = "arm,pl061", "arm,primecell";
(...)
    pinctrl = <&mr_pincontrol>;
};

Then just check if you have this pinctrl binding set
to figure out if has_pinctrl_backend should be true.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 07/10] ARM: OMAP5: clock data: Add OMAP54XX full clock tree and headers
From: Santosh Shilimkar @ 2013-01-21 14:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FD5055.6000903@ti.com>

On Monday 21 January 2013 07:57 PM, Sebastien Guiriec wrote:
> Hi Santosh,
>
> I check the tree with Audio and it is working. Just a comment for the
> addition of ABE DPLL locking like for OMAP4.
>
Excellent. Can you send the update please?
I will fold that in.

Regards
santosh

^ permalink raw reply

* [PATCH v5 00/12] clk: exynos4: migrate to common clock framework
From: Sylwester Nawrocki @ 2013-01-21 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1356827621-27617-1-git-send-email-thomas.abraham@linaro.org>

On 12/30/2012 01:33 AM, Thomas Abraham wrote:
> Changes since v4:
> - Rebased to linux-3.8-rc1.
> 
> Changes since v3:
> - Includes changes suggested by Tomasz Figa <tomasz.figa@gmail.com>
> 
> This patch series migrates the Samsung Exynos4 SoC clock code to adopt the
> common clock framework. The use of Samsung specific clock structures has
> been removed and all board support code has been updated. imx-style of
> clock registration and lookup has been adopted for device tree based
> exynos4 platforms.
> 
> This patch series depends on this series:
> http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg14471.html
> and this patch
> http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg14472.html
> 
> Thomas Abraham (12):
>   clk: samsung: add common clock framework helper functions for Samsung platforms
>   clk: samsung: add pll clock registration helper functions
>   clk: exynos4: register clocks using common clock framework
>   ARM: Exynos: Rework timer initialization sequence
>   ARM: Exynos4: Migrate clock support to common clock framework
>   ARM: dts: add exynos4 clock controller nodes
>   ARM: dts: add xxti and xusbxti fixed rate clock nodes for exynos4 based platforms
>   ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
>   ARM: dts: add clock provider information for all controllers in Exynos4 SoC
>   ARM: Exynos4: remove auxdata table from machine file
>   ARM: Exynos: use fin_pll clock as the tick clock source for mct
>   ARM: Exynos: add support for mct clock setup
> 
>  .../devicetree/bindings/clock/exynos4-clock.txt    |  215 +++++++
>  arch/arm/boot/dts/exynos4.dtsi                     |   50 ++
>  arch/arm/boot/dts/exynos4210-origen.dts            |   12 +
>  arch/arm/boot/dts/exynos4210-smdkv310.dts          |   12 +
>  arch/arm/boot/dts/exynos4210.dtsi                  |    6 +
>  arch/arm/boot/dts/exynos4412-origen.dts            |   12 +
>  arch/arm/boot/dts/exynos4412-smdk4412.dts          |   12 +
>  arch/arm/boot/dts/exynos4x12.dtsi                  |    6 +
>  arch/arm/mach-exynos/Kconfig                       |    1 +
>  arch/arm/mach-exynos/Makefile                      |    3 -
>  arch/arm/mach-exynos/clock-exynos4.h               |   35 -
>  arch/arm/mach-exynos/clock-exynos4210.c            |  188 ------
>  arch/arm/mach-exynos/clock-exynos4212.c            |  192 ------
>  arch/arm/mach-exynos/common.c                      |   57 ++-
>  arch/arm/mach-exynos/common.h                      |   21 +-
>  arch/arm/mach-exynos/mach-armlex4210.c             |    3 +-
>  arch/arm/mach-exynos/mach-exynos4-dt.c             |   72 +--
>  arch/arm/mach-exynos/mach-exynos5-dt.c             |    2 +-
>  arch/arm/mach-exynos/mach-nuri.c                   |    5 +-
>  arch/arm/mach-exynos/mach-origen.c                 |    5 +-
>  arch/arm/mach-exynos/mach-smdk4x12.c               |    5 +-
>  arch/arm/mach-exynos/mach-smdkv310.c               |    7 +-
>  arch/arm/mach-exynos/mach-universal_c210.c         |    3 +-
>  arch/arm/mach-exynos/mct.c                         |   32 +-
>  arch/arm/plat-samsung/Kconfig                      |    4 +-
>  drivers/clk/Makefile                               |    1 +
>  drivers/clk/samsung/Makefile                       |    6 +
>  drivers/clk/samsung/clk-exynos4.c                  |  655 ++++++++++++++++++++
>  drivers/clk/samsung/clk-pll.c                      |  400 ++++++++++++
>  drivers/clk/samsung/clk-pll.h                      |   38 ++
>  drivers/clk/samsung/clk.c                          |  180 ++++++
>  drivers/clk/samsung/clk.h                          |  216 +++++++
>  32 files changed, 1919 insertions(+), 537 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>  delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
>  delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
>  delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>  create mode 100644 drivers/clk/samsung/Makefile
>  create mode 100644 drivers/clk/samsung/clk-exynos4.c
>  create mode 100644 drivers/clk/samsung/clk-pll.c
>  create mode 100644 drivers/clk/samsung/clk-pll.h
>  create mode 100644 drivers/clk/samsung/clk.c
>  create mode 100644 drivers/clk/samsung/clk.h

Thanks Thomas! The patch series generally looks good to me, I've tested 
it on an Exynos4412 based board. I have applied couple fixes that Tomasz
Figa has sent you off the mailing list. And to make a MIPI-CSI2 camera 
working a small fixup patch as below.

I have just one remark, but this could possibly be done as a follow up 
patch. Namely it may make sense to rename various sclk_* clocks to just
"sclk", so for instance we don't have "fimd", "sclk_fimd", "fimc", 
"sclk_fimc" but e.g. "bus" or "gate" and "sclk" for each device. Such 
naming might be better for handling devices at core subsystems level, 
e.g. Runtime PM or devfreq.

Please feel free to add:

Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

I would be great to have this patch set merged for 3.9, so people can 
switch earlier to the common clock API, rather than modifying files 
that will be removed soon.

--

Regards,
Sylwester

>From 8382dcc93bf465e9a03f4f07426825f1a9be0ba1 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Fri, 18 Jan 2013 19:13:52 +0100
Subject: [PATCH] clk: samsung: Correct definition of sclk_cam gate clocks

sclk_cam0/1 clock gates are present on all exynos4 SoCs. Move
definitions of these clocks to proper table to reflect that.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 6bdb13b..9c3e106 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -299,6 +299,8 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
 			0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
 	GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
 			0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+	GATE(sclk_cam0, "sclk_cam0", "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_cam1, "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
 	GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
 	GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
 	GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
@@ -416,8 +418,6 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
 			0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
 	GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12, CLK_SET_RATE_PARENT, 0),
 	GATE(sclk_sata, "sclk_sata", "div_sata", 0xc340, 24, CLK_SET_RATE_PARENT, 0),
-	GATE(sclk_cam0, "sclk_cam0", "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0),
-	GATE(sclk_cam1, "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
 	GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
 	GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
 	GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 07/10] ARM: OMAP5: clock data: Add OMAP54XX full clock tree and headers
From: Sebastien Guiriec @ 2013-01-21 14:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358522856-12180-8-git-send-email-santosh.shilimkar@ti.com>

Hi Santosh,

I check the tree with Audio and it is working. Just a comment for the 
addition of ABE DPLL locking like for OMAP4.

Sebastien

On 01/18/2013 04:27 PM, Santosh Shilimkar wrote:
> From: Rajendra Nayak <rnayak@ti.com>
>
> Add the clock tree related data for OMAP54xx platforms.
>
> Cc: Paul Walmsley <paul@pwsan.com>
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
> [santosh.shilimkar at ti.com: Generated es2.0 data]
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> As mentioned in the summary, this patch will be updated once the
> movement of clock data to drivers/clock is clear.
>
>   arch/arm/mach-omap2/cclock54xx_data.c   | 1794 +++++++++++++++++++++++++++++++
>   arch/arm/mach-omap2/clock.h             |   23 +-
>   arch/arm/mach-omap2/clock54xx.h         |   12 +
>   arch/arm/mach-omap2/clock_common_data.c |  139 ++-
>   4 files changed, 1931 insertions(+), 37 deletions(-)
>   create mode 100644 arch/arm/mach-omap2/cclock54xx_data.c
>   create mode 100644 arch/arm/mach-omap2/clock54xx.h
>
> diff --git a/arch/arm/mach-omap2/cclock54xx_data.c b/arch/arm/mach-omap2/cclock54xx_data.c
> new file mode 100644
> index 0000000..a1e2800
> --- /dev/null
> +++ b/arch/arm/mach-omap2/cclock54xx_data.c
> @@ -0,0 +1,1794 @@
> +/*
> + * OMAP54xx Clock data
> + *
> + * Copyright (C) 2013 Texas Instruments, Inc.
> + *
> + * Paul Walmsley (paul at pwsan.com)
> + * Rajendra Nayak (rnayak at ti.com)
> + * Benoit Cousson (b-cousson at ti.com)
> + * Mike Turquette (mturquette at ti.com)
> + *
> + * This file is automatically generated from the OMAP hardware databases.
> + * We respectfully ask that any modifications to this file be coordinated
> + * with the public linux-omap at vger.kernel.org mailing list and the
> + * authors above to ensure that the autogeneration scripts are kept
> + * up-to-date with the file contents.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * XXX Some of the ES1 clocks have been removed/changed; once support
> + * is added for discriminating clocks by ES level, these should be added back
> + * in.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/list.h>
> +#include <linux/clk-private.h>
> +#include <linux/clkdev.h>
> +#include <linux/io.h>
> +
> +#include "soc.h"
> +#include "iomap.h"
> +#include "clock.h"
> +#include "clock54xx.h"
> +#include "cm1_54xx.h"
> +#include "cm2_54xx.h"
> +#include "cm-regbits-54xx.h"
> +#include "prm54xx.h"
> +#include "prm-regbits-54xx.h"
> +#include "control.h"
> +#include "scrm54xx.h"
> +
> +/* OMAP4 modulemode control */
> +#define OMAP54XX_MODULEMODE_HWCTRL			0
> +#define OMAP54XX_MODULEMODE_SWCTRL			1
> +
> +/* Root clocks */
> +
> +DEFINE_CLK_FIXED_RATE(pad_clks_src_ck, CLK_IS_ROOT, 12000000, 0x0);
> +
> +DEFINE_CLK_GATE(pad_clks_ck, "pad_clks_src_ck", &pad_clks_src_ck, 0x0,
> +		OMAP54XX_CM_CLKSEL_ABE, OMAP54XX_PAD_CLKS_GATE_SHIFT, 0x0,
> +		NULL);
> +
> +DEFINE_CLK_FIXED_RATE(secure_32k_clk_src_ck, CLK_IS_ROOT, 32768, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(slimbus_src_clk, CLK_IS_ROOT, 12000000, 0x0);
> +
> +DEFINE_CLK_GATE(slimbus_clk, "slimbus_src_clk", &slimbus_src_clk, 0x0,
> +		OMAP54XX_CM_CLKSEL_ABE, OMAP54XX_SLIMBUS1_CLK_GATE_SHIFT, 0x0,
> +		NULL);
> +
> +DEFINE_CLK_FIXED_RATE(sys_32k_ck, CLK_IS_ROOT, 32768, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_12000000_ck, CLK_IS_ROOT, 12000000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_13000000_ck, CLK_IS_ROOT, 13000000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_16800000_ck, CLK_IS_ROOT, 16800000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_27000000_ck, CLK_IS_ROOT, 27000000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(virt_38400000_ck, CLK_IS_ROOT, 38400000, 0x0);
> +
> +static const struct clksel_rate div_1_5_rates[] = {
> +	{ .div = 1, .val = 5, .flags = RATE_IN_54XX },
> +	{ .div = 0 },
> +};
> +
> +static const struct clksel_rate div_1_6_rates[] = {
> +	{ .div = 1, .val = 6, .flags = RATE_IN_54XX },
> +	{ .div = 0 },
> +};
> +
> +static const struct clksel_rate div_1_7_rates[] = {
> +	{ .div = 1, .val = 7, .flags = RATE_IN_54XX },
> +	{ .div = 0 },
> +};
> +
> +static const struct clksel sys_clkin_sel[] = {
> +	{ .parent = &virt_12000000_ck, .rates = div_1_1_rates },
> +	{ .parent = &virt_13000000_ck, .rates = div_1_2_rates },
> +	{ .parent = &virt_16800000_ck, .rates = div_1_3_rates },
> +	{ .parent = &virt_19200000_ck, .rates = div_1_4_rates },
> +	{ .parent = &virt_26000000_ck, .rates = div_1_5_rates },
> +	{ .parent = &virt_27000000_ck, .rates = div_1_6_rates },
> +	{ .parent = &virt_38400000_ck, .rates = div_1_7_rates },
> +	{ .parent = NULL },
> +};
> +
> +static const char *sys_clkin_parents[] = {
> +	"virt_12000000_ck",
> +	"virt_13000000_ck",
> +	"virt_16800000_ck",
> +	"virt_19200000_ck",
> +	"virt_26000000_ck",
> +	"virt_27000000_ck",
> +	"virt_38400000_ck",
> +
> +};
> +
> +DEFINE_CLK_MUX(sys_clkin, sys_clkin_parents, NULL, 0x0, OMAP54XX_CM_CLKSEL_SYS,
> +	       OMAP54XX_SYS_CLKSEL_SHIFT, OMAP54XX_SYS_CLKSEL_WIDTH,
> +	       CLK_MUX_INDEX_ONE, NULL);
> +
> +DEFINE_CLK_FIXED_RATE(xclk60mhsp1_ck, CLK_IS_ROOT, 60000000, 0x0);
> +
> +DEFINE_CLK_FIXED_RATE(xclk60mhsp2_ck, CLK_IS_ROOT, 60000000, 0x0);
> +
> +/* Module clocks and DPLL outputs */
> +
> +static const char *abe_dpll_bypass_clk_mux_parents[] = {
> +	"sys_clkin", "sys_32k_ck",
> +};
> +
> +DEFINE_CLK_MUX(abe_dpll_bypass_clk_mux, abe_dpll_bypass_clk_mux_parents, NULL,
> +	       0x0, OMAP54XX_CM_CLKSEL_WKUPAON, OMAP54XX_CLKSEL_0_0_SHIFT,
> +	       OMAP54XX_CLKSEL_0_0_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(abe_dpll_clk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_CLKSEL_ABE_PLL_REF, OMAP54XX_CLKSEL_0_0_SHIFT,
> +	       OMAP54XX_CLKSEL_0_0_WIDTH, 0x0, NULL);
> +
> +/* DPLL_ABE */
> +static struct dpll_data dpll_abe_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_ABE,
> +	.clk_bypass	= &abe_dpll_bypass_clk_mux,
> +	.clk_ref	= &abe_dpll_clk_mux,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_ABE,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_ABE,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_ABE,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 2047,
> +	.max_divider	= 128,
> +	.min_divider	= 1,
> +};
> +
> +
> +static const char *dpll_abe_ck_parents[] = {
> +	"abe_dpll_clk_mux",
> +};
> +
> +static struct clk dpll_abe_ck;
> +
> +static const struct clk_ops dpll_abe_ck_ops = {
> +	.enable		= &omap3_noncore_dpll_enable,
> +	.disable	= &omap3_noncore_dpll_disable,
> +	.recalc_rate	= &omap4_dpll_regm4xen_recalc,
> +	.round_rate	= &omap4_dpll_regm4xen_round_rate,
> +	.set_rate	= &omap3_noncore_dpll_set_rate,
> +	.get_parent	= &omap2_init_dpll_parent,
> +};
> +
> +static struct clk_hw_omap dpll_abe_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_abe_ck,
> +	},
> +	.dpll_data	= &dpll_abe_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_abe_ck, dpll_abe_ck_parents, dpll_abe_ck_ops);
> +
> +static const char *dpll_abe_x2_ck_parents[] = {
> +	"dpll_abe_ck",
> +};
> +
> +static struct clk dpll_abe_x2_ck;
> +
> +static const struct clk_ops dpll_abe_x2_ck_ops = {
> +	.recalc_rate	= &omap3_clkoutx2_recalc,
> +};
> +
> +static struct clk_hw_omap dpll_abe_x2_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_abe_x2_ck,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_abe_x2_ck, dpll_abe_x2_ck_parents, dpll_abe_x2_ck_ops);
> +
> +static const struct clk_ops omap_hsdivider_ops = {
> +	.set_rate	= &omap2_clksel_set_rate,
> +	.recalc_rate	= &omap2_clksel_recalc,
> +	.round_rate	= &omap2_clksel_round_rate,
> +};
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_abe_m2x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck,
> +			    0x0, OMAP54XX_CM_DIV_M2_DPLL_ABE,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +DEFINE_CLK_FIXED_FACTOR(abe_24m_fclk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck,
> +			0x0, 1, 8);
> +
> +DEFINE_CLK_DIVIDER(abe_clk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, 0x0,
> +		   OMAP54XX_CM_CLKSEL_ABE, OMAP54XX_CLKSEL_OPP_SHIFT,
> +		   OMAP54XX_CLKSEL_OPP_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
> +		   NULL);
> +
> +DEFINE_CLK_FIXED_FACTOR(abe_iclk, "abe_clk", &abe_clk, 0x0, 1, 2);
> +
> +DEFINE_CLK_FIXED_FACTOR(abe_lp_clk_div, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck,
> +			0x0, 1, 16);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_abe_m3x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck,
> +			    0x0, OMAP54XX_CM_DIV_M3_DPLL_ABE,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +/* DPLL_CORE */
> +static struct dpll_data dpll_core_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_CORE,
> +	.clk_bypass	= &dpll_abe_m3x2_ck,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_CORE,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_CORE,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_CORE,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 2047,
> +	.max_divider	= 128,
> +	.min_divider	= 1,
> +};
> +
> +
> +static const char *dpll_core_ck_parents[] = {
> +	"sys_clkin",
> +};
> +
> +static struct clk dpll_core_ck;
> +
> +static const struct clk_ops dpll_core_ck_ops = {
> +	.recalc_rate	= &omap3_dpll_recalc,
> +	.get_parent	= &omap2_init_dpll_parent,
> +};
> +
> +static struct clk_hw_omap dpll_core_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_core_ck,
> +	},
> +	.dpll_data	= &dpll_core_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops);
> +
> +static const char *dpll_core_x2_ck_parents[] = {
> +	"dpll_core_ck",
> +};
> +
> +static struct clk dpll_core_x2_ck;
> +
> +static struct clk_hw_omap dpll_core_x2_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_core_x2_ck,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_abe_x2_ck_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h21x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H21_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +static const char *c2c_fclk_parents[] = {
> +	"dpll_core_h21x2_ck",
> +};
> +
> +static struct clk c2c_fclk;
> +
> +static const struct clk_ops c2c_fclk_ops = {
> +};
> +
> +static struct clk_hw_omap c2c_fclk_hw = {
> +	.hw = {
> +		.clk = &c2c_fclk,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(c2c_fclk, c2c_fclk_parents, c2c_fclk_ops);
> +
> +DEFINE_CLK_FIXED_FACTOR(c2c_iclk, "c2c_fclk", &c2c_fclk, 0x0, 1, 2);
> +
> +DEFINE_CLK_FIXED_FACTOR(custefuse_sys_gfclk_div, "sys_clkin", &sys_clkin, 0x0,
> +			1, 2);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h11x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H11_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h12x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H12_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h13x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H13_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h14x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H14_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h22x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H22_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h23x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H23_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_h24x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_H24_DPLL_CORE, OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_m2_ck, "dpll_core_ck", &dpll_core_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_CORE,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_core_m3x2_ck, "dpll_core_x2_ck",
> +			    &dpll_core_x2_ck, 0x0, OMAP54XX_CM_DIV_M3_DPLL_CORE,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +static const char *iva_dpll_hs_clk_div_parents[] = {
> +	"dpll_core_h12x2_ck",
> +};
> +
> +static struct clk iva_dpll_hs_clk_div;
> +
> +static struct clk_hw_omap iva_dpll_hs_clk_div_hw = {
> +	.hw = {
> +		.clk = &iva_dpll_hs_clk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(iva_dpll_hs_clk_div, iva_dpll_hs_clk_div_parents,
> +		  c2c_fclk_ops);
> +
> +/* DPLL_IVA */
> +static struct dpll_data dpll_iva_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_IVA,
> +	.clk_bypass	= &iva_dpll_hs_clk_div,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_IVA,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_IVA,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_IVA,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 2047,
> +	.max_divider	= 128,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_iva_ck;
> +
> +static const struct clk_ops dpll_iva_ck_ops = {
> +	.enable		= &omap3_noncore_dpll_enable,
> +	.disable	= &omap3_noncore_dpll_disable,
> +	.recalc_rate	= &omap3_dpll_recalc,
> +	.round_rate	= &omap2_dpll_round_rate,
> +	.set_rate	= &omap3_noncore_dpll_set_rate,
> +	.get_parent	= &omap2_init_dpll_parent,
> +};
> +
> +static struct clk_hw_omap dpll_iva_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_iva_ck,
> +	},
> +	.dpll_data	= &dpll_iva_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_iva_ck, dpll_core_ck_parents, dpll_iva_ck_ops);
> +
> +static const char *dpll_iva_x2_ck_parents[] = {
> +	"dpll_iva_ck",
> +};
> +
> +static struct clk dpll_iva_x2_ck;
> +
> +static struct clk_hw_omap dpll_iva_x2_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_iva_x2_ck,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_iva_x2_ck, dpll_iva_x2_ck_parents, dpll_abe_x2_ck_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_iva_h11x2_ck, "dpll_iva_x2_ck",
> +			    &dpll_iva_x2_ck, 0x0, OMAP54XX_CM_DIV_H11_DPLL_IVA,
> +			    OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_iva_h12x2_ck, "dpll_iva_x2_ck",
> +			    &dpll_iva_x2_ck, 0x0, OMAP54XX_CM_DIV_H12_DPLL_IVA,
> +			    OMAP54XX_DIVHS_MASK);
> +
> +static struct clk mpu_dpll_hs_clk_div;
> +
> +static struct clk_hw_omap mpu_dpll_hs_clk_div_hw = {
> +	.hw = {
> +		.clk = &mpu_dpll_hs_clk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(mpu_dpll_hs_clk_div, iva_dpll_hs_clk_div_parents,
> +		  c2c_fclk_ops);
> +
> +/* DPLL_MPU */
> +static struct dpll_data dpll_mpu_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_MPU,
> +	.clk_bypass	= &mpu_dpll_hs_clk_div,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_MPU,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_MPU,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_MPU,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 2047,
> +	.max_divider	= 128,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_mpu_ck;
> +
> +static struct clk_hw_omap dpll_mpu_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_mpu_ck,
> +	},
> +	.dpll_data	= &dpll_mpu_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_iva_ck_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_MPU,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +DEFINE_CLK_FIXED_FACTOR(per_dpll_hs_clk_div, "dpll_abe_m3x2_ck",
> +			&dpll_abe_m3x2_ck, 0x0, 1, 2);
> +
> +/* DPLL_PER */
> +static struct dpll_data dpll_per_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_PER,
> +	.clk_bypass	= &per_dpll_hs_clk_div,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_PER,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_PER,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_PER,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 2047,
> +	.max_divider	= 128,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_per_ck;
> +
> +static struct clk_hw_omap dpll_per_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_per_ck,
> +	},
> +	.dpll_data	= &dpll_per_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_iva_ck_ops);
> +
> +static const char *dpll_per_x2_ck_parents[] = {
> +	"dpll_per_ck",
> +};
> +
> +static struct clk dpll_per_x2_ck;
> +
> +static struct clk_hw_omap dpll_per_x2_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_per_x2_ck,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_per_x2_ck, dpll_per_x2_ck_parents, dpll_abe_x2_ck_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_h11x2_ck, "dpll_per_x2_ck",
> +			    &dpll_per_x2_ck, 0x0, OMAP54XX_CM_DIV_H11_DPLL_PER,
> +			    OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_h12x2_ck, "dpll_per_x2_ck",
> +			    &dpll_per_x2_ck, 0x0, OMAP54XX_CM_DIV_H12_DPLL_PER,
> +			    OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_h14x2_ck, "dpll_per_x2_ck",
> +			    &dpll_per_x2_ck, 0x0, OMAP54XX_CM_DIV_H14_DPLL_PER,
> +			    OMAP54XX_DIVHS_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_PER,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_m2x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
> +			    0x0, OMAP54XX_CM_DIV_M2_DPLL_PER,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_per_m3x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
> +			    0x0, OMAP54XX_CM_DIV_M3_DPLL_PER,
> +			    OMAP54XX_DIVHS_0_4_MASK);
> +
> +/* DPLL_UNIPRO1 */
> +static struct dpll_data dpll_unipro1_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1,
> +	.clk_bypass	= &sys_clkin,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_UNIPRO1,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 4095,
> +	.max_divider	= 256,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_unipro1_ck;
> +
> +static struct clk_hw_omap dpll_unipro1_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_unipro1_ck,
> +	},
> +	.dpll_data	= &dpll_unipro1_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_unipro1_ck, dpll_core_ck_parents, dpll_iva_ck_ops);
> +
> +static const char *dpll_unipro1_clkdcoldo_parents[] = {
> +	"dpll_unipro1_ck",
> +};
> +
> +static struct clk dpll_unipro1_clkdcoldo;
> +
> +static struct clk_hw_omap dpll_unipro1_clkdcoldo_hw = {
> +	.hw = {
> +		.clk = &dpll_unipro1_clkdcoldo,
> +	},
> +	.clksel_reg	= OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_unipro1_clkdcoldo, dpll_unipro1_clkdcoldo_parents,
> +		  c2c_fclk_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_unipro1_m2_ck, "dpll_unipro1_ck",
> +			    &dpll_unipro1_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1,
> +			    OMAP54XX_DIVHS_0_6_MASK);
> +
> +/* DPLL_UNIPRO2 */
> +static struct dpll_data dpll_unipro2_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2,
> +	.clk_bypass	= &sys_clkin,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_UNIPRO2,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.max_multiplier	= 4095,
> +	.max_divider	= 256,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_unipro2_ck;
> +
> +static struct clk_hw_omap dpll_unipro2_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_unipro2_ck,
> +	},
> +	.dpll_data	= &dpll_unipro2_dd,
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_unipro2_ck, dpll_core_ck_parents, dpll_iva_ck_ops);
> +
> +static const char *dpll_unipro2_clkdcoldo_parents[] = {
> +	"dpll_unipro2_ck",
> +};
> +
> +static struct clk dpll_unipro2_clkdcoldo;
> +
> +static struct clk_hw_omap dpll_unipro2_clkdcoldo_hw = {
> +	.hw = {
> +		.clk = &dpll_unipro2_clkdcoldo,
> +	},
> +	.clksel_reg	= OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_unipro2_clkdcoldo, dpll_unipro2_clkdcoldo_parents,
> +		  c2c_fclk_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_unipro2_m2_ck, "dpll_unipro2_ck",
> +			    &dpll_unipro2_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2,
> +			    OMAP54XX_DIVHS_0_6_MASK);
> +
> +DEFINE_CLK_FIXED_FACTOR(usb_dpll_hs_clk_div, "dpll_abe_m3x2_ck",
> +			&dpll_abe_m3x2_ck, 0x0, 1, 3);
> +
> +/* DPLL_USB */
> +static struct dpll_data dpll_usb_dd = {
> +	.mult_div1_reg	= OMAP54XX_CM_CLKSEL_DPLL_USB,
> +	.clk_bypass	= &usb_dpll_hs_clk_div,
> +	.flags		= DPLL_J_TYPE,
> +	.clk_ref	= &sys_clkin,
> +	.control_reg	= OMAP54XX_CM_CLKMODE_DPLL_USB,
> +	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
> +	.autoidle_reg	= OMAP54XX_CM_AUTOIDLE_DPLL_USB,
> +	.idlest_reg	= OMAP54XX_CM_IDLEST_DPLL_USB,
> +	.mult_mask	= OMAP54XX_DPLL_MULT_MASK,
> +	.div1_mask	= OMAP54XX_DPLL_DIV_MASK,
> +	.enable_mask	= OMAP54XX_DPLL_EN_MASK,
> +	.autoidle_mask	= OMAP54XX_AUTO_DPLL_MODE_MASK,
> +	.idlest_mask	= OMAP54XX_ST_DPLL_CLK_MASK,
> +	.sddiv_mask	= OMAP54XX_DPLL_SD_DIV_MASK,
> +	.max_multiplier	= 4095,
> +	.max_divider	= 256,
> +	.min_divider	= 1,
> +};
> +
> +
> +static struct clk dpll_usb_ck;
> +
> +static const struct clk_ops dpll_usb_ck_ops = {
> +	.enable		= &omap3_noncore_dpll_enable,
> +	.disable	= &omap3_noncore_dpll_disable,
> +	.recalc_rate	= &omap3_dpll_recalc,
> +	.round_rate	= &omap2_dpll_round_rate,
> +	.set_rate	= &omap3_noncore_dpll_set_rate,
> +	.get_parent	= &omap2_init_dpll_parent,
> +	.init	= &omap2_init_clk_clkdm,
> +};
> +
> +static struct clk_hw_omap dpll_usb_ck_hw = {
> +	.hw = {
> +		.clk = &dpll_usb_ck,
> +	},
> +	.dpll_data	= &dpll_usb_dd,
> +	.clkdm_name	= "l3init_clkdm",
> +	.ops		= &clkhwops_omap3_dpll,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_core_ck_parents, dpll_usb_ck_ops);
> +
> +static const char *dpll_usb_clkdcoldo_parents[] = {
> +	"dpll_usb_ck",
> +};
> +
> +static struct clk dpll_usb_clkdcoldo;
> +
> +static struct clk_hw_omap dpll_usb_clkdcoldo_hw = {
> +	.hw = {
> +		.clk = &dpll_usb_clkdcoldo,
> +	},
> +	.clksel_reg	= OMAP54XX_CM_CLKDCOLDO_DPLL_USB,
> +};
> +
> +DEFINE_STRUCT_CLK(dpll_usb_clkdcoldo, dpll_usb_clkdcoldo_parents, c2c_fclk_ops);
> +
> +DEFINE_CLK_OMAP_HSDIVIDER63(dpll_usb_m2_ck, "dpll_usb_ck", &dpll_usb_ck, 0x0,
> +			    OMAP54XX_CM_DIV_M2_DPLL_USB,
> +			    OMAP54XX_DIVHS_0_6_MASK);
> +
> +static const char *dss_syc_gfclk_div_parents[] = {
> +	"sys_clkin",
> +};
> +
> +static struct clk dss_syc_gfclk_div;
> +
> +static struct clk_hw_omap dss_syc_gfclk_div_hw = {
> +	.hw = {
> +		.clk = &dss_syc_gfclk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(dss_syc_gfclk_div, dss_syc_gfclk_div_parents, c2c_fclk_ops);
> +
> +static struct clk l3_iclk_div;
> +
> +static struct clk_hw_omap l3_iclk_div_hw = {
> +	.hw = {
> +		.clk = &l3_iclk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(l3_iclk_div, iva_dpll_hs_clk_div_parents, c2c_fclk_ops);
> +
> +DEFINE_CLK_FIXED_FACTOR(func_128m_clk, "dpll_per_h11x2_ck", &dpll_per_h11x2_ck,
> +			0x0, 1, 2);
> +
> +DEFINE_CLK_FIXED_FACTOR(func_12m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
> +			0x0, 1, 16);
> +
> +DEFINE_CLK_FIXED_FACTOR(func_24m_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1,
> +			4);
> +
> +DEFINE_CLK_FIXED_FACTOR(func_48m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
> +			0x0, 1, 4);
> +
> +DEFINE_CLK_FIXED_FACTOR(func_96m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
> +			0x0, 1, 2);
> +
> +static const char *gpu_core_gclk_mux_parents[] = {
> +	"dpll_core_h14x2_ck", "dpll_per_h14x2_ck",
> +};
> +
> +DEFINE_CLK_MUX(gpu_core_gclk_mux, gpu_core_gclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_GPU_GPU_CLKCTRL, OMAP54XX_CLKSEL_GPU_CORE_GCLK_SHIFT,
> +	       OMAP54XX_CLKSEL_GPU_CORE_GCLK_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(gpu_hyd_gclk_mux, gpu_core_gclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_GPU_GPU_CLKCTRL, OMAP54XX_CLKSEL_GPU_HYD_GCLK_SHIFT,
> +	       OMAP54XX_CLKSEL_GPU_HYD_GCLK_WIDTH, 0x0, NULL);
> +
> +static const char *gpu_l3_iclk_parents[] = {
> +	"l3_iclk_div",
> +};
> +
> +static struct clk gpu_l3_iclk;
> +
> +static struct clk_hw_omap gpu_l3_iclk_hw = {
> +	.hw = {
> +		.clk = &gpu_l3_iclk,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(gpu_l3_iclk, gpu_l3_iclk_parents, c2c_fclk_ops);
> +
> +static const struct clk_div_table l3init_60m_fclk_rates[] = {
> +	{ .div = 1, .val = 0 },
> +	{ .div = 8, .val = 1 },
> +	{ .div = 0 },
> +};
> +DEFINE_CLK_DIVIDER_TABLE(l3init_60m_fclk, "dpll_usb_m2_ck", &dpll_usb_m2_ck,
> +			 0x0, OMAP54XX_CM_CLKSEL_USB_60MHZ,
> +			 OMAP54XX_CLKSEL_0_0_SHIFT, OMAP54XX_CLKSEL_0_0_WIDTH,
> +			 0x0, l3init_60m_fclk_rates, NULL);
> +
> +static const char *wkupaon_iclk_mux_parents[] = {
> +	"sys_clkin", "abe_lp_clk_div",
> +};
> +
> +DEFINE_CLK_MUX(wkupaon_iclk_mux, wkupaon_iclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_CLKSEL_WKUPAON, OMAP54XX_CLKSEL_0_0_SHIFT,
> +	       OMAP54XX_CLKSEL_0_0_WIDTH, 0x0, NULL);
> +
> +static const char *l3instr_ts_gclk_div_parents[] = {
> +	"wkupaon_iclk_mux",
> +};
> +
> +static struct clk l3instr_ts_gclk_div;
> +
> +static struct clk_hw_omap l3instr_ts_gclk_div_hw = {
> +	.hw = {
> +		.clk = &l3instr_ts_gclk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(l3instr_ts_gclk_div, l3instr_ts_gclk_div_parents,
> +		  c2c_fclk_ops);
> +
> +static struct clk l4_root_clk_div;
> +
> +static struct clk_hw_omap l4_root_clk_div_hw = {
> +	.hw = {
> +		.clk = &l4_root_clk_div,
> +	},
> +};
> +
> +DEFINE_STRUCT_CLK(l4_root_clk_div, gpu_l3_iclk_parents, c2c_fclk_ops);
> +
> +DEFINE_CLK_MUX(timer10_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER10_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer11_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER11_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer1_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer2_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER2_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer3_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER3_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer4_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER4_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +static const char *timer5_gfclk_mux_parents[] = {
> +	"dss_syc_gfclk_div", "sys_32k_ck",
> +};
> +
> +DEFINE_CLK_MUX(timer5_gfclk_mux, timer5_gfclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_TIMER5_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer6_gfclk_mux, timer5_gfclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_TIMER6_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer7_gfclk_mux, timer5_gfclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_TIMER7_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer8_gfclk_mux, timer5_gfclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_TIMER8_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(timer9_gfclk_mux, abe_dpll_bypass_clk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L4PER_TIMER9_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +	       OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +/* Leaf clocks controlled by modules */
> +
> +static const char *dss_32khz_clk_parents[] = {
> +	"sys_32k_ck",
> +};
> +
> +static struct clk dss_32khz_clk;
> +
> +static const struct clk_ops dss_32khz_clk_ops = {
> +	.enable		= &omap2_dflt_clk_enable,
> +	.disable	= &omap2_dflt_clk_disable,
> +	.is_enabled	= &omap2_dflt_clk_is_enabled,
> +	.init	= &omap2_init_clk_clkdm,
> +};
> +
> +static struct clk_hw_omap dss_32khz_clk_hw = {
> +	.hw = {
> +		.clk = &dss_32khz_clk,
> +	},
> +	.clkdm_name	= "dss_clkdm",
> +	.enable_reg	= OMAP54XX_CM_DSS_DSS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_32KHZ_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(dss_32khz_clk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *dss_48mhz_clk_parents[] = {
> +	"func_48m_fclk",
> +};
> +
> +static struct clk dss_48mhz_clk;
> +
> +static struct clk_hw_omap dss_48mhz_clk_hw = {
> +	.hw = {
> +		.clk = &dss_48mhz_clk,
> +	},
> +	.clkdm_name	= "dss_clkdm",
> +	.enable_reg	= OMAP54XX_CM_DSS_DSS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_48MHZ_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(dss_48mhz_clk, dss_48mhz_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *dss_dss_clk_parents[] = {
> +	"dpll_per_h12x2_ck",
> +};
> +
> +static struct clk dss_dss_clk;
> +
> +static struct clk_hw_omap dss_dss_clk_hw = {
> +	.hw = {
> +		.clk = &dss_dss_clk,
> +	},
> +	.clkdm_name	= "dss_clkdm",
> +	.enable_reg	= OMAP54XX_CM_DSS_DSS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DSSCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(dss_dss_clk, dss_dss_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *dss_sys_clk_parents[] = {
> +	"dss_syc_gfclk_div",
> +};
> +
> +static struct clk dss_sys_clk;
> +
> +static struct clk_hw_omap dss_sys_clk_hw = {
> +	.hw = {
> +		.clk = &dss_sys_clk,
> +	},
> +	.clkdm_name	= "dss_clkdm",
> +	.enable_reg	= OMAP54XX_CM_DSS_DSS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_SYS_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(dss_sys_clk, dss_sys_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio1_dbclk;
> +
> +static struct clk_hw_omap gpio1_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio1_dbclk,
> +	},
> +	.clkdm_name	= "wkupaon_clkdm",
> +	.enable_reg	= OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio1_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio2_dbclk;
> +
> +static struct clk_hw_omap gpio2_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio2_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO2_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio2_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio3_dbclk;
> +
> +static struct clk_hw_omap gpio3_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio3_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO3_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio3_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio4_dbclk;
> +
> +static struct clk_hw_omap gpio4_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio4_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO4_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio4_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio5_dbclk;
> +
> +static struct clk_hw_omap gpio5_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio5_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO5_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio5_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio6_dbclk;
> +
> +static struct clk_hw_omap gpio6_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio6_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO6_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio6_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio7_dbclk;
> +
> +static struct clk_hw_omap gpio7_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio7_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO7_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio7_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk gpio8_dbclk;
> +
> +static struct clk_hw_omap gpio8_dbclk_hw = {
> +	.hw = {
> +		.clk = &gpio8_dbclk,
> +	},
> +	.clkdm_name	= "l4per_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L4PER_GPIO8_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_DBCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(gpio8_dbclk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *iss_ctrlclk_parents[] = {
> +	"func_96m_fclk",
> +};
> +
> +static struct clk iss_ctrlclk;
> +
> +static struct clk_hw_omap iss_ctrlclk_hw = {
> +	.hw = {
> +		.clk = &iss_ctrlclk,
> +	},
> +	.clkdm_name	= "cam_clkdm",
> +	.enable_reg	= OMAP54XX_CM_CAM_ISS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_CTRLCLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(iss_ctrlclk, iss_ctrlclk_parents, dss_32khz_clk_ops);
> +
> +static const char *lli_txphy_clk_parents[] = {
> +	"dpll_unipro1_clkdcoldo",
> +};
> +
> +static struct clk lli_txphy_clk;
> +
> +static struct clk_hw_omap lli_txphy_clk_hw = {
> +	.hw = {
> +		.clk = &lli_txphy_clk,
> +	},
> +	.clkdm_name	= "mipiext_clkdm",
> +	.enable_reg	= OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_TXPHY_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(lli_txphy_clk, lli_txphy_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *lli_txphy_ls_clk_parents[] = {
> +	"dpll_unipro1_m2_ck",
> +};
> +
> +static struct clk lli_txphy_ls_clk;
> +
> +static struct clk_hw_omap lli_txphy_ls_clk_hw = {
> +	.hw = {
> +		.clk = &lli_txphy_ls_clk,
> +	},
> +	.clkdm_name	= "mipiext_clkdm",
> +	.enable_reg	= OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(lli_txphy_ls_clk, lli_txphy_ls_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static struct clk mmc1_32khz_clk;
> +
> +static struct clk_hw_omap mmc1_32khz_clk_hw = {
> +	.hw = {
> +		.clk = &mmc1_32khz_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_MMC1_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(mmc1_32khz_clk, dss_32khz_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk sata_ref_clk;
> +
> +static struct clk_hw_omap sata_ref_clk_hw = {
> +	.hw = {
> +		.clk = &sata_ref_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_SATA_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_REF_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(sata_ref_clk, dss_syc_gfclk_div_parents, dss_32khz_clk_ops);
> +
> +static const char *slimbus1_slimbus_clk_parents[] = {
> +	"slimbus_clk",
> +};
> +
> +static struct clk slimbus1_slimbus_clk;
> +
> +static struct clk_hw_omap slimbus1_slimbus_clk_hw = {
> +	.hw = {
> +		.clk = &slimbus1_slimbus_clk,
> +	},
> +	.clkdm_name	= "abe_clkdm",
> +	.enable_reg	= OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(slimbus1_slimbus_clk, slimbus1_slimbus_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static const char *usb_host_hs_hsic480m_p1_clk_parents[] = {
> +	"dpll_usb_m2_ck",
> +};
> +
> +static struct clk usb_host_hs_hsic480m_p1_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic480m_p1_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic480m_p1_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic480m_p1_clk,
> +		  usb_host_hs_hsic480m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk usb_host_hs_hsic480m_p2_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic480m_p2_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic480m_p2_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic480m_p2_clk,
> +		  usb_host_hs_hsic480m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk usb_host_hs_hsic480m_p3_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic480m_p3_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic480m_p3_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic480m_p3_clk,
> +		  usb_host_hs_hsic480m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *usb_host_hs_hsic60m_p1_clk_parents[] = {
> +	"l3init_60m_fclk",
> +};
> +
> +static struct clk usb_host_hs_hsic60m_p1_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic60m_p1_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic60m_p1_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic60m_p1_clk,
> +		  usb_host_hs_hsic60m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk usb_host_hs_hsic60m_p2_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic60m_p2_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic60m_p2_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic60m_p2_clk,
> +		  usb_host_hs_hsic60m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static struct clk usb_host_hs_hsic60m_p3_clk;
> +
> +static struct clk_hw_omap usb_host_hs_hsic60m_p3_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_hsic60m_p3_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_hsic60m_p3_clk,
> +		  usb_host_hs_hsic60m_p1_clk_parents, dss_32khz_clk_ops);
> +
> +static const char *utmi_p1_gfclk_parents[] = {
> +	"l3init_60m_fclk", "xclk60mhsp1",
> +};
> +
> +DEFINE_CLK_MUX(utmi_p1_gfclk, utmi_p1_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	       OMAP54XX_CLKSEL_UTMI_P1_SHIFT, OMAP54XX_CLKSEL_UTMI_P1_WIDTH,
> +	       0x0, NULL);
> +
> +static const char *usb_host_hs_utmi_p1_clk_parents[] = {
> +	"utmi_p1_gfclk",
> +};
> +
> +static struct clk usb_host_hs_utmi_p1_clk;
> +
> +static struct clk_hw_omap usb_host_hs_utmi_p1_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_utmi_p1_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_utmi_p1_clk, usb_host_hs_utmi_p1_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static const char *utmi_p2_gfclk_parents[] = {
> +	"l3init_60m_fclk", "xclk60mhsp2",
> +};
> +
> +DEFINE_CLK_MUX(utmi_p2_gfclk, utmi_p2_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	       OMAP54XX_CLKSEL_UTMI_P2_SHIFT, OMAP54XX_CLKSEL_UTMI_P2_WIDTH,
> +	       0x0, NULL);
> +
> +static const char *usb_host_hs_utmi_p2_clk_parents[] = {
> +	"utmi_p2_gfclk",
> +};
> +
> +static struct clk usb_host_hs_utmi_p2_clk;
> +
> +static struct clk_hw_omap usb_host_hs_utmi_p2_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_utmi_p2_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_utmi_p2_clk, usb_host_hs_utmi_p2_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static struct clk usb_host_hs_utmi_p3_clk;
> +
> +static struct clk_hw_omap usb_host_hs_utmi_p3_clk_hw = {
> +	.hw = {
> +		.clk = &usb_host_hs_utmi_p3_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_host_hs_utmi_p3_clk, usb_host_hs_hsic60m_p1_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static const char *usb_otg_ss_refclk960m_parents[] = {
> +	"dpll_usb_clkdcoldo",
> +};
> +
> +static struct clk usb_otg_ss_refclk960m;
> +
> +static struct clk_hw_omap usb_otg_ss_refclk960m_hw = {
> +	.hw = {
> +		.clk = &usb_otg_ss_refclk960m,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_REFCLK960M_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_otg_ss_refclk960m, usb_otg_ss_refclk960m_parents,
> +		  dss_32khz_clk_ops);
> +
> +static struct clk usb_tll_hs_usb_ch0_clk;
> +
> +static struct clk_hw_omap usb_tll_hs_usb_ch0_clk_hw = {
> +	.hw = {
> +		.clk = &usb_tll_hs_usb_ch0_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_USB_CH0_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_tll_hs_usb_ch0_clk, usb_host_hs_hsic60m_p1_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static struct clk usb_tll_hs_usb_ch1_clk;
> +
> +static struct clk_hw_omap usb_tll_hs_usb_ch1_clk_hw = {
> +	.hw = {
> +		.clk = &usb_tll_hs_usb_ch1_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_USB_CH1_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_tll_hs_usb_ch1_clk, usb_host_hs_hsic60m_p1_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +static struct clk usb_tll_hs_usb_ch2_clk;
> +
> +static struct clk_hw_omap usb_tll_hs_usb_ch2_clk_hw = {
> +	.hw = {
> +		.clk = &usb_tll_hs_usb_ch2_clk,
> +	},
> +	.clkdm_name	= "l3init_clkdm",
> +	.enable_reg	= OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL,
> +	.enable_bit	= OMAP54XX_OPTFCLKEN_USB_CH2_CLK_SHIFT,
> +};
> +
> +DEFINE_STRUCT_CLK(usb_tll_hs_usb_ch2_clk, usb_host_hs_hsic60m_p1_clk_parents,
> +		  dss_32khz_clk_ops);
> +
> +/* Remaining optional clocks */
> +DEFINE_CLK_DIVIDER(aess_fclk, "abe_clk", &abe_clk, 0x0,
> +		   OMAP54XX_CM_ABE_AESS_CLKCTRL,
> +		   OMAP54XX_CLKSEL_AESS_FCLK_SHIFT,
> +		   OMAP54XX_CLKSEL_AESS_FCLK_WIDTH, 0x0, NULL);
> +
> +static const char *dmic_sync_mux_ck_parents[] = {
> +	"abe_24m_fclk", "dss_syc_gfclk_div", "func_24m_clk",
> +};
> +
> +DEFINE_CLK_MUX(dmic_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_DMIC_CLKCTRL,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *dmic_gfclk_parents[] = {
> +	"dmic_sync_mux_ck", "pad_clks", "slimbus_clk",
> +};
> +
> +DEFINE_CLK_MUX(dmic_gfclk, dmic_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_DMIC_CLKCTRL, OMAP54XX_CLKSEL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_DIVIDER(fdif_fclk, "dpll_per_h11x2_ck", &dpll_per_h11x2_ck, 0x0,
> +		   OMAP54XX_CM_CAM_FDIF_CLKCTRL, OMAP54XX_CLKSEL_FCLK_SHIFT,
> +		   OMAP54XX_CLKSEL_FCLK_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_DIVIDER(hsi_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0,
> +		   OMAP54XX_CM_L3INIT_HSI_CLKCTRL, OMAP54XX_CLKSEL_SHIFT,
> +		   OMAP54XX_CLKSEL_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCASP_CLKCTRL,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *mcasp_gfclk_parents[] = {
> +	"mcasp_sync_mux_ck", "pad_clks", "slimbus_clk",
> +};
> +
> +DEFINE_CLK_MUX(mcasp_gfclk, mcasp_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCASP_CLKCTRL, OMAP54XX_CLKSEL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP1_CLKCTRL,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *mcbsp1_gfclk_parents[] = {
> +	"mcbsp1_sync_mux_ck", "pad_clks", "slimbus_clk",
> +};
> +
> +DEFINE_CLK_MUX(mcbsp1_gfclk, mcbsp1_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP1_CLKCTRL, OMAP54XX_CLKSEL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP2_CLKCTRL,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *mcbsp2_gfclk_parents[] = {
> +	"mcbsp2_sync_mux_ck", "pad_clks", "slimbus_clk",
> +};
> +
> +DEFINE_CLK_MUX(mcbsp2_gfclk, mcbsp2_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP2_CLKCTRL, OMAP54XX_CLKSEL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP3_CLKCTRL,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *mcbsp3_gfclk_parents[] = {
> +	"mcbsp3_sync_mux_ck", "pad_clks", "slimbus_clk",
> +};
> +
> +DEFINE_CLK_MUX(mcbsp3_gfclk, mcbsp3_gfclk_parents, NULL, 0x0,
> +	       OMAP54XX_CM_ABE_MCBSP3_CLKCTRL, OMAP54XX_CLKSEL_SOURCE_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_WIDTH, 0x0, NULL);
> +
> +static const char *mmc1_fclk_mux_parents[] = {
> +	"func_128m_clk", "dpll_per_m2x2_ck",
> +};
> +
> +DEFINE_CLK_MUX(mmc1_fclk_mux, mmc1_fclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L3INIT_MMC1_CLKCTRL,
> +	       OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_DIVIDER(mmc1_fclk, "mmc1_fclk_mux", &mmc1_fclk_mux, 0x0,
> +		   OMAP54XX_CM_L3INIT_MMC1_CLKCTRL, OMAP54XX_CLKSEL_DIV_SHIFT,
> +		   OMAP54XX_CLKSEL_DIV_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_MUX(mmc2_fclk_mux, mmc1_fclk_mux_parents, NULL, 0x0,
> +	       OMAP54XX_CM_L3INIT_MMC2_CLKCTRL,
> +	       OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_SHIFT,
> +	       OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_WIDTH, 0x0, NULL);
> +
> +DEFINE_CLK_DIVIDER(mmc2_fclk, "mmc2_fclk_mux", &mmc2_fclk_mux, 0x0,
> +		   OMAP54XX_CM_L3INIT_MMC2_CLKCTRL, OMAP54XX_CLKSEL_DIV_SHIFT,
> +		   OMAP54XX_CLKSEL_DIV_WIDTH, 0x0, NULL);
> +
> +/* SCRM aux clk nodes */
> +
> +static const struct clksel auxclk_src_sel[] = {
> +	{ .parent = &sys_clkin, .rates = div_1_0_rates },
> +	{ .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
> +	{ .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
> +	{ .parent = NULL },
> +};
> +
> +static const char *auxclk_src_ck_parents[] = {
> +	"sys_clkin", "dpll_core_m3x2_ck", "dpll_per_m3x2_ck",
> +};
> +
> +static const struct clk_ops auxclk_src_ck_ops = {
> +	.enable		= &omap2_dflt_clk_enable,
> +	.disable	= &omap2_dflt_clk_disable,
> +	.is_enabled	= &omap2_dflt_clk_is_enabled,
> +	.recalc_rate	= &omap2_clksel_recalc,
> +	.get_parent	= &omap2_clksel_find_parent_index,
> +};
> +
> +DEFINE_CLK_OMAP_MUX_GATE(auxclk0_src_ck, NULL, auxclk_src_sel,
> +			 OMAP5_SCRM_AUXCLK0, OMAP5_SRCSELECT_MASK,
> +			 OMAP5_SCRM_AUXCLK0, OMAP5_ENABLE_SHIFT, NULL,
> +			 auxclk_src_ck_parents, auxclk_src_ck_ops);
> +
> +DEFINE_CLK_DIVIDER(auxclk0_ck, "auxclk0_src_ck", &auxclk0_src_ck, 0x0,
> +		   OMAP5_SCRM_AUXCLK0, OMAP5_CLKDIV_SHIFT, OMAP5_CLKDIV_WIDTH,
> +		   0x0, NULL);
> +
> +DEFINE_CLK_OMAP_MUX_GATE(auxclk1_src_ck, NULL, auxclk_src_sel,
> +			 OMAP5_SCRM_AUXCLK1, OMAP5_SRCSELECT_MASK,
> +			 OMAP5_SCRM_AUXCLK1, OMAP5_ENABLE_SHIFT, NULL,
> +			 auxclk_src_ck_parents, auxclk_src_ck_ops);
> +
> +DEFINE_CLK_DIVIDER(auxclk1_ck, "auxclk1_src_ck", &auxclk1_src_ck, 0x0,
> +		   OMAP5_SCRM_AUXCLK1, OMAP5_CLKDIV_SHIFT, OMAP5_CLKDIV_WIDTH,
> +		   0x0, NULL);
> +
> +DEFINE_CLK_OMAP_MUX_GATE(auxclk2_src_ck, NULL, auxclk_src_sel,
> +			 OMAP5_SCRM_AUXCLK2, OMAP5_SRCSELECT_MASK,
> +			 OMAP5_SCRM_AUXCLK2, OMAP5_ENABLE_SHIFT, NULL,
> +			 auxclk_src_ck_parents, auxclk_src_ck_ops);
> +
> +DEFINE_CLK_DIVIDER(auxclk2_ck, "auxclk2_src_ck", &auxclk2_src_ck, 0x0,
> +		   OMAP5_SCRM_AUXCLK2, OMAP5_CLKDIV_SHIFT, OMAP5_CLKDIV_WIDTH,
> +		   0x0, NULL);
> +
> +DEFINE_CLK_OMAP_MUX_GATE(auxclk3_src_ck, NULL, auxclk_src_sel,
> +			 OMAP5_SCRM_AUXCLK3, OMAP5_SRCSELECT_MASK,
> +			 OMAP5_SCRM_AUXCLK3, OMAP5_ENABLE_SHIFT, NULL,
> +			 auxclk_src_ck_parents, auxclk_src_ck_ops);
> +
> +DEFINE_CLK_DIVIDER(auxclk3_ck, "auxclk3_src_ck", &auxclk3_src_ck, 0x0,
> +		   OMAP5_SCRM_AUXCLK3, OMAP5_CLKDIV_SHIFT, OMAP5_CLKDIV_WIDTH,
> +		   0x0, NULL);
> +
> +static const char *auxclkreq_ck_parents[] = {
> +	"auxclk0_ck", "auxclk1_ck", "auxclk2_ck", "auxclk3_ck", "auxclk4_ck",
> +	"auxclk5_ck",
> +};
> +
> +DEFINE_CLK_MUX(auxclkreq0_ck, auxclkreq_ck_parents, NULL, 0x0,
> +	       OMAP5_SCRM_AUXCLKREQ0, OMAP5_MAPPING_SHIFT, OMAP5_MAPPING_WIDTH,
> +	       0x0, NULL);
> +
> +DEFINE_CLK_MUX(auxclkreq1_ck, auxclkreq_ck_parents, NULL, 0x0,
> +	       OMAP5_SCRM_AUXCLKREQ1, OMAP5_MAPPING_SHIFT, OMAP5_MAPPING_WIDTH,
> +	       0x0, NULL);
> +
> +DEFINE_CLK_MUX(auxclkreq2_ck, auxclkreq_ck_parents, NULL, 0x0,
> +	       OMAP5_SCRM_AUXCLKREQ2, OMAP5_MAPPING_SHIFT, OMAP5_MAPPING_WIDTH,
> +	       0x0, NULL);
> +
> +DEFINE_CLK_MUX(auxclkreq3_ck, auxclkreq_ck_parents, NULL, 0x0,
> +	       OMAP5_SCRM_AUXCLKREQ3, OMAP5_MAPPING_SHIFT, OMAP5_MAPPING_WIDTH,
> +	       0x0, NULL);
> +
> +/*
> + * clkdev
> + */
> +
> +static struct omap_clk omap54xx_clks[] = {
> +	CLK(NULL,	"pad_clks_src_ck",		&pad_clks_src_ck,	CK_54XX),
> +	CLK(NULL,	"pad_clks_ck",			&pad_clks_ck,	CK_54XX),
> +	CLK(NULL,	"secure_32k_clk_src_ck",	&secure_32k_clk_src_ck,	CK_54XX),
> +	CLK(NULL,	"slimbus_src_clk",		&slimbus_src_clk,	CK_54XX),
> +	CLK(NULL,	"slimbus_clk",			&slimbus_clk,	CK_54XX),
> +	CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_54XX),
> +	CLK(NULL,	"virt_12000000_ck",		&virt_12000000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_13000000_ck",		&virt_13000000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_16800000_ck",		&virt_16800000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_19200000_ck",		&virt_19200000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_26000000_ck",		&virt_26000000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_27000000_ck",		&virt_27000000_ck,	CK_54XX),
> +	CLK(NULL,	"virt_38400000_ck",		&virt_38400000_ck,	CK_54XX),
> +	CLK(NULL,	"sys_clkin",			&sys_clkin,	CK_54XX),
> +	CLK(NULL,	"xclk60mhsp1_ck",		&xclk60mhsp1_ck,	CK_54XX),
> +	CLK(NULL,	"xclk60mhsp2_ck",		&xclk60mhsp2_ck,	CK_54XX),
> +	CLK(NULL,	"abe_dpll_bypass_clk_mux",	&abe_dpll_bypass_clk_mux,	CK_54XX),
> +	CLK(NULL,	"abe_dpll_clk_mux",		&abe_dpll_clk_mux,	CK_54XX),
> +	CLK(NULL,	"dpll_abe_ck",			&dpll_abe_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_abe_x2_ck",		&dpll_abe_x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_abe_m2x2_ck",		&dpll_abe_m2x2_ck,	CK_54XX),
> +	CLK(NULL,	"abe_24m_fclk",			&abe_24m_fclk,	CK_54XX),
> +	CLK(NULL,	"abe_clk",			&abe_clk,	CK_54XX),
> +	CLK(NULL,	"abe_iclk",			&abe_iclk,	CK_54XX),
> +	CLK(NULL,	"abe_lp_clk_div",		&abe_lp_clk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_abe_m3x2_ck",		&dpll_abe_m3x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_ck",			&dpll_core_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_x2_ck",		&dpll_core_x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h21x2_ck",		&dpll_core_h21x2_ck,	CK_54XX),
> +	CLK(NULL,	"c2c_fclk",			&c2c_fclk,	CK_54XX),
> +	CLK(NULL,	"c2c_iclk",			&c2c_iclk,	CK_54XX),
> +	CLK(NULL,	"custefuse_sys_gfclk_div",	&custefuse_sys_gfclk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h11x2_ck",		&dpll_core_h11x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h12x2_ck",		&dpll_core_h12x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h13x2_ck",		&dpll_core_h13x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h14x2_ck",		&dpll_core_h14x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h22x2_ck",		&dpll_core_h22x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h23x2_ck",		&dpll_core_h23x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_h24x2_ck",		&dpll_core_h24x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_m2_ck",		&dpll_core_m2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_core_m3x2_ck",		&dpll_core_m3x2_ck,	CK_54XX),
> +	CLK(NULL,	"iva_dpll_hs_clk_div",		&iva_dpll_hs_clk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_iva_ck",			&dpll_iva_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_iva_x2_ck",		&dpll_iva_x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_iva_h11x2_ck",		&dpll_iva_h11x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_iva_h12x2_ck",		&dpll_iva_h12x2_ck,	CK_54XX),
> +	CLK(NULL,	"mpu_dpll_hs_clk_div",		&mpu_dpll_hs_clk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_mpu_ck",			&dpll_mpu_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_mpu_m2_ck",		&dpll_mpu_m2_ck,	CK_54XX),
> +	CLK(NULL,	"per_dpll_hs_clk_div",		&per_dpll_hs_clk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_per_ck",			&dpll_per_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_x2_ck",		&dpll_per_x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_h11x2_ck",		&dpll_per_h11x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_h12x2_ck",		&dpll_per_h12x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_h14x2_ck",		&dpll_per_h14x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_m2_ck",		&dpll_per_m2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_m2x2_ck",		&dpll_per_m2x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_per_m3x2_ck",		&dpll_per_m3x2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro1_ck",		&dpll_unipro1_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro1_clkdcoldo",	&dpll_unipro1_clkdcoldo,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro1_m2_ck",		&dpll_unipro1_m2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro2_ck",		&dpll_unipro2_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro2_clkdcoldo",	&dpll_unipro2_clkdcoldo,	CK_54XX),
> +	CLK(NULL,	"dpll_unipro2_m2_ck",		&dpll_unipro2_m2_ck,	CK_54XX),
> +	CLK(NULL,	"usb_dpll_hs_clk_div",		&usb_dpll_hs_clk_div,	CK_54XX),
> +	CLK(NULL,	"dpll_usb_ck",			&dpll_usb_ck,	CK_54XX),
> +	CLK(NULL,	"dpll_usb_clkdcoldo",		&dpll_usb_clkdcoldo,	CK_54XX),
> +	CLK(NULL,	"dpll_usb_m2_ck",		&dpll_usb_m2_ck,	CK_54XX),
> +	CLK(NULL,	"dss_syc_gfclk_div",		&dss_syc_gfclk_div,	CK_54XX),
> +	CLK(NULL,	"l3_iclk_div",			&l3_iclk_div,	CK_54XX),
> +	CLK(NULL,	"func_128m_clk",		&func_128m_clk,	CK_54XX),
> +	CLK(NULL,	"func_12m_fclk",		&func_12m_fclk,	CK_54XX),
> +	CLK(NULL,	"func_24m_clk",			&func_24m_clk,	CK_54XX),
> +	CLK(NULL,	"func_48m_fclk",		&func_48m_fclk,	CK_54XX),
> +	CLK(NULL,	"func_96m_fclk",		&func_96m_fclk,	CK_54XX),
> +	CLK(NULL,	"gpu_core_gclk_mux",		&gpu_core_gclk_mux,	CK_54XX),
> +	CLK(NULL,	"gpu_hyd_gclk_mux",		&gpu_hyd_gclk_mux,	CK_54XX),
> +	CLK(NULL,	"gpu_l3_iclk",			&gpu_l3_iclk,	CK_54XX),
> +	CLK(NULL,	"l3init_60m_fclk",		&l3init_60m_fclk,	CK_54XX),
> +	CLK(NULL,	"wkupaon_iclk_mux",		&wkupaon_iclk_mux,	CK_54XX),
> +	CLK(NULL,	"l3instr_ts_gclk_div",		&l3instr_ts_gclk_div,	CK_54XX),
> +	CLK(NULL,	"l4_root_clk_div",		&l4_root_clk_div,	CK_54XX),
> +	CLK(NULL,	"timer10_gfclk_mux",		&timer10_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer11_gfclk_mux",		&timer11_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer1_gfclk_mux",		&timer1_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer2_gfclk_mux",		&timer2_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer3_gfclk_mux",		&timer3_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer4_gfclk_mux",		&timer4_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer5_gfclk_mux",		&timer5_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer6_gfclk_mux",		&timer6_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer7_gfclk_mux",		&timer7_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer8_gfclk_mux",		&timer8_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"timer9_gfclk_mux",		&timer9_gfclk_mux,	CK_54XX),
> +	CLK(NULL,	"dss_32khz_clk",		&dss_32khz_clk,	CK_54XX),
> +	CLK(NULL,	"dss_48mhz_clk",		&dss_48mhz_clk,	CK_54XX),
> +	CLK(NULL,	"dss_dss_clk",			&dss_dss_clk,	CK_54XX),
> +	CLK(NULL,	"dss_sys_clk",			&dss_sys_clk,	CK_54XX),
> +	CLK(NULL,	"gpio1_dbclk",			&gpio1_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio2_dbclk",			&gpio2_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio3_dbclk",			&gpio3_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio4_dbclk",			&gpio4_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio5_dbclk",			&gpio5_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio6_dbclk",			&gpio6_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio7_dbclk",			&gpio7_dbclk,	CK_54XX),
> +	CLK(NULL,	"gpio8_dbclk",			&gpio8_dbclk,	CK_54XX),
> +	CLK(NULL,	"iss_ctrlclk",			&iss_ctrlclk,	CK_54XX),
> +	CLK(NULL,	"lli_txphy_clk",		&lli_txphy_clk,	CK_54XX),
> +	CLK(NULL,	"lli_txphy_ls_clk",		&lli_txphy_ls_clk,	CK_54XX),
> +	CLK(NULL,	"mmc1_32khz_clk",		&mmc1_32khz_clk,	CK_54XX),
> +	CLK(NULL,	"sata_ref_clk",			&sata_ref_clk,	CK_54XX),
> +	CLK(NULL,	"slimbus1_slimbus_clk",		&slimbus1_slimbus_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic480m_p1_clk",	&usb_host_hs_hsic480m_p1_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic480m_p2_clk",	&usb_host_hs_hsic480m_p2_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic480m_p3_clk",	&usb_host_hs_hsic480m_p3_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic60m_p1_clk",	&usb_host_hs_hsic60m_p1_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic60m_p2_clk",	&usb_host_hs_hsic60m_p2_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_hsic60m_p3_clk",	&usb_host_hs_hsic60m_p3_clk,	CK_54XX),
> +	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&usb_host_hs_utmi_p1_clk,	CK_54XX),
> +	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&usb_host_hs_utmi_p2_clk,	CK_54XX),
> +	CLK(NULL,	"usb_host_hs_utmi_p3_clk",	&usb_host_hs_utmi_p3_clk,	CK_54XX),
> +	CLK(NULL,	"usb_otg_ss_refclk960m",	&usb_otg_ss_refclk960m,	CK_54XX),
> +	CLK(NULL,	"usb_tll_hs_usb_ch0_clk",	&usb_tll_hs_usb_ch0_clk,	CK_54XX),
> +	CLK(NULL,	"usb_tll_hs_usb_ch1_clk",	&usb_tll_hs_usb_ch1_clk,	CK_54XX),
> +	CLK(NULL,	"usb_tll_hs_usb_ch2_clk",	&usb_tll_hs_usb_ch2_clk,	CK_54XX),
> +	CLK(NULL,	"aess_fclk",			&aess_fclk,	CK_54XX),
> +	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_54XX),
> +	CLK(NULL,	"dmic_gfclk",			&dmic_gfclk,	CK_54XX),
> +	CLK(NULL,	"fdif_fclk",			&fdif_fclk,	CK_54XX),
> +	CLK(NULL,	"hsi_fclk",			&hsi_fclk,	CK_54XX),
> +	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_54XX),
> +	CLK(NULL,	"mcasp_gfclk",			&mcasp_gfclk,	CK_54XX),
> +	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_54XX),
> +	CLK(NULL,	"mcbsp1_gfclk",			&mcbsp1_gfclk,	CK_54XX),
> +	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_54XX),
> +	CLK(NULL,	"mcbsp2_gfclk",			&mcbsp2_gfclk,	CK_54XX),
> +	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_54XX),
> +	CLK(NULL,	"mcbsp3_gfclk",			&mcbsp3_gfclk,	CK_54XX),
> +	CLK(NULL,	"mmc1_fclk_mux",		&mmc1_fclk_mux,	CK_54XX),
> +	CLK(NULL,	"mmc1_fclk",			&mmc1_fclk,	CK_54XX),
> +	CLK(NULL,	"mmc2_fclk_mux",		&mmc2_fclk_mux,	CK_54XX),
> +	CLK(NULL,	"mmc2_fclk",			&mmc2_fclk,	CK_54XX),
> +	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_54XX),
> +	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_54XX),
> +	CLK(NULL,	"auxclk0_src_ck",		&auxclk0_src_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk0_ck",			&auxclk0_ck,	CK_54XX),
> +	CLK(NULL,	"auxclkreq0_ck",		&auxclkreq0_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk1_src_ck",		&auxclk1_src_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk1_ck",			&auxclk1_ck,	CK_54XX),
> +	CLK(NULL,	"auxclkreq1_ck",		&auxclkreq1_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk2_src_ck",		&auxclk2_src_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk2_ck",			&auxclk2_ck,	CK_54XX),
> +	CLK(NULL,	"auxclkreq2_ck",		&auxclkreq2_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk3_src_ck",		&auxclk3_src_ck,	CK_54XX),
> +	CLK(NULL,	"auxclk3_ck",			&auxclk3_ck,	CK_54XX),
> +	CLK(NULL,	"auxclkreq3_ck",		&auxclkreq3_ck,	CK_54XX),
> +	CLK(NULL,	"gpmc_ck",			&dummy_ck,	CK_54XX),
> +	CLK("omap_i2c.1",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_i2c.2",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_i2c.3",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_i2c.4",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK(NULL,	"mailboxes_ick",		&dummy_ck,	CK_54XX),
> +	CLK("omap_hsmmc.0",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_hsmmc.1",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_hsmmc.2",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_hsmmc.3",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap_hsmmc.4",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap-mcbsp.1",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap-mcbsp.2",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap-mcbsp.3",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap-mcbsp.4",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap2_mcspi.1",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap2_mcspi.2",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap2_mcspi.3",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK("omap2_mcspi.4",	"ick",			&dummy_ck,	CK_54XX),
> +	CLK(NULL,	"uart1_ick",			&dummy_ck,	CK_54XX),
> +	CLK(NULL,	"uart2_ick",			&dummy_ck,	CK_54XX),
> +	CLK(NULL,	"uart3_ick",			&dummy_ck,	CK_54XX),
> +	CLK(NULL,	"uart4_ick",			&dummy_ck,	CK_54XX),
> +	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,	CK_54XX),
> +	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_54XX),
> +	CLK("omap_wdt",	"ick",				&dummy_ck,	CK_54XX),
> +	CLK("omap_timer.1",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.2",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.3",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.4",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.5",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.6",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.7",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.8",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.9",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.10",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.11",	"32k_ck",		&sys_32k_ck,	CK_54XX),
> +	CLK("omap_timer.1",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.2",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.3",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.4",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.9",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.10",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.11",	"sys_ck",		&sys_clkin,	CK_54XX),
> +	CLK("omap_timer.5",	"sys_ck",		&dss_syc_gfclk_div,	CK_54XX),
> +	CLK("omap_timer.6",	"sys_ck",		&dss_syc_gfclk_div,	CK_54XX),
> +	CLK("omap_timer.7",	"sys_ck",		&dss_syc_gfclk_div,	CK_54XX),
> +	CLK("omap_timer.8",	"sys_ck",		&dss_syc_gfclk_div,	CK_54XX),
> +};
> +
> +int __init omap5xxx_clk_init(void)
> +{
> +	u32 cpu_clkflg;
> +	struct omap_clk *c;
> +
> +	if (soc_is_omap54xx()) {
> +		cpu_mask = RATE_IN_54XX;
> +		cpu_clkflg = CK_54XX;
> +	}
> +
> +	/*
> +	 * Must stay commented until all OMAP SoC drivers are
> +	 * converted to runtime PM, or drivers may start crashing
> +	 *
> +	 * omap2_clk_disable_clkdm_control();
> +	 */
> +
> +	for (c = omap54xx_clks; c < omap54xx_clks + ARRAY_SIZE(omap54xx_clks);
> +									c++) {
> +		if (c->cpu & cpu_clkflg) {
> +			clkdev_add(&c->lk);
> +			if (!__clk_init(NULL, c->lk.clk))
> +				omap2_init_clk_hw_omap_clocks(c->lk.clk);
> +		}
> +	}
> +
> +	omap2_clk_disable_autoidle_all();

Can we add the ABE DPLL locking on 32kHz  here like for OMAP4. Otherwise 
we will get the same problem

	/*
	 * Lock the ABE DPLL in any case to avoid issues with audio.
	 */
	rc = clk_set_parent(&abe_dpll_clk_mux, &sys_32k_ck);
	if (!rc)
		rc = clk_set_rate(&dpll_abe_ck, OMAP4_DPLL_ABE_DEFFREQ);
	if (rc)
		pr_err("%s: failed to configure ABE DPLL!\n", __func__);



> +
> +	return 0;
> +}
> diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
> index b402048..836311f 100644
> --- a/arch/arm/mach-omap2/clock.h
> +++ b/arch/arm/mach-omap2/clock.h
> @@ -48,6 +48,7 @@ struct omap_clk {
>   #define CK_TI816X	(1 << 7)
>   #define CK_446X		(1 << 8)
>   #define CK_AM33XX	(1 << 9)	/* AM33xx specific clocks */
> +#define CK_54XX		(1 << 10)	/* OMAP54xx specific clocks */
>
>
>   #define CK_34XX		(CK_3430ES1 | CK_3430ES2PLUS)
> @@ -107,13 +108,31 @@ struct clockdomain;
>   	};							\
>   	DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
>
> +
> +#define DEFINE_CLK_OMAP_HSDIVIDER63(_name, _parent_name,	\
> +				_parent_ptr, _flags,		\
> +				_clksel_reg, _clksel_mask)	\
> +								\
> +	_DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
> +				_parent_ptr, _flags,		\
> +				_clksel_reg, _clksel_mask, 63)
> +
>   #define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
>   				_parent_ptr, _flags,		\
>   				_clksel_reg, _clksel_mask)	\
> +								\
> +	_DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
> +				_parent_ptr, _flags,		\
> +				_clksel_reg, _clksel_mask, 31)
> +
> +
> +#define _DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
> +				_parent_ptr, _flags,		\
> +				_clksel_reg, _clksel_mask, mdiv)\
>   	static const struct clksel _name##_div[] = {		\
>   		{						\
>   			.parent = _parent_ptr,			\
> -			.rates = div31_1to31_rates		\
> +			.rates = div##mdiv##_1to##mdiv##_rates	\
>   		},						\
>   		{ .parent = NULL },				\
>   	};							\
> @@ -143,6 +162,7 @@ struct clockdomain;
>   #define RATE_IN_4460		(1 << 7)
>   #define RATE_IN_AM33XX		(1 << 8)
>   #define RATE_IN_TI814X		(1 << 9)
> +#define RATE_IN_54XX		(1 << 10)
>
>   #define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
>   #define RATE_IN_34XX		(RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
> @@ -463,6 +483,7 @@ extern const struct clksel_rate div_1_2_rates[];
>   extern const struct clksel_rate div_1_3_rates[];
>   extern const struct clksel_rate div_1_4_rates[];
>   extern const struct clksel_rate div31_1to31_rates[];
> +extern const struct clksel_rate div63_1to63_rates[];
>
>   extern int am33xx_clk_init(void);
>
> diff --git a/arch/arm/mach-omap2/clock54xx.h b/arch/arm/mach-omap2/clock54xx.h
> new file mode 100644
> index 0000000..3b09134
> --- /dev/null
> +++ b/arch/arm/mach-omap2/clock54xx.h
> @@ -0,0 +1,12 @@
> +/*
> + * OMAP5 clock function prototypes and macros
> + *
> + * Copyright (C) 2013 Texas Instruments, Inc.
> + */
> +
> +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK54XX_H
> +#define __ARCH_ARM_MACH_OMAP2_CLOCK54XX_H
> +
> +int omap5xxx_clk_init(void);
> +
> +#endif
> diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c
> index ef4d21b..c918efb 100644
> --- a/arch/arm/mach-omap2/clock_common_data.c
> +++ b/arch/arm/mach-omap2/clock_common_data.c
> @@ -49,7 +49,7 @@ const struct clksel_rate dsp_ick_rates[] = {
>   /* clksel_rate blocks shared between OMAP44xx and AM33xx */
>
>   const struct clksel_rate div_1_0_rates[] = {
> -	{ .div = 1, .val = 0, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 0, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
> @@ -61,57 +61,124 @@ const struct clksel_rate div3_1to4_rates[] = {
>   };
>
>   const struct clksel_rate div_1_1_rates[] = {
> -	{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
>   const struct clksel_rate div_1_2_rates[] = {
> -	{ .div = 1, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
>   const struct clksel_rate div_1_3_rates[] = {
> -	{ .div = 1, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
>   const struct clksel_rate div_1_4_rates[] = {
> -	{ .div = 1, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
>   const struct clksel_rate div31_1to31_rates[] = {
> -	{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 2, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 3, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 4, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 5, .val = 5, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 6, .val = 6, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 7, .val = 7, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 8, .val = 8, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 9, .val = 9, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 10, .val = 10, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 11, .val = 11, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 12, .val = 12, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 13, .val = 13, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 14, .val = 14, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 15, .val = 15, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 16, .val = 16, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 17, .val = 17, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 18, .val = 18, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 19, .val = 19, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 20, .val = 20, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 21, .val = 21, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 22, .val = 22, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 23, .val = 23, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 24, .val = 24, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 25, .val = 25, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 26, .val = 26, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 27, .val = 27, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 28, .val = 28, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 29, .val = 29, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 30, .val = 30, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> -	{ .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
> +	{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 2, .val = 2, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 3, .val = 3, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 4, .val = 4, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 5, .val = 5, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 6, .val = 6, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 7, .val = 7, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 8, .val = 8, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 9, .val = 9, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 10, .val = 10, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 11, .val = 11, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 12, .val = 12, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 13, .val = 13, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 14, .val = 14, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 15, .val = 15, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 16, .val = 16, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 17, .val = 17, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 18, .val = 18, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 19, .val = 19, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 20, .val = 20, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 21, .val = 21, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 22, .val = 22, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 23, .val = 23, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 24, .val = 24, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 25, .val = 25, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 26, .val = 26, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 27, .val = 27, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 28, .val = 28, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 29, .val = 29, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 30, .val = 30, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX | RATE_IN_54XX },
> +	{ .div = 0 },
> +};
> +
> +const struct clksel_rate div63_1to63_rates[] = {
> +	{ .div = 1, .val = 1, .flags = RATE_IN_54XX },
> +	{ .div = 2, .val = 2, .flags = RATE_IN_54XX },
> +	{ .div = 3, .val = 3, .flags = RATE_IN_54XX },
> +	{ .div = 4, .val = 4, .flags = RATE_IN_54XX },
> +	{ .div = 5, .val = 5, .flags = RATE_IN_54XX },
> +	{ .div = 6, .val = 6, .flags = RATE_IN_54XX },
> +	{ .div = 7, .val = 7, .flags = RATE_IN_54XX },
> +	{ .div = 8, .val = 8, .flags = RATE_IN_54XX },
> +	{ .div = 9, .val = 9, .flags = RATE_IN_54XX },
> +	{ .div = 10, .val = 10, .flags = RATE_IN_54XX },
> +	{ .div = 11, .val = 11, .flags = RATE_IN_54XX },
> +	{ .div = 12, .val = 12, .flags = RATE_IN_54XX },
> +	{ .div = 13, .val = 13, .flags = RATE_IN_54XX },
> +	{ .div = 14, .val = 14, .flags = RATE_IN_54XX },
> +	{ .div = 15, .val = 15, .flags = RATE_IN_54XX },
> +	{ .div = 16, .val = 16, .flags = RATE_IN_54XX },
> +	{ .div = 17, .val = 17, .flags = RATE_IN_54XX },
> +	{ .div = 18, .val = 18, .flags = RATE_IN_54XX },
> +	{ .div = 19, .val = 19, .flags = RATE_IN_54XX },
> +	{ .div = 20, .val = 20, .flags = RATE_IN_54XX },
> +	{ .div = 21, .val = 21, .flags = RATE_IN_54XX },
> +	{ .div = 22, .val = 22, .flags = RATE_IN_54XX },
> +	{ .div = 23, .val = 23, .flags = RATE_IN_54XX },
> +	{ .div = 24, .val = 24, .flags = RATE_IN_54XX },
> +	{ .div = 25, .val = 25, .flags = RATE_IN_54XX },
> +	{ .div = 26, .val = 26, .flags = RATE_IN_54XX },
> +	{ .div = 27, .val = 27, .flags = RATE_IN_54XX },
> +	{ .div = 28, .val = 28, .flags = RATE_IN_54XX },
> +	{ .div = 29, .val = 29, .flags = RATE_IN_54XX },
> +	{ .div = 30, .val = 30, .flags = RATE_IN_54XX },
> +	{ .div = 31, .val = 31, .flags = RATE_IN_54XX },
> +	{ .div = 32, .val = 32, .flags = RATE_IN_54XX },
> +	{ .div = 33, .val = 33, .flags = RATE_IN_54XX },
> +	{ .div = 34, .val = 34, .flags = RATE_IN_54XX },
> +	{ .div = 35, .val = 35, .flags = RATE_IN_54XX },
> +	{ .div = 36, .val = 36, .flags = RATE_IN_54XX },
> +	{ .div = 37, .val = 37, .flags = RATE_IN_54XX },
> +	{ .div = 38, .val = 38, .flags = RATE_IN_54XX },
> +	{ .div = 39, .val = 39, .flags = RATE_IN_54XX },
> +	{ .div = 40, .val = 40, .flags = RATE_IN_54XX },
> +	{ .div = 41, .val = 41, .flags = RATE_IN_54XX },
> +	{ .div = 42, .val = 42, .flags = RATE_IN_54XX },
> +	{ .div = 43, .val = 43, .flags = RATE_IN_54XX },
> +	{ .div = 44, .val = 44, .flags = RATE_IN_54XX },
> +	{ .div = 45, .val = 45, .flags = RATE_IN_54XX },
> +	{ .div = 46, .val = 46, .flags = RATE_IN_54XX },
> +	{ .div = 47, .val = 47, .flags = RATE_IN_54XX },
> +	{ .div = 48, .val = 48, .flags = RATE_IN_54XX },
> +	{ .div = 49, .val = 49, .flags = RATE_IN_54XX },
> +	{ .div = 50, .val = 50, .flags = RATE_IN_54XX },
> +	{ .div = 51, .val = 51, .flags = RATE_IN_54XX },
> +	{ .div = 52, .val = 52, .flags = RATE_IN_54XX },
> +	{ .div = 53, .val = 53, .flags = RATE_IN_54XX },
> +	{ .div = 54, .val = 54, .flags = RATE_IN_54XX },
> +	{ .div = 55, .val = 55, .flags = RATE_IN_54XX },
> +	{ .div = 56, .val = 56, .flags = RATE_IN_54XX },
> +	{ .div = 57, .val = 57, .flags = RATE_IN_54XX },
> +	{ .div = 58, .val = 58, .flags = RATE_IN_54XX },
> +	{ .div = 59, .val = 59, .flags = RATE_IN_54XX },
> +	{ .div = 60, .val = 60, .flags = RATE_IN_54XX },
> +	{ .div = 61, .val = 61, .flags = RATE_IN_54XX },
> +	{ .div = 62, .val = 62, .flags = RATE_IN_54XX },
> +	{ .div = 63, .val = 63, .flags = RATE_IN_54XX },
>   	{ .div = 0 },
>   };
>
>

^ permalink raw reply

* [PATCH 08/10] ARM: OMAP5: hwmod data: Create initial OMAP5 SOC hwmod data
From: Sebastien Guiriec @ 2013-01-21 14:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FCF838.6000105@ti.com>

Hi Santosh

We can also remove all the next data:
	omap54xx_l4_abe__aess_dma,
	omap54xx_l4_abe__dmic_dma,
	omap54xx_l4_abe__mcasp_dma,
	omap54xx_l4_abe__mcbsp1_dma,
	omap54xx_l4_abe__mcbsp2_dma,
	omap54xx_l4_abe__mcbsp3_dma,
	omap54xx_l4_abe__mcpdm_dma,
	omap54xx_l4_abe__slimbus1_dma,
	omap54xx_l4_abe__timer5_dma,
	omap54xx_l4_abe__timer6_dma,
	omap54xx_l4_abe__timer7_dma,
	omap54xx_l4_abe__timer8_dma,
	omap54xx_l4_abe__wd_timer3_dma,

It was needed in the past due to the way the lockup between DT data and 
hwmod was done but Peter clean it up in 3.8.

For AESS we just need the last memory bank due to hwmod code for 
SYS_CONFIG access.

Best regards,

Sebastien


On 01/21/2013 09:11 AM, Santosh Shilimkar wrote:
> On Friday 18 January 2013 10:45 PM, Tony Lindgren wrote:
>> Hi,
>>
>> * Santosh Shilimkar <santosh.shilimkar@ti.com> [130118 07:30]:
>>> From: Benoit Cousson <b-cousson@ti.com>
>>>
>>> Adding the hwmod data for OMAP54xx platforms.
>>> --- /dev/null
>>> +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
>>> +/* bb2d */
>>> +static struct omap_hwmod_irq_info omap54xx_bb2d_irqs[] = {
>>> +    { .irq = 125 + OMAP54XX_IRQ_GIC_START },
>>> +    { .irq = -1 }
>>> +};
>> ...
>>
>>> +/* c2c */
>>> +static struct omap_hwmod_irq_info omap54xx_c2c_irqs[] = {
>>> +    { .irq = 88 + OMAP54XX_IRQ_GIC_START },
>>> +    { .irq = -1 }
>>> +};
>> ...
>>
>>
>>> +static struct omap_hwmod_dma_info omap54xx_c2c_sdma_reqs[] = {
>>> +    { .dma_req = 68 + OMAP54XX_DMA_REQ_START },
>>> +    { .dma_req = -1 }
>>> +};
>>
>>
>>
>>> +static struct omap_hwmod_addr_space omap54xx_elm_addrs[] = {
>>> +    {
>>> +        .pa_start    = 0x48078000,
>>> +        .pa_end        = 0x48078fff,
>>> +        .flags        = ADDR_TYPE_RT
>>> +    },
>>> +    { }
>>> +};
>> ...
>>
>>> +static struct omap_hwmod_addr_space omap54xx_emif1_addrs[] = {
>>> +    {
>>> +        .pa_start    = 0x4c000000,
>>> +        .pa_end        = 0x4c0003ff,
>>> +        .flags        = ADDR_TYPE_RT
>>> +    },
>>> +    { }
>>> +};
>>
>> As discussed earlier on this list, let's not duplicate the standard
>> resources here as they already are supposed to come from device tree.
>>
>> Whatever issues prevent us from dropping the duplicate data here need
>> to be fixed. I believe Benoit already had some scripts/patches for
>> that and was just waiting for the DMA binding to get merged?
>>
> Will have a loot at it. DMA binding pull request narrowly missed
> 3.8 but should get into 3.9.
>
> Regards
> santosh
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v7 06/15] gpio: find gpio base by ascend order
From: Linus Walleij @ 2013-01-21 14:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-7-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> gpiochip_find_base() always tries to find valid gpio with descend order.
> It's inconvient if gpio information is passing from DTS. Now try to find
> valid gpio with ascend order.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Grant, can you comment on this?

You know DT and GPIO better than me....

Yours,
Linus Walleij

^ permalink raw reply

* [RFC PATCH 6/6] USB: MUSB: OMAP: get PHY by phandle for dt boot
From: Roger Quadros @ 2013-01-21 14:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FD4593.5020007@ti.com>

On 01/21/2013 03:41 PM, kishon wrote:
> Hi,
> 
> On Monday 21 January 2013 06:48 PM, Roger Quadros wrote:
>> On 01/16/2013 05:01 PM, Kishon Vijay Abraham I wrote:
>>> The OMAP glue has been modified to get PHY by phandle for dt boot.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>   drivers/usb/musb/omap2430.c |    7 ++++++-
>>>   1 file changed, 6 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
>>> index 3628a50..08709cf 100644
>>> --- a/drivers/usb/musb/omap2430.c
>>> +++ b/drivers/usb/musb/omap2430.c
>>> @@ -346,7 +346,12 @@ static int omap2430_musb_init(struct musb *musb)
>>>        * up through ULPI.  TWL4030-family PMICs include one,
>>>        * which needs a driver, drivers aren't always needed.
>>>        */
>>> -    musb->xceiv = devm_usb_get_phy(dev, 0);
>>> +    if (dev->parent->of_node)
>>> +        musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
>>> +            "usb_phy", 0);
>>
>> Why dev->parent and not just dev?
> 
> Right now MUSB core is not converted to dt and hence we don't have
> separate dt node for MUSB core.
> So the PHY information is added to the glue dt data.
> 

OK. Got it :).

--
cheers,
-roger

^ permalink raw reply

* [RFC PATCH 5/6] usb: otg: add device tree support to otg library
From: Roger Quadros @ 2013-01-21 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50FD43F5.1020208@ti.com>

On 01/21/2013 03:34 PM, kishon wrote:
> On Monday 21 January 2013 06:51 PM, Roger Quadros wrote:
>> On 01/16/2013 05:01 PM, Kishon Vijay Abraham I wrote:
>>> Added an API devm_usb_get_phy_by_phandle(), to get usb phy by passing a
>>> device node phandle value. This function will return a pointer to
>>> the phy on success, -EPROBE_DEFER if there is a device_node for the
>>> phandle,
>>> but the phy has not been added, or a ERR_PTR() otherwise.
>>>
>>> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>>   drivers/usb/otg/otg.c   |   77
>>> +++++++++++++++++++++++++++++++++++++++++++++++
>>>   include/linux/usb/phy.h |    8 +++++
>>>   2 files changed, 85 insertions(+)
>>>
>>> diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
>>> index dbf2043..e9799bb 100644
>>> --- a/drivers/usb/otg/otg.c
>>> +++ b/drivers/usb/otg/otg.c
>>> @@ -13,7 +13,9 @@
>>>   #include <linux/export.h>
>>>   #include <linux/err.h>
>>>   #include <linux/device.h>
>>> +#include <linux/module.h>
>>>   #include <linux/slab.h>
>>> +#include <linux/of.h>
>>>
>>>   #include <linux/usb/otg.h>
>>>
>>> @@ -34,6 +36,20 @@ static struct usb_phy *__usb_find_phy(struct
>>> device *dev, u8 index)
>>>       return ERR_PTR(-ENODEV);
>>>   }
>>>
>>> +static struct usb_phy *__of_usb_find_phy(struct device_node *node)
>>> +{
>>> +    struct usb_phy  *phy;
>>> +
>>> +    list_for_each_entry(phy, &phy_list, head) {
>>> +        if (node != phy->dev->of_node)
>>> +            continue;
>>> +
>>> +        return phy;
>>> +    }
>>> +
>>> +    return ERR_PTR(-ENODEV);
>>> +}
>>> +
>>>   static void devm_usb_phy_release(struct device *dev, void *res)
>>>   {
>>>       struct usb_phy *phy = *(struct usb_phy **)res;
>>> @@ -109,6 +125,67 @@ err0:
>>>   }
>>>   EXPORT_SYMBOL(usb_get_phy);
>>>
>>> + /**
>>> + * devm_usb_get_phy_by_phandle - find the USB PHY by phandle
>>> + * @dev - device that requests this phy
>>> + * @phandle - name of the property holding the phy phandle value
>>> + * @index - the index of the phy
>>> + *
>>> + * Returns the phy driver associated with the given phandle value,
>>> + * after getting a refcount to it, -ENODEV if there is no such phy or
>>> + * -EPROBE_DEFER if there is a phandle to the phy, but the device is
>>> + * not yet loaded. While at that, it also associates the device with
>>> + * the phy using devres. On driver detach, release function is invoked
>>> + * on the devres data, then, devres data is freed.
>>> + *
>>> + * For use by USB host and peripheral drivers.
>>> + */
>>> +struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
>>> +    const char *phandle, u8 index)
>>> +{
>>> +    struct usb_phy    *phy = NULL, **ptr;
>>> +    unsigned long    flags;
>>> +    struct device_node *node;
>>> +
>>> +    if (!dev->of_node) {
>>> +        dev_dbg(dev, "device does not have a device node entry\n");
>>> +        return ERR_PTR(-EINVAL);
>>> +    }
>>> +
>>> +    node = of_parse_phandle(dev->of_node, phandle, index);
>>> +    if (!node) {
>>> +        dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle,
>>> +            dev->of_node->full_name);
>>> +        return ERR_PTR(-ENODEV);
>>> +    }
>>> +
>>> +    ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
>>> +    if (!ptr) {
>>> +        dev_dbg(dev, "failed to allocate memory for devres\n");
>>> +        return ERR_PTR(-ENOMEM);
>>> +    }
>>
>> I fail to understand why you need ptr at all and why do devres_alloc()
>> for it.
> 
> Thats how we create a "managed device resource". You can have a look at
> Documentation/driver-model/devres.txt and drivers/base/devres.c.

OK, I get it now. You might want to update the text file too since you
are adding a automagically managed interface.

regards,
-roger

^ permalink raw reply

* [RESEND PATCH v9 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs
From: Tomasz Figa @ 2013-01-21 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358499623-13901-1-git-send-email-p.paneri@samsung.com>

On Friday 18 of January 2013 14:30:21 Praveen Paneri wrote:
> Changes from v8:
> Resending this patch series after rebasing to the latest usb-next
> branch. Rewording inline comments for better readability.
> Removed IS_ENABLED(CONFIG_OF) as pdev->dev.of_node is enough to check
> for dt support. Using of_match_ptr to add of_match_table to
> platform_driver structure. Removed unnecessary variables.
> 
> Changes from v7:
> Rebased to the latest usb-next branch.
> Separating arch patches from these driver patches.
> 
> Changes from v6:
> Modified register definitions according to the existing ones.
> Changed default PHY clk selection for SoCs.
> Improved binding text and rebased to the latest usb-next.
> 
> Changes from v5:
> Moved clk_get() to driver's probe function. Now reference clock
> frequency selection value is stored in samsung_usbphy structure for
> later use. Used IS_ENABLED() instead of #ifdef in
> samsung_usbphy_get_driver_data().
> 
> Changes from v4:
> Moved header file contents to driver's source file
> Removed unnecessary print message from driver's probe function
> Dropped the Free Software Foundation address from the header
> 
> Changes from v3:
> Replaced susbsys_initcall()/module_exit() by module_platform_driver().
> Accordingly in the hsotg driver returned -EPROBE_DEFER until phy driver
> is registered
> Removed unnecessary devm_usb_put_phy() call from the hsotg driver
> remove.
> 
> Changes from v2:
> Changed the driver filenames to samsung-usbphy
> Rectified coding style related errors
> 
> Changes from v1:
> Rebased patches to latest usb-next branch
> Changed the name 'sec_usbphy' to 'samsung_usbphy'
> 
> This patch set introduces a phy driver for samsung SoCs. It uses the
> existing transceiver infrastructure to provide phy control functions.
> Use of this driver can be extended for usb host phy as well. Over the
> period of time all the phy related code for most of the samsung SoCs
> can be integrated here. Removing the existing phy code from
> mach-s3c64xx. Same can be done for other SoCs when they start
> supporting this phy driver.
> This driver is tested with smdk6410 and Exynos4210(with DT).
> 
> Praveen Paneri (2):
>   usb: phy: samsung: Introducing usb phy driver for hsotg
>   usb: s3c-hsotg: Adding phy driver support
> 
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>  drivers/usb/gadget/s3c-hsotg.c                     |   37 ++-
>  drivers/usb/phy/Kconfig                            |    8 +
>  drivers/usb/phy/Makefile                           |    1 +
>  drivers/usb/phy/samsung-usbphy.c                   |  354
> ++++++++++++++++++++ include/linux/platform_data/samsung-usbphy.h      
> |   27 ++
>  6 files changed, 428 insertions(+), 10 deletions(-)
>  create mode 100644
> Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode
> 100644 drivers/usb/phy/samsung-usbphy.c
>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
> 
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-samsung-soc" in the body of a message to
> majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Tested on Exynos4210-Trats.

Tested-by: Tomasz Figa <t.figa@samsung.com>

I also have patches for Exynos 4x12, which I will send once this series 
and generic PMU isolation setting patches get merged.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

^ permalink raw reply

* [PATCH v7 04/15] gpio: set gpio range cells property as 3
From: Linus Walleij @ 2013-01-21 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-5-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> Add gpio offset into "gpio-range-cells" property. It's used to support
> sparse pinctrl range in gpio chip.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Need Shiraz to comment on this.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v7 03/15] gpio: use pinctrl device name for add range
From: Linus Walleij @ 2013-01-21 14:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-4-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> gpiochip_add_pin_range() needs pinctrl device name as parameter.
> Currently the parameter is pinctrl description name. So fix it.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  drivers/gpio/gpiolib-of.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index d542a14..25b1dbe 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -250,7 +250,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
>                  * on the same GPIO chip.
>                  */
>                 ret = gpiochip_add_pin_range(chip,
> -                                            pinctrl_dev_get_name(pctldev),
> +                                            pinctrl_dev_get_devname(pctldev),
>                                              0, /* offset in gpiochip */
>                                              pinspec.args[0],
>                                              pinspec.args[1]);

Hm looks like the right thing to do!

Patch applied.

It must be such that everyone using this so far has just
set the name to be identical to the device name.

Maybe we should just drop the name in the descriptor
if it's causing problems like this?

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v7 02/15] pinctrl: core: get devname from pinctrl_dev
From: Linus Walleij @ 2013-01-21 14:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358494279-16503-3-git-send-email-haojian.zhuang@linaro.org>

On Fri, Jan 18, 2013 at 8:31 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:

> Add new function to get devname from pinctrl_dev. pinctrl_dev_get_name()
> can only get pinctrl description name. If we want to use gpio driver to
> find pinctrl device node, we need to fetch the pinctrl device name.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

Looks helpful in its own right, patch applied!

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 4/4 v3] pinctrl/abx500: add AB8500 pinctrl driver
From: Linus Walleij @ 2013-01-21 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrice Chotard <patrice.chotard@st.com>

This adds a subdriver for the AB8500 pinctrl portions.

Reviewed-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v2->v3:
- Actually commit the changes dropping the _ranges_ infix.
ChangeLog v1->v2:
- Move definition of init functions over to this patch from
  the core patch so we don't have unimplemented functions defined
  in the kernel.
- Drop a few "_ranges_" substrings wher unappropriate.
---
 arch/arm/mach-ux500/Kconfig      |   1 +
 drivers/pinctrl/Kconfig          |   4 +
 drivers/pinctrl/Makefile         |   1 +
 drivers/pinctrl/pinctrl-ab8500.c | 485 +++++++++++++++++++++++++++++++++++++++
 drivers/pinctrl/pinctrl-abx500.c |   3 +
 drivers/pinctrl/pinctrl-abx500.h |  13 ++
 6 files changed, 507 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-ab8500.c

diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 2c090d7..31f1b5a 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -19,6 +19,7 @@ config UX500_SOC_DB8500
 	select CPU_FREQ_TABLE if CPU_FREQ
 	select MFD_DB8500_PRCMU
 	select PINCTRL_DB8500
+	select PINCTRL_AB8500
 	select REGULATOR
 	select REGULATOR_DB8500_PRCMU
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index ba3038c..367556f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -33,6 +33,10 @@ config PINCTRL_ABX500
 	help
 	  Select this to enable the ABx500 family IC GPIO driver
 
+config PINCTRL_AB8500
+	bool "AB8500 pin controller driver"
+	depends on PINCTRL_ABX500 && ARCH_U8500
+
 config PINCTRL_AT91
 	bool "AT91 pinctrl driver"
 	depends on OF
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index ead4fa7..aad5c93 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL)		+= devicetree.o
 endif
 obj-$(CONFIG_GENERIC_PINCONF)	+= pinconf-generic.o
 obj-$(CONFIG_PINCTRL_ABX500)	+= pinctrl-abx500.o
+obj-$(CONFIG_PINCTRL_AB8500)	+= pinctrl-ab8500.o
 obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_BCM2835)	+= pinctrl-bcm2835.o
 obj-$(CONFIG_PINCTRL_IMX)	+= pinctrl-imx.o
diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/pinctrl-ab8500.c
new file mode 100644
index 0000000..6495390
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-ab8500.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2012
+ *
+ * Author: Patrice Chotard <patrice.chotard@stericsson.com> for ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include "pinctrl-abx500.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define ABX500_GPIO(offset)		(offset)
+
+#define AB8500_PIN_T10		ABX500_GPIO(1)
+#define AB8500_PIN_T9		ABX500_GPIO(2)
+#define AB8500_PIN_U9		ABX500_GPIO(3)
+#define AB8500_PIN_W2		ABX500_GPIO(4)
+/* hole */
+#define AB8500_PIN_Y18		ABX500_GPIO(6)
+#define AB8500_PIN_AA20		ABX500_GPIO(7)
+#define AB8500_PIN_W18		ABX500_GPIO(8)
+#define AB8500_PIN_AA19		ABX500_GPIO(9)
+#define AB8500_PIN_U17		ABX500_GPIO(10)
+#define AB8500_PIN_AA18		ABX500_GPIO(11)
+#define AB8500_PIN_U16		ABX500_GPIO(12)
+#define AB8500_PIN_W17		ABX500_GPIO(13)
+#define AB8500_PIN_F14		ABX500_GPIO(14)
+#define AB8500_PIN_B17		ABX500_GPIO(15)
+#define AB8500_PIN_F15		ABX500_GPIO(16)
+#define AB8500_PIN_P5		ABX500_GPIO(17)
+#define AB8500_PIN_R5		ABX500_GPIO(18)
+#define AB8500_PIN_U5		ABX500_GPIO(19)
+#define AB8500_PIN_T5		ABX500_GPIO(20)
+#define AB8500_PIN_H19		ABX500_GPIO(21)
+#define AB8500_PIN_G20		ABX500_GPIO(22)
+#define AB8500_PIN_G19		ABX500_GPIO(23)
+#define AB8500_PIN_T14		ABX500_GPIO(24)
+#define AB8500_PIN_R16		ABX500_GPIO(25)
+#define AB8500_PIN_M16		ABX500_GPIO(26)
+#define AB8500_PIN_J6		ABX500_GPIO(27)
+#define AB8500_PIN_K6		ABX500_GPIO(28)
+#define AB8500_PIN_G6		ABX500_GPIO(29)
+#define AB8500_PIN_H6		ABX500_GPIO(30)
+#define AB8500_PIN_F5		ABX500_GPIO(31)
+#define AB8500_PIN_G5		ABX500_GPIO(32)
+/* hole */
+#define AB8500_PIN_R17		ABX500_GPIO(34)
+#define AB8500_PIN_W15		ABX500_GPIO(35)
+#define AB8500_PIN_A17		ABX500_GPIO(36)
+#define AB8500_PIN_E15		ABX500_GPIO(37)
+#define AB8500_PIN_C17		ABX500_GPIO(38)
+#define AB8500_PIN_E16		ABX500_GPIO(39)
+#define AB8500_PIN_T19		ABX500_GPIO(40)
+#define AB8500_PIN_U19		ABX500_GPIO(41)
+#define AB8500_PIN_U2		ABX500_GPIO(42)
+
+/* indicates the highest GPIO number */
+#define AB8500_GPIO_MAX_NUMBER	42
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc ab8500_pins[] = {
+	PINCTRL_PIN(AB8500_PIN_T10, "GPIO1_T10"),
+	PINCTRL_PIN(AB8500_PIN_T9, "GPIO2_T9"),
+	PINCTRL_PIN(AB8500_PIN_U9, "GPIO3_U9"),
+	PINCTRL_PIN(AB8500_PIN_W2, "GPIO4_W2"),
+	/* hole */
+	PINCTRL_PIN(AB8500_PIN_Y18, "GPIO6_Y18"),
+	PINCTRL_PIN(AB8500_PIN_AA20, "GPIO7_AA20"),
+	PINCTRL_PIN(AB8500_PIN_W18, "GPIO8_W18"),
+	PINCTRL_PIN(AB8500_PIN_AA19, "GPIO9_AA19"),
+	PINCTRL_PIN(AB8500_PIN_U17, "GPIO10_U17"),
+	PINCTRL_PIN(AB8500_PIN_AA18, "GPIO11_AA18"),
+	PINCTRL_PIN(AB8500_PIN_U16, "GPIO12_U16"),
+	PINCTRL_PIN(AB8500_PIN_W17, "GPIO13_W17"),
+	PINCTRL_PIN(AB8500_PIN_F14, "GPIO14_F14"),
+	PINCTRL_PIN(AB8500_PIN_B17, "GPIO15_B17"),
+	PINCTRL_PIN(AB8500_PIN_F15, "GPIO16_F15"),
+	PINCTRL_PIN(AB8500_PIN_P5, "GPIO17_P5"),
+	PINCTRL_PIN(AB8500_PIN_R5, "GPIO18_R5"),
+	PINCTRL_PIN(AB8500_PIN_U5, "GPIO19_U5"),
+	PINCTRL_PIN(AB8500_PIN_T5, "GPIO20_T5"),
+	PINCTRL_PIN(AB8500_PIN_H19, "GPIO21_H19"),
+	PINCTRL_PIN(AB8500_PIN_G20, "GPIO22_G20"),
+	PINCTRL_PIN(AB8500_PIN_G19, "GPIO23_G19"),
+	PINCTRL_PIN(AB8500_PIN_T14, "GPIO24_T14"),
+	PINCTRL_PIN(AB8500_PIN_R16, "GPIO25_R16"),
+	PINCTRL_PIN(AB8500_PIN_M16, "GPIO26_M16"),
+	PINCTRL_PIN(AB8500_PIN_J6, "GPIO27_J6"),
+	PINCTRL_PIN(AB8500_PIN_K6, "GPIO28_K6"),
+	PINCTRL_PIN(AB8500_PIN_G6, "GPIO29_G6"),
+	PINCTRL_PIN(AB8500_PIN_H6, "GPIO30_H6"),
+	PINCTRL_PIN(AB8500_PIN_F5, "GPIO31_F5"),
+	PINCTRL_PIN(AB8500_PIN_G5, "GPIO32_G5"),
+	/* hole */
+	PINCTRL_PIN(AB8500_PIN_R17, "GPIO34_R17"),
+	PINCTRL_PIN(AB8500_PIN_W15, "GPIO35_W15"),
+	PINCTRL_PIN(AB8500_PIN_A17, "GPIO36_A17"),
+	PINCTRL_PIN(AB8500_PIN_E15, "GPIO37_E15"),
+	PINCTRL_PIN(AB8500_PIN_C17, "GPIO38_C17"),
+	PINCTRL_PIN(AB8500_PIN_E16, "GPIO39_E16"),
+	PINCTRL_PIN(AB8500_PIN_T19, "GPIO40_T19"),
+	PINCTRL_PIN(AB8500_PIN_U19, "GPIO41_U19"),
+	PINCTRL_PIN(AB8500_PIN_U2, "GPIO42_U2"),
+};
+
+/*
+ * Maps local GPIO offsets to local pin numbers
+ */
+static const struct abx500_pinrange ab8500_pinranges[] = {
+	ABX500_PINRANGE(1, 4, ABX500_ALT_A),
+	ABX500_PINRANGE(6, 4, ABX500_ALT_A),
+	ABX500_PINRANGE(10, 4, ABX500_DEFAULT),
+	ABX500_PINRANGE(14, 12, ABX500_ALT_A),
+	ABX500_PINRANGE(26, 1, ABX500_DEFAULT),
+	ABX500_PINRANGE(27, 6, ABX500_ALT_A),
+	ABX500_PINRANGE(34, 1, ABX500_ALT_A),
+	ABX500_PINRANGE(35, 1, ABX500_DEFAULT),
+	ABX500_PINRANGE(36, 7, ABX500_ALT_A),
+};
+
+/*
+ * Read the pin group names like this:
+ * sysclkreq2_d_1 = first groups of pins for sysclkreq2 on default function
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* default column */
+static const unsigned sysclkreq2_d_1_pins[] = { AB8500_PIN_T10 };
+static const unsigned sysclkreq3_d_1_pins[] = { AB8500_PIN_T9 };
+static const unsigned sysclkreq4_d_1_pins[] = { AB8500_PIN_U9 };
+static const unsigned sysclkreq6_d_1_pins[] = { AB8500_PIN_W2 };
+static const unsigned ycbcr0123_d_1_pins[] = { AB8500_PIN_Y18, AB8500_PIN_AA20,
+					AB8500_PIN_W18, AB8500_PIN_AA19};
+static const unsigned gpio10_d_1_pins[] = { AB8500_PIN_U17 };
+static const unsigned gpio11_d_1_pins[] = { AB8500_PIN_AA18 };
+static const unsigned gpio12_d_1_pins[] = { AB8500_PIN_U16 };
+static const unsigned gpio13_d_1_pins[] = { AB8500_PIN_W17 };
+static const unsigned pwmout1_d_1_pins[] = { AB8500_PIN_F14 };
+static const unsigned pwmout2_d_1_pins[] = { AB8500_PIN_B17 };
+static const unsigned pwmout3_d_1_pins[] = { AB8500_PIN_F15 };
+
+/* audio data interface 1*/
+static const unsigned adi1_d_1_pins[] = { AB8500_PIN_P5, AB8500_PIN_R5,
+					AB8500_PIN_U5, AB8500_PIN_T5 };
+/* USBUICC */
+static const unsigned usbuicc_d_1_pins[] = { AB8500_PIN_H19, AB8500_PIN_G20,
+					AB8500_PIN_G19 };
+static const unsigned sysclkreq7_d_1_pins[] = { AB8500_PIN_T14 };
+static const unsigned sysclkreq8_d_1_pins[] = { AB8500_PIN_R16 };
+static const unsigned gpio26_d_1_pins[] = { AB8500_PIN_M16 };
+/* Digital microphone 1 and 2 */
+static const unsigned dmic12_d_1_pins[] = { AB8500_PIN_J6, AB8500_PIN_K6 };
+/* Digital microphone 3 and 4 */
+static const unsigned dmic34_d_1_pins[] = { AB8500_PIN_G6, AB8500_PIN_H6 };
+/* Digital microphone 5 and 6 */
+static const unsigned dmic56_d_1_pins[] = { AB8500_PIN_F5, AB8500_PIN_G5 };
+static const unsigned extcpena_d_1_pins[] = { AB8500_PIN_R17 };
+static const unsigned gpio35_d_1_pins[] = { AB8500_PIN_W15 };
+/* APE SPI */
+static const unsigned apespi_d_1_pins[] = { AB8500_PIN_A17, AB8500_PIN_E15,
+					AB8500_PIN_C17, AB8500_PIN_E16};
+/* modem SDA/SCL */
+static const unsigned modsclsda_d_1_pins[] = { AB8500_PIN_T19, AB8500_PIN_U19 };
+static const unsigned sysclkreq5_d_1_pins[] = { AB8500_PIN_U2 };
+
+/* Altfunction A column */
+static const unsigned gpio1_a_1_pins[] = { AB8500_PIN_T10 };
+static const unsigned gpio2_a_1_pins[] = { AB8500_PIN_T9 };
+static const unsigned gpio3_a_1_pins[] = { AB8500_PIN_U9 };
+static const unsigned gpio4_a_1_pins[] = { AB8500_PIN_W2 };
+static const unsigned gpio6_a_1_pins[] = { AB8500_PIN_Y18 };
+static const unsigned gpio7_a_1_pins[] = { AB8500_PIN_AA20 };
+static const unsigned gpio8_a_1_pins[] = { AB8500_PIN_W18 };
+static const unsigned gpio9_a_1_pins[] = { AB8500_PIN_AA19 };
+/* YCbCr4 YCbCr5 YCbCr6 YCbCr7*/
+static const unsigned ycbcr4567_a_1_pins[] = { AB8500_PIN_U17, AB8500_PIN_AA18,
+					AB8500_PIN_U16, AB8500_PIN_W17};
+static const unsigned gpio14_a_1_pins[] = { AB8500_PIN_F14 };
+static const unsigned gpio15_a_1_pins[] = { AB8500_PIN_B17 };
+static const unsigned gpio16_a_1_pins[] = { AB8500_PIN_F15 };
+static const unsigned gpio17_a_1_pins[] = { AB8500_PIN_P5 };
+static const unsigned gpio18_a_1_pins[] = { AB8500_PIN_R5 };
+static const unsigned gpio19_a_1_pins[] = { AB8500_PIN_U5 };
+static const unsigned gpio20_a_1_pins[] = { AB8500_PIN_T5 };
+static const unsigned gpio21_a_1_pins[] = { AB8500_PIN_H19 };
+static const unsigned gpio22_a_1_pins[] = { AB8500_PIN_G20 };
+static const unsigned gpio23_a_1_pins[] = { AB8500_PIN_G19 };
+static const unsigned gpio24_a_1_pins[] = { AB8500_PIN_T14 };
+static const unsigned gpio25_a_1_pins[] = { AB8500_PIN_R16 };
+static const unsigned gpio27_a_1_pins[] = { AB8500_PIN_J6 };
+static const unsigned gpio28_a_1_pins[] = { AB8500_PIN_K6 };
+static const unsigned gpio29_a_1_pins[] = { AB8500_PIN_G6 };
+static const unsigned gpio30_a_1_pins[] = { AB8500_PIN_H6 };
+static const unsigned gpio31_a_1_pins[] = { AB8500_PIN_F5 };
+static const unsigned gpio32_a_1_pins[] = { AB8500_PIN_G5 };
+static const unsigned gpio34_a_1_pins[] = { AB8500_PIN_R17 };
+static const unsigned gpio36_a_1_pins[] = { AB8500_PIN_A17 };
+static const unsigned gpio37_a_1_pins[] = { AB8500_PIN_E15 };
+static const unsigned gpio38_a_1_pins[] = { AB8500_PIN_C17 };
+static const unsigned gpio39_a_1_pins[] = { AB8500_PIN_E16 };
+static const unsigned gpio40_a_1_pins[] = { AB8500_PIN_T19 };
+static const unsigned gpio41_a_1_pins[] = { AB8500_PIN_U19 };
+static const unsigned gpio42_a_1_pins[] = { AB8500_PIN_U2 };
+
+/* Altfunction B colum */
+static const unsigned hiqclkena_b_1_pins[] = { AB8500_PIN_U17 };
+static const unsigned usbuiccpd_b_1_pins[] = { AB8500_PIN_AA18 };
+static const unsigned i2ctrig1_b_1_pins[] = { AB8500_PIN_U16 };
+static const unsigned i2ctrig2_b_1_pins[] = { AB8500_PIN_W17 };
+
+/* Altfunction C column */
+static const unsigned usbvdat_c_1_pins[] = { AB8500_PIN_W17 };
+
+
+#define AB8500_PIN_GROUP(a, b) { .name = #a, .pins = a##_pins,		\
+			.npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct abx500_pingroup ab8500_groups[] = {
+	/* default column */
+	AB8500_PIN_GROUP(sysclkreq2_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq3_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq4_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq6_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(ycbcr0123_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio10_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio11_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio12_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio13_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(pwmout1_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(pwmout2_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(pwmout3_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(adi1_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(usbuicc_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq7_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq8_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio26_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(dmic12_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(dmic34_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(dmic56_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(extcpena_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(gpio35_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(apespi_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(modsclsda_d_1, ABX500_DEFAULT),
+	AB8500_PIN_GROUP(sysclkreq5_d_1, ABX500_DEFAULT),
+	/* Altfunction A column */
+	AB8500_PIN_GROUP(gpio1_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio2_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio3_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio4_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio6_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio7_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio8_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio9_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(ycbcr4567_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio14_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio15_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio16_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio17_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio18_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio19_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio20_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio21_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio22_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio23_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio24_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio25_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio27_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio28_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio29_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio30_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio31_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio32_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio34_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio36_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio37_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio38_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio39_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio40_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio41_a_1, ABX500_ALT_A),
+	AB8500_PIN_GROUP(gpio42_a_1, ABX500_ALT_A),
+	/* Altfunction B column */
+	AB8500_PIN_GROUP(hiqclkena_b_1, ABX500_ALT_B),
+	AB8500_PIN_GROUP(usbuiccpd_b_1, ABX500_ALT_B),
+	AB8500_PIN_GROUP(i2ctrig1_b_1, ABX500_ALT_B),
+	AB8500_PIN_GROUP(i2ctrig2_b_1, ABX500_ALT_B),
+	/* Altfunction C column */
+	AB8500_PIN_GROUP(usbvdat_c_1, ABX500_ALT_C),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define AB8500_FUNC_GROUPS(a, b...)	   \
+static const char * const a##_groups[] = { b };
+
+AB8500_FUNC_GROUPS(sysclkreq, "sysclkreq2_d_1", "sysclkreq3_d_1",
+		"sysclkreq4_d_1", "sysclkreq5_d_1", "sysclkreq6_d_1",
+		"sysclkreq7_d_1", "sysclkreq8_d_1");
+AB8500_FUNC_GROUPS(ycbcr, "ycbcr0123_d_1", "ycbcr4567_a_1");
+AB8500_FUNC_GROUPS(gpio, "gpio1_a_1", "gpio2_a_1", "gpio3_a_1", "gpio4_a_1",
+		"gpio6_a_1", "gpio7_a_1", "gpio8_a_1", "gpio9_a_1",
+		"gpio10_d_1", "gpio11_d_1", "gpio12_d_1", "gpio13_d_1",
+		"gpio14_a_1", "gpio15_a_1", "gpio16_a_1", "gpio17_a_1",
+		"gpio18_a_1", "gpio19_a_1", "gpio20_a_1", "gpio21_a_1",
+		"gpio22_a_1", "gpio23_a_1", "gpio24_a_1", "gpio25_a_1",
+		"gpio26_d_1", "gpio27_a_1", "gpio28_a_1", "gpio29_a_1",
+		"gpio30_a_1", "gpio31_a_1", "gpio32_a_1", "gpio34_a_1",
+		"gpio35_d_1", "gpio36_a_1", "gpio37_a_1", "gpio38_a_1",
+		"gpio39_a_1", "gpio40_a_1", "gpio41_a_1", "gpio42_a_1");
+AB8500_FUNC_GROUPS(pwmout, "pwmout1_d_1", "pwmout2_d_1", "pwmout3_d_1");
+AB8500_FUNC_GROUPS(adi1, "adi1_d_1");
+AB8500_FUNC_GROUPS(usbuicc, "usbuicc_d_1", "usbuiccpd_b_1");
+AB8500_FUNC_GROUPS(dmic, "dmic12_d_1", "dmic34_d_1", "dmic56_d_1");
+AB8500_FUNC_GROUPS(extcpena, "extcpena_d_1");
+AB8500_FUNC_GROUPS(apespi, "apespi_d_1");
+AB8500_FUNC_GROUPS(modsclsda, "modsclsda_d_1");
+AB8500_FUNC_GROUPS(hiqclkena, "hiqclkena_b_1");
+AB8500_FUNC_GROUPS(i2ctrig, "i2ctrig1_b_1", "i2ctrig2_b_1");
+AB8500_FUNC_GROUPS(usbvdat, "usbvdat_c_1");
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+static const struct abx500_function ab8500_functions[] = {
+	FUNCTION(sysclkreq),
+	FUNCTION(ycbcr),
+	FUNCTION(gpio),
+	FUNCTION(pwmout),
+	FUNCTION(adi1),
+	FUNCTION(usbuicc),
+	FUNCTION(dmic),
+	FUNCTION(extcpena),
+	FUNCTION(apespi),
+	FUNCTION(modsclsda),
+	FUNCTION(hiqclkena),
+	FUNCTION(i2ctrig),
+	FUNCTION(usbvdat),
+};
+
+/*
+ * this table translates what's is in the AB8500 specification regarding the
+ * balls alternate functions (as for DB, default, ALT_A, ALT_B and ALT_C).
+ * ALTERNATE_FUNCTIONS(GPIO_NUMBER, GPIOSEL bit, ALTERNATFUNC bit1,
+ * ALTERNATEFUNC bit2, ALTA val, ALTB val, ALTC val),
+ *
+ * example :
+ *
+ *	ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1 ,2),
+ *	means that pin AB8500_PIN_W17 (pin 13) supports 4 mux (default/ALT_A,
+ *	ALT_B and ALT_C), so GPIOSEL and ALTERNATFUNC registers are used to
+ *	select the mux.  ALTA, ALTB and ALTC val indicates values to write in
+ *	ALTERNATFUNC register. We need to specifies these values as SOC
+ *	designers didn't apply the same logic on how to select mux in the
+ *	ABx500 family.
+ *
+ *	As this pins supports at least ALT_B mux, default mux is
+ *	selected by writing 1 in GPIOSEL bit :
+ *
+ *		| GPIOSEL bit=4 | alternatfunc bit2=4 | alternatfunc bit1=3
+ *	default	|       1       |          0          |          0
+ *	alt_A	|       0       |          0          |          0
+ *	alt_B	|       0       |          0          |          1
+ *	alt_C	|       0       |          1          |          0
+ *
+ *	ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED),
+ *	means that pin AB8500_PIN_W18 (pin 8) supports 2 mux, so only GPIOSEL
+ *	register is used to select the mux. As this pins doesn't support at
+ *	least ALT_B mux, default mux is by writing 0 in GPIOSEL bit :
+ *
+ *		| GPIOSEL bit=7 | alternatfunc bit2=  | alternatfunc bit1=
+ *	default	|       0       |          0          |          0
+ *	alt_A	|       1       |          0          |          0
+ */
+
+struct alternate_functions ab8500_alternate_functions[AB8500_GPIO_MAX_NUMBER + 1] = {
+	ALTERNATE_FUNCTIONS(0, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO0 */
+	ALTERNATE_FUNCTIONS(1,	    0, UNUSED, UNUSED, 0, 0, 0), /* GPIO1, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(2,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO2, altA controlled by bit 1 */
+	ALTERNATE_FUNCTIONS(3,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO3, altA controlled by bit 2*/
+	ALTERNATE_FUNCTIONS(4,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO4, altA controlled by bit 3*/
+	/* bit 4 reserved */
+	ALTERNATE_FUNCTIONS(5, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO5 */
+	ALTERNATE_FUNCTIONS(6,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO6, altA controlled by bit 5*/
+	ALTERNATE_FUNCTIONS(7,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO7, altA controlled by bit 6*/
+	ALTERNATE_FUNCTIONS(8,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO8, altA controlled by bit 7*/
+
+	ALTERNATE_FUNCTIONS(9,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO9, altA controlled by bit 0*/
+	ALTERNATE_FUNCTIONS(10,     1,      0, UNUSED, 0, 1, 0), /* GPIO10, altA and altB controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(11,     2,      1, UNUSED, 0, 1, 0), /* GPIO11, altA and altB controlled by bit 1 */
+	ALTERNATE_FUNCTIONS(12,     3,      2, UNUSED, 0, 1, 0), /* GPIO12, altA and altB controlled by bit 2 */
+	ALTERNATE_FUNCTIONS(13,     4,      3,      4, 0, 1, 2), /* GPIO13, altA altB and altC controlled by bit 3 and 4 */
+	ALTERNATE_FUNCTIONS(14,     5, UNUSED, UNUSED, 0, 0, 0), /* GPIO14, altA controlled by bit 5 */
+	ALTERNATE_FUNCTIONS(15,     6, UNUSED, UNUSED, 0, 0, 0), /* GPIO15, altA controlled by bit 6 */
+	ALTERNATE_FUNCTIONS(16,     7, UNUSED, UNUSED, 0, 0, 0), /* GPIO16, altA controlled by bit 7 */
+	/*
+	 * pins 17 to 20 are special case, only bit 0 is used to select
+	 * alternate function for these 4 pins.
+	 * bits 1 to 3 are reserved
+	 */
+	ALTERNATE_FUNCTIONS(17,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO17, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(18,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO18, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(19,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO19, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(20,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO20, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(21,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO21, altA controlled by bit 4 */
+	ALTERNATE_FUNCTIONS(22,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO22, altA controlled by bit 5 */
+	ALTERNATE_FUNCTIONS(23,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO23, altA controlled by bit 6 */
+	ALTERNATE_FUNCTIONS(24,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO24, altA controlled by bit 7 */
+
+	ALTERNATE_FUNCTIONS(25,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO25, altA controlled by bit 0 */
+	/* pin 26 special case, no alternate function, bit 1 reserved */
+	ALTERNATE_FUNCTIONS(26, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO26 */
+	ALTERNATE_FUNCTIONS(27,      2, UNUSED, UNUSED, 0, 0, 0), /* GPIO27, altA controlled by bit 2 */
+	ALTERNATE_FUNCTIONS(28,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO28, altA controlled by bit 3 */
+	ALTERNATE_FUNCTIONS(29,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO29, altA controlled by bit 4 */
+	ALTERNATE_FUNCTIONS(30,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO30, altA controlled by bit 5 */
+	ALTERNATE_FUNCTIONS(31,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO31, altA controlled by bit 6 */
+	ALTERNATE_FUNCTIONS(32,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO32, altA controlled by bit 7 */
+
+	ALTERNATE_FUNCTIONS(33, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* no GPIO33 */
+	ALTERNATE_FUNCTIONS(34,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO34, altA controlled by bit 1 */
+	/* pin 35 special case, no alternate function, bit 2 reserved */
+	ALTERNATE_FUNCTIONS(35, UNUSED, UNUSED, UNUSED, 0, 0, 0), /* GPIO35 */
+	ALTERNATE_FUNCTIONS(36,      3, UNUSED, UNUSED, 0, 0, 0), /* GPIO36, altA controlled by bit 3 */
+	ALTERNATE_FUNCTIONS(37,      4, UNUSED, UNUSED, 0, 0, 0), /* GPIO37, altA controlled by bit 4 */
+	ALTERNATE_FUNCTIONS(38,      5, UNUSED, UNUSED, 0, 0, 0), /* GPIO38, altA controlled by bit 5 */
+	ALTERNATE_FUNCTIONS(39,      6, UNUSED, UNUSED, 0, 0, 0), /* GPIO39, altA controlled by bit 6 */
+	ALTERNATE_FUNCTIONS(40,      7, UNUSED, UNUSED, 0, 0, 0), /* GPIO40, altA controlled by bit 7 */
+
+	ALTERNATE_FUNCTIONS(41,      0, UNUSED, UNUSED, 0, 0, 0), /* GPIO41, altA controlled by bit 0 */
+	ALTERNATE_FUNCTIONS(42,      1, UNUSED, UNUSED, 0, 0, 0), /* GPIO42, altA controlled by bit 1 */
+};
+
+/*
+ * Only some GPIOs are interrupt capable, and they are
+ * organized in discontiguous clusters:
+ *
+ *	GPIO6 to GPIO13
+ *	GPIO24 and GPIO25
+ *	GPIO36 to GPIO41
+ */
+struct abx500_gpio_irq_cluster ab8500_gpio_irq_cluster[] = {
+	GPIO_IRQ_CLUSTER(5, 12, 0), /* GPIO numbers start from 1 */
+	GPIO_IRQ_CLUSTER(23, 24, 0),
+	GPIO_IRQ_CLUSTER(35, 40, 0),
+};
+
+static struct abx500_pinctrl_soc_data ab8500_soc = {
+	.gpio_ranges = ab8500_pinranges,
+	.gpio_num_ranges = ARRAY_SIZE(ab8500_pinranges),
+	.pins = ab8500_pins,
+	.npins = ARRAY_SIZE(ab8500_pins),
+	.functions = ab8500_functions,
+	.nfunctions = ARRAY_SIZE(ab8500_functions),
+	.groups = ab8500_groups,
+	.ngroups = ARRAY_SIZE(ab8500_groups),
+	.alternate_functions = ab8500_alternate_functions,
+	.gpio_irq_cluster = ab8500_gpio_irq_cluster,
+	.ngpio_irq_cluster = ARRAY_SIZE(ab8500_gpio_irq_cluster),
+	.irq_gpio_rising_offset = AB8500_INT_GPIO6R,
+	.irq_gpio_falling_offset = AB8500_INT_GPIO6F,
+	.irq_gpio_factor = 1,
+};
+
+void __devinit
+abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
+{
+	*soc = &ab8500_soc;
+}
diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c
index 26abfd8..13ae68f 100644
--- a/drivers/pinctrl/pinctrl-abx500.c
+++ b/drivers/pinctrl/pinctrl-abx500.c
@@ -1116,6 +1116,9 @@ static int __devinit abx500_gpio_probe(struct platform_device *pdev)
 
 	/* Poke in other ASIC variants here */
 	switch (platid->driver_data) {
+	case PINCTRL_AB8500:
+		abx500_pinctrl_ab8500_init(&pct->soc);
+		break;
 	default:
 		dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n",
 				(int) platid->driver_data);
diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/pinctrl-abx500.h
index 436ace3..a6c9332 100644
--- a/drivers/pinctrl/pinctrl-abx500.h
+++ b/drivers/pinctrl/pinctrl-abx500.h
@@ -177,4 +177,17 @@ struct abx500_pinctrl_soc_data {
 	int irq_gpio_factor;
 };
 
+#ifdef CONFIG_PINCTRL_AB8500
+
+void abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+abx500_pinctrl_ab8500_init(struct abx500_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
 #endif /* PINCTRL_PINCTRL_ABx500_H */
-- 
1.7.11.3

^ 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