Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [QUESTION] : why is the exynos not using the TWD as local timers ?
From: Daniel Lezcano @ 2013-02-01 16:05 UTC (permalink / raw)
  To: linux-arm-kernel


Hi all,

why is the exynos not using the TWD as local timers ?

Probably already asked, but I was not able to find an detailed answer
for that [1]

Thanks
  -- Daniel

[1] http://www.spinics.net/lists/arm-kernel/msg218906.html

-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH v2 19/27] pci: PCIe driver for Marvell Armada 370/XP systems
From: Arnd Bergmann @ 2013-02-01 16:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201100329.4d57fa55@skate>

On Friday 01 February 2013, Thomas Petazzoni wrote:
> So there is really a range of I/O addresses associated to it, even
> though the device will apparently not use it. Would it be possible to
> detect that the I/O range is not used by the device, and therefore
> avoid the allocation of an address decoding window for this I/O range?

I suspect it just gets disabled because the port number 0xc0010000 is
larger than IO_PORT_LIMIT and we cannot access that offset inside
of the virtual memory window we use for PIO.

	Arnd

^ permalink raw reply

* [PATCH v4 00/13] ARM LPAE Fixes - Part 1
From: Cyril Chemparathy @ 2013-02-01 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201151410.GR23505@n2100.arm.linux.org.uk>

On 02/01/2013 10:14 AM, Russell King - ARM Linux wrote:
> On Fri, Feb 01, 2013 at 10:10:37AM -0500, Cyril Chemparathy wrote:
>> With this, I ran simple network and filesystem performance tests to
>> compare the code-patching vs. non-code-patching variants.  These tests
>> didn't yield any significant performance difference between the two on
>> an ARMv7 (Cortex-A8) platform.
>
> It's not network and fs activity that this kind of stuff is likely to
> show up in, but more to do with walking pages tables and the like -
> remember that page tables are stored using physical addresses, and any
> walks of them have to convert those physical addresses to virtual
> addresses and back again.
>
> So, things like page scanning for eviction (eg, page aging, page
> faults even those which just re-use a page from the page cache) have
> to use the v:p / p:v translation macros.
>

Thanks, Russell.  Any recommendations on how to best benchmark this?

Thanks
-- Cyril.

^ permalink raw reply

* [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses
From: Catalin Marinas @ 2013-02-01 16:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359472036-7613-1-git-send-email-r.sricharan@ti.com>

On Tue, Jan 29, 2013 at 03:07:16PM +0000, R Sricharan wrote:
> With LPAE enabled, alloc_init_section() does not map the
> entire address space for unaligned addresses.
> 
> The issue also reproduced with CMA + LPAE. CMA tries to map 16MB
> with page granularity mappings during boot. alloc_init_pte()
> is called and out of 16MB, only 2MB gets mapped and rest remains
> unaccessible.
> 
> Because of this OMAP5 boot is broken with CMA + LPAE enabled.
> Fix the issue by ensuring that the entire addresses are
> mapped.
> 
> Signed-off-by: R Sricharan <r.sricharan@ti.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Christoffer Dall <chris@cloudcar.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Tested-by: Christoffer Dall  <chris@cloudcar.com>
> ---
>  [V2] Moved the loop to alloc_init_pte as per Russell's
>      feedback and changed the subject accordingly.
>      Using PMD_XXX instead of SECTION_XXX to avoid
>      different loop increments with/without LPAE.
> 
>  [v3] Removed the dummy variable phys and updated
>       the commit log for CMA case.
> 
>  [v4] Resending with updated change log and 
>       updating the tags.
> 
>  arch/arm/mm/mmu.c |   20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index f8388ad..b94c313 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -569,11 +569,23 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
>  				  unsigned long end, unsigned long pfn,
>  				  const struct mem_type *type)
>  {
> -	pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
> +	unsigned long next;
> +	pte_t *pte;
> +
>  	do {
> -		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
> -		pfn++;
> -	} while (pte++, addr += PAGE_SIZE, addr != end);
> +		if ((end-addr) & PMD_MASK)
> +			next = (addr + PMD_SIZE) & PMD_MASK;
> +		else
> +			next = end;

Can use pmd_addr_end(addr, end) here?

> +		pte = early_pte_alloc(pmd, addr, type->prot_l1);
> +		do {
> +			set_pte_ext(pte, pfn_pte(pfn,
> +					__pgprot(type->prot_pte)), 0);
> +			pfn++;
> +		} while (pte++, addr += PAGE_SIZE, addr != next);
> +
> +	} while (pmd++, addr = next, addr != end);

I would actually keep the loop in alloc_init_section(). There is even a
comment in there saying "no need to loop" but you actually moved the
loop in alloc_init_pte().

I'm proposing a simpler patch below (only lightly tested on VE/C-A9).
The only difference is that we do more flush_pmd_entry() calls but I'm
not really bothered, it's during boot and you won't notice.


diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 9c82f98..eaa8ba8 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -205,6 +205,11 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
 
 #define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
 
+#define section_addr_end(addr, end)						\
+({	unsigned long __boundary = ((addr) + SECTION_SIZE) & SECTION_MASK;	\
+	(__boundary - 1 < (end) - 1)? __boundary: (end);			\
+})
+
 #if __LINUX_ARM_ARCH__ < 6
 static inline void __sync_icache_dcache(pte_t pteval)
 {
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9f06102..0d0faed 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -581,34 +581,19 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 				      const struct mem_type *type)
 {
 	pmd_t *pmd = pmd_offset(pud, addr);
+	unsigned long next;
 
-	/*
-	 * Try a section mapping - end, addr and phys must all be aligned
-	 * to a section boundary.  Note that PMDs refer to the individual
-	 * L1 entries, whereas PGDs refer to a group of L1 entries making
-	 * up one logical pointer to an L2 table.
-	 */
-	if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
-		pmd_t *p = pmd;
-
-#ifndef CONFIG_ARM_LPAE
-		if (addr & SECTION_SIZE)
-			pmd++;
-#endif
-
-		do {
+	do {
+		next = section_addr_end(addr, end);
+		/* try section mapping first */
+		if (((addr | next | phys) & ~SECTION_MASK) == 0) {
 			*pmd = __pmd(phys | type->prot_sect);
-			phys += SECTION_SIZE;
-		} while (pmd++, addr += SECTION_SIZE, addr != end);
-
-		flush_pmd_entry(p);
-	} else {
-		/*
-		 * No need to loop; pte's aren't interested in the
-		 * individual L1 entries.
-		 */
-		alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
-	}
+			flush_pmd_entry(pmd);
+		} else {
+			alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
+		}
+		phys += next - addr;
+	} while (pmd++, addr = next, addr != end);
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,

^ permalink raw reply related

* [PATCH v2 19/27] pci: PCIe driver for Marvell Armada 370/XP systems
From: Russell King - ARM Linux @ 2013-02-01 16:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201302011607.49205.arnd@arndb.de>

On Fri, Feb 01, 2013 at 04:07:49PM +0000, Arnd Bergmann wrote:
> On Friday 01 February 2013, Thomas Petazzoni wrote:
> > So there is really a range of I/O addresses associated to it, even
> > though the device will apparently not use it. Would it be possible to
> > detect that the I/O range is not used by the device, and therefore
> > avoid the allocation of an address decoding window for this I/O range?
> 
> I suspect it just gets disabled because the port number 0xc0010000 is
> larger than IO_PORT_LIMIT and we cannot access that offset inside
> of the virtual memory window we use for PIO.

You're running into that trap again which you fall into on other
architectures.

If you arrange for your PCI IO space to start at 0 rather than the
physical address that it appears on your CPU, then you shouldn't
end up with it extending up to something at 0xcXXXXXXX.

Remember that we should be ensuring that inb(0) hits the first address
of the cross-subarch PCI IO area - this alway requires that any sub-arch
taking part in a multiplatform kernel must start its IO space addresses
at 0 and not the physical address on the local CPU.

^ permalink raw reply

* [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses
From: Christoffer Dall @ 2013-02-01 16:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201162631.GG5151@arm.com>

On Fri, Feb 1, 2013 at 11:26 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Tue, Jan 29, 2013 at 03:07:16PM +0000, R Sricharan wrote:
>> With LPAE enabled, alloc_init_section() does not map the
>> entire address space for unaligned addresses.
>>
>> The issue also reproduced with CMA + LPAE. CMA tries to map 16MB
>> with page granularity mappings during boot. alloc_init_pte()
>> is called and out of 16MB, only 2MB gets mapped and rest remains
>> unaccessible.
>>
>> Because of this OMAP5 boot is broken with CMA + LPAE enabled.
>> Fix the issue by ensuring that the entire addresses are
>> mapped.
>>
>> Signed-off-by: R Sricharan <r.sricharan@ti.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Christoffer Dall <chris@cloudcar.com>
>> Cc: Russell King <linux@arm.linux.org.uk>
>> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Tested-by: Christoffer Dall  <chris@cloudcar.com>
>> ---
>>  [V2] Moved the loop to alloc_init_pte as per Russell's
>>      feedback and changed the subject accordingly.
>>      Using PMD_XXX instead of SECTION_XXX to avoid
>>      different loop increments with/without LPAE.
>>
>>  [v3] Removed the dummy variable phys and updated
>>       the commit log for CMA case.
>>
>>  [v4] Resending with updated change log and
>>       updating the tags.
>>
>>  arch/arm/mm/mmu.c |   20 ++++++++++++++++----
>>  1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>> index f8388ad..b94c313 100644
>> --- a/arch/arm/mm/mmu.c
>> +++ b/arch/arm/mm/mmu.c
>> @@ -569,11 +569,23 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
>>                                 unsigned long end, unsigned long pfn,
>>                                 const struct mem_type *type)
>>  {
>> -     pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
>> +     unsigned long next;
>> +     pte_t *pte;
>> +
>>       do {
>> -             set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
>> -             pfn++;
>> -     } while (pte++, addr += PAGE_SIZE, addr != end);
>> +             if ((end-addr) & PMD_MASK)
>> +                     next = (addr + PMD_SIZE) & PMD_MASK;
>> +             else
>> +                     next = end;
>
> Can use pmd_addr_end(addr, end) here?
>
>> +             pte = early_pte_alloc(pmd, addr, type->prot_l1);
>> +             do {
>> +                     set_pte_ext(pte, pfn_pte(pfn,
>> +                                     __pgprot(type->prot_pte)), 0);
>> +                     pfn++;
>> +             } while (pte++, addr += PAGE_SIZE, addr != next);
>> +
>> +     } while (pmd++, addr = next, addr != end);
>
> I would actually keep the loop in alloc_init_section(). There is even a
> comment in there saying "no need to loop" but you actually moved the
> loop in alloc_init_pte().
>
> I'm proposing a simpler patch below (only lightly tested on VE/C-A9).
> The only difference is that we do more flush_pmd_entry() calls but I'm
> not really bothered, it's during boot and you won't notice.
>
>
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index 9c82f98..eaa8ba8 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -205,6 +205,11 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
>
>  #define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
>
> +#define section_addr_end(addr, end)                                            \
> +({     unsigned long __boundary = ((addr) + SECTION_SIZE) & SECTION_MASK;      \
> +       (__boundary - 1 < (end) - 1)? __boundary: (end);                        \
> +})
> +
>  #if __LINUX_ARM_ARCH__ < 6
>  static inline void __sync_icache_dcache(pte_t pteval)
>  {
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 9f06102..0d0faed 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -581,34 +581,19 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
>                                       const struct mem_type *type)
>  {
>         pmd_t *pmd = pmd_offset(pud, addr);
> +       unsigned long next;
>
> -       /*
> -        * Try a section mapping - end, addr and phys must all be aligned
> -        * to a section boundary.  Note that PMDs refer to the individual
> -        * L1 entries, whereas PGDs refer to a group of L1 entries making
> -        * up one logical pointer to an L2 table.
> -        */
> -       if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
> -               pmd_t *p = pmd;
> -
> -#ifndef CONFIG_ARM_LPAE
> -               if (addr & SECTION_SIZE)
> -                       pmd++;
> -#endif
> -
> -               do {
> +       do {
> +               next = section_addr_end(addr, end);
> +               /* try section mapping first */
> +               if (((addr | next | phys) & ~SECTION_MASK) == 0) {
>                         *pmd = __pmd(phys | type->prot_sect);
> -                       phys += SECTION_SIZE;
> -               } while (pmd++, addr += SECTION_SIZE, addr != end);
> -
> -               flush_pmd_entry(p);
> -       } else {
> -               /*
> -                * No need to loop; pte's aren't interested in the
> -                * individual L1 entries.
> -                */
> -               alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
> -       }
> +                       flush_pmd_entry(pmd);
> +               } else {
> +                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);

aren't you wasting memory here? The pte doesn't alloc a full page, but
the memblock allocator allocates a full page right?

I thought this was the rationale behind Russell's previous comments on
Santosh's earlier patch version.

> +               }
> +               phys += next - addr;
> +       } while (pmd++, addr = next, addr != end);
>  }
>
>  static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,

^ permalink raw reply

* [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses
From: Catalin Marinas @ 2013-02-01 16:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANOGCgOp=kSatDu8fL7grk+bXLQ2pgKAEvEK6LoG8Ba4mqUH=w@mail.gmail.com>

On Fri, Feb 01, 2013 at 04:32:54PM +0000, Christoffer Dall wrote:
> On Fri, Feb 1, 2013 at 11:26 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> > On Tue, Jan 29, 2013 at 03:07:16PM +0000, R Sricharan wrote:
> >> With LPAE enabled, alloc_init_section() does not map the
> >> entire address space for unaligned addresses.
> >>
> >> The issue also reproduced with CMA + LPAE. CMA tries to map 16MB
> >> with page granularity mappings during boot. alloc_init_pte()
> >> is called and out of 16MB, only 2MB gets mapped and rest remains
> >> unaccessible.
> >>
> >> Because of this OMAP5 boot is broken with CMA + LPAE enabled.
> >> Fix the issue by ensuring that the entire addresses are
> >> mapped.
> >>
> >> Signed-off-by: R Sricharan <r.sricharan@ti.com>
> >> Cc: Catalin Marinas <catalin.marinas@arm.com>
> >> Cc: Christoffer Dall <chris@cloudcar.com>
> >> Cc: Russell King <linux@arm.linux.org.uk>
> >> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> Tested-by: Christoffer Dall  <chris@cloudcar.com>
> >> ---
> >>  [V2] Moved the loop to alloc_init_pte as per Russell's
> >>      feedback and changed the subject accordingly.
> >>      Using PMD_XXX instead of SECTION_XXX to avoid
> >>      different loop increments with/without LPAE.
> >>
> >>  [v3] Removed the dummy variable phys and updated
> >>       the commit log for CMA case.
> >>
> >>  [v4] Resending with updated change log and
> >>       updating the tags.
> >>
> >>  arch/arm/mm/mmu.c |   20 ++++++++++++++++----
> >>  1 file changed, 16 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> >> index f8388ad..b94c313 100644
> >> --- a/arch/arm/mm/mmu.c
> >> +++ b/arch/arm/mm/mmu.c
> >> @@ -569,11 +569,23 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
> >>                                 unsigned long end, unsigned long pfn,
> >>                                 const struct mem_type *type)
> >>  {
> >> -     pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
> >> +     unsigned long next;
> >> +     pte_t *pte;
> >> +
> >>       do {
> >> -             set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
> >> -             pfn++;
> >> -     } while (pte++, addr += PAGE_SIZE, addr != end);
> >> +             if ((end-addr) & PMD_MASK)
> >> +                     next = (addr + PMD_SIZE) & PMD_MASK;
> >> +             else
> >> +                     next = end;
> >
> > Can use pmd_addr_end(addr, end) here?
> >
> >> +             pte = early_pte_alloc(pmd, addr, type->prot_l1);
> >> +             do {
> >> +                     set_pte_ext(pte, pfn_pte(pfn,
> >> +                                     __pgprot(type->prot_pte)), 0);
> >> +                     pfn++;
> >> +             } while (pte++, addr += PAGE_SIZE, addr != next);
> >> +
> >> +     } while (pmd++, addr = next, addr != end);
> >
> > I would actually keep the loop in alloc_init_section(). There is even a
> > comment in there saying "no need to loop" but you actually moved the
> > loop in alloc_init_pte().
> >
> > I'm proposing a simpler patch below (only lightly tested on VE/C-A9).
> > The only difference is that we do more flush_pmd_entry() calls but I'm
> > not really bothered, it's during boot and you won't notice.
> >
> >
> > diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> > index 9c82f98..eaa8ba8 100644
> > --- a/arch/arm/include/asm/pgtable.h
> > +++ b/arch/arm/include/asm/pgtable.h
> > @@ -205,6 +205,11 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
> >
> >  #define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
> >
> > +#define section_addr_end(addr, end)                                            \
> > +({     unsigned long __boundary = ((addr) + SECTION_SIZE) & SECTION_MASK;      \
> > +       (__boundary - 1 < (end) - 1)? __boundary: (end);                        \
> > +})
> > +
> >  #if __LINUX_ARM_ARCH__ < 6
> >  static inline void __sync_icache_dcache(pte_t pteval)
> >  {
> > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> > index 9f06102..0d0faed 100644
> > --- a/arch/arm/mm/mmu.c
> > +++ b/arch/arm/mm/mmu.c
> > @@ -581,34 +581,19 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
> >                                       const struct mem_type *type)
> >  {
> >         pmd_t *pmd = pmd_offset(pud, addr);
> > +       unsigned long next;
> >
> > -       /*
> > -        * Try a section mapping - end, addr and phys must all be aligned
> > -        * to a section boundary.  Note that PMDs refer to the individual
> > -        * L1 entries, whereas PGDs refer to a group of L1 entries making
> > -        * up one logical pointer to an L2 table.
> > -        */
> > -       if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
> > -               pmd_t *p = pmd;
> > -
> > -#ifndef CONFIG_ARM_LPAE
> > -               if (addr & SECTION_SIZE)
> > -                       pmd++;
> > -#endif
> > -
> > -               do {
> > +       do {
> > +               next = section_addr_end(addr, end);
> > +               /* try section mapping first */
> > +               if (((addr | next | phys) & ~SECTION_MASK) == 0) {
> >                         *pmd = __pmd(phys | type->prot_sect);
> > -                       phys += SECTION_SIZE;
> > -               } while (pmd++, addr += SECTION_SIZE, addr != end);
> > -
> > -               flush_pmd_entry(p);
> > -       } else {
> > -               /*
> > -                * No need to loop; pte's aren't interested in the
> > -                * individual L1 entries.
> > -                */
> > -               alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
> > -       }
> > +                       flush_pmd_entry(pmd);
> > +               } else {
> > +                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
> 
> aren't you wasting memory here? The pte doesn't alloc a full page, but
> the memblock allocator allocates a full page right?
> 
> I thought this was the rationale behind Russell's previous comments on
> Santosh's earlier patch version.

You are right, it's allocating more ptes. Than we can use pmd_addr_end.
I'll go back to the code.

-- 
Catalin

^ permalink raw reply

* [PATCH 0/2] ARM: OMAP2+: GPMC Fixes
From: Jon Hunter @ 2013-02-01 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

A couple GPMC fixes for OMAP2+ devices which were causing boot problems
on OMAP2420 H4.

Please note that long term we need to remove the cpu_is_omap24xx() from
the gpmc driver and pass the gpmc_mem_root information via platform data
and figure out a way to pass this information for device tree.

Boot tested on OMAP2420 H4, OMAP3430 SDP, OMAP4430 SDP and AM335x EVM.

Jon Hunter (2):
  ARM: OMAP2+: Prevent potential crash if GPMC probe fails
  ARM: OMAP2: Fix GPMC memory initialisation

 arch/arm/mach-omap2/gpmc.c |   31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH 1/2] ARM: OMAP2+: Prevent potential crash if GPMC probe fails
From: Jon Hunter @ 2013-02-01 16:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359736726-10193-1-git-send-email-jon-hunter@ti.com>

If the GPMC probe fails, devices that use the GPMC (such as ethernet
chips, flash memories, etc) can still allocate a GPMC chip-select and
register the device. On the OMAP2420 H4 board, this was causing the
kernel to crash after the gpmc probe failed and the board attempted
to start networking. Prevent this by marking all the chip-selects as
reserved by default and only make them available for devices to request
if the GPMC probe succeeds.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 8033cb7..441cc63 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -145,7 +145,8 @@ static unsigned gpmc_irq_start;
 static struct resource	gpmc_mem_root;
 static struct resource	gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
-static unsigned int gpmc_cs_map;	/* flag for cs which are initialized */
+/* Define chip-selects as reserved by default until probe completes */
+static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
 static struct device *gpmc_dev;
 static int gpmc_irq;
 static resource_size_t phys_base, mem_size;
@@ -1174,6 +1175,9 @@ static int gpmc_probe(struct platform_device *pdev)
 	if (IS_ERR_VALUE(gpmc_setup_irq()))
 		dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
 
+	/* Now the GPMC is initialised, unreserve the chip-selects */
+	gpmc_cs_map = 0;
+
 	return 0;
 }
 
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/2] ARM: OMAP2: Fix GPMC memory initialisation
From: Jon Hunter @ 2013-02-01 16:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359736726-10193-1-git-send-email-jon-hunter@ti.com>

OMAP2+ devices have an internal ROM that by default is typically mapped
to the first 1MB of the GPMC address space (0x0).

For OMAP24xx devices, GPMC chip-select 0 (CS0) may be mapped to address
0x0 instead of the internal ROM if configured for an external boot mode.
If configured for an internal boot mode then the internal ROM is mapped
to 0x0.

Currently, the function gpmc_mem_init() function reserves the first 1MB
of GPMC address space for the internal OMAP ROM with the exception of
the OMAP2 APOLLON board. This prevents any device (ethernet chip, flash
memories, etc) from using this address range. This causes the GPMC probe
to fail on the OMAP2420 H4 when NOR flash is mapped to address 0x0. Fix
this by testing the boot mode for OMAP24xx devices to see if the
SYS_BOOT3 is low, indicating an external boot, and thus GPMC CS0 is
mapped to 0x0.

Please note that for OMAP3-5 devices, when booting from NOR or NAND
memories connected to CS0, these memories are always mapped to address
0x08000000 and so reserving this memory range does not present any
problems for these devices.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/gpmc.c |   25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 441cc63..9486b8e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -32,6 +32,7 @@
 
 #include "soc.h"
 #include "common.h"
+#include "control.h"
 #include "omap_device.h"
 #include "gpmc.h"
 
@@ -778,18 +779,26 @@ static void gpmc_mem_exit(void)
 static int gpmc_mem_init(void)
 {
 	int cs, rc;
-	unsigned long boot_rom_space = 0;
 
-	/* never allocate the first page, to facilitate bug detection;
-	 * even if we didn't boot from ROM.
+	/*
+	 * The first 1MB of GPMC address space is mapped to the
+	 * internal ROM. OMAP2 devices are an exception to this
+	 * where the first 1MB may be mapped to the GPMC.
 	 */
-	boot_rom_space = BOOT_ROM_SPACE;
-	/* In apollon the CS0 is mapped as 0x0000 0000 */
-	if (machine_is_omap_apollon())
-		boot_rom_space = 0;
-	gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+	gpmc_mem_root.start = GPMC_MEM_START + BOOT_ROM_SPACE;
 	gpmc_mem_root.end = GPMC_MEM_END;
 
+	/*
+	 * OMAP2 devices that boot from external memory devices, will
+	 * map CS0 to the start of the GPMC address space (0x0). We can
+	 * test this by checking if SYS_BOOT3 pin is set. If not set
+	 * then CS0 is mapped to 0x0.
+	 */
+	if (cpu_is_omap24xx())
+		if (!(omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
+		      OMAP2_SYSBOOT_3_MASK))
+			gpmc_mem_root.start = GPMC_MEM_START;
+
 	/* Reserve all regions that has been set up by bootloader */
 	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
 		u32 base, size;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCHv2 for soc 4/4] arm: socfpga: Add SMP support for actual socfpga harware
From: Dinh Nguyen @ 2013-02-01 16:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201153152.GS23505@n2100.arm.linux.org.uk>

On Fri, 2013-02-01 at 15:31 +0000, Russell King - ARM Linux wrote:
> On Fri, Feb 01, 2013 at 07:27:46AM -0800, Dinh Nguyen wrote:
> > Hi Olof,
> > On Fri, 2013-02-01 at 11:46 +0100, ZY - pavel wrote:
> > > Hi!
> > >
> > > > > Because the CPU1 start address is different for socfpga-vt and
> > > > > socfpga-cyclone5, we add code to use the correct CPU1 start addr.
> > >
> > > > > @@ -72,6 +73,13 @@ void __init socfpga_sysmgr_init(void)
> > > > >   struct device_node *np;
> > > > >
> > > > >   np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
> > > > > +
> > > > > + if (of_property_read_u32(np, "cpu1-start-addr",
> > > > > +                 (u32 *) &cpu1start_addr)) {
> > > > > +         early_printk("Need cpu1-start-addr in device tree.\n");
> > > > > +         panic("Need cpu1-start-addr in device tree.\n");
> > > > > + }
> > > > > +
> > > > >   sys_manager_base_addr = of_iomap(np, 0);
> > > >
> > > > Wouldn't it be easier to diagnose this failure if you just printed the error
> > > > and continued booting without the second CPU? An early panic is usually really
> > > > hard to debug since you might not get early console without extra work.
> > >
> > > I actually thought about that... but could not think of non-ugly way
> > > of doing that. I hope dts will normally be "right" for any production
> > > system...
> > 
> > I think a panic is better just for the reason that if someone is
> > expecting SMP, but missed the warning message, and later finds out that
> > the secondary core never came up, it would save some debugging time.
> > 
> > Since I have to send out a v3 from the 1st patch anyways, let me verify
> > that I can get the early warning.
> 
> The choice is between a panic() at a point where the only way to find
> out is to throw in printascii() or a working printk, and ending up with
> an unbootable kernel, vs continuing the boot and having an almost
> working system which can be logged into and the messages viewed.
> 
> If you have an application which relies on the second CPU coming up,
> why not have it verify that the second CPU came up (it's quite easy
> to do - there's POSIX standard libc calls to get the number of online
> CPUs).

Point taken...thanks Russell.

Dinh
> 

^ permalink raw reply

* [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses
From: Christoffer Dall @ 2013-02-01 16:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201163722.GH5151@arm.com>

On Fri, Feb 1, 2013 at 11:37 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Fri, Feb 01, 2013 at 04:32:54PM +0000, Christoffer Dall wrote:
>> On Fri, Feb 1, 2013 at 11:26 AM, Catalin Marinas
>> <catalin.marinas@arm.com> wrote:
>> > On Tue, Jan 29, 2013 at 03:07:16PM +0000, R Sricharan wrote:
>> >> With LPAE enabled, alloc_init_section() does not map the
>> >> entire address space for unaligned addresses.
>> >>
>> >> The issue also reproduced with CMA + LPAE. CMA tries to map 16MB
>> >> with page granularity mappings during boot. alloc_init_pte()
>> >> is called and out of 16MB, only 2MB gets mapped and rest remains
>> >> unaccessible.
>> >>
>> >> Because of this OMAP5 boot is broken with CMA + LPAE enabled.
>> >> Fix the issue by ensuring that the entire addresses are
>> >> mapped.
>> >>
>> >> Signed-off-by: R Sricharan <r.sricharan@ti.com>
>> >> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> >> Cc: Christoffer Dall <chris@cloudcar.com>
>> >> Cc: Russell King <linux@arm.linux.org.uk>
>> >> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> >> Tested-by: Christoffer Dall  <chris@cloudcar.com>
>> >> ---
>> >>  [V2] Moved the loop to alloc_init_pte as per Russell's
>> >>      feedback and changed the subject accordingly.
>> >>      Using PMD_XXX instead of SECTION_XXX to avoid
>> >>      different loop increments with/without LPAE.
>> >>
>> >>  [v3] Removed the dummy variable phys and updated
>> >>       the commit log for CMA case.
>> >>
>> >>  [v4] Resending with updated change log and
>> >>       updating the tags.
>> >>
>> >>  arch/arm/mm/mmu.c |   20 ++++++++++++++++----
>> >>  1 file changed, 16 insertions(+), 4 deletions(-)
>> >>
>> >> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>> >> index f8388ad..b94c313 100644
>> >> --- a/arch/arm/mm/mmu.c
>> >> +++ b/arch/arm/mm/mmu.c
>> >> @@ -569,11 +569,23 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
>> >>                                 unsigned long end, unsigned long pfn,
>> >>                                 const struct mem_type *type)
>> >>  {
>> >> -     pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
>> >> +     unsigned long next;
>> >> +     pte_t *pte;
>> >> +
>> >>       do {
>> >> -             set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
>> >> -             pfn++;
>> >> -     } while (pte++, addr += PAGE_SIZE, addr != end);
>> >> +             if ((end-addr) & PMD_MASK)
>> >> +                     next = (addr + PMD_SIZE) & PMD_MASK;
>> >> +             else
>> >> +                     next = end;
>> >
>> > Can use pmd_addr_end(addr, end) here?
>> >
>> >> +             pte = early_pte_alloc(pmd, addr, type->prot_l1);
>> >> +             do {
>> >> +                     set_pte_ext(pte, pfn_pte(pfn,
>> >> +                                     __pgprot(type->prot_pte)), 0);
>> >> +                     pfn++;
>> >> +             } while (pte++, addr += PAGE_SIZE, addr != next);
>> >> +
>> >> +     } while (pmd++, addr = next, addr != end);
>> >
>> > I would actually keep the loop in alloc_init_section(). There is even a
>> > comment in there saying "no need to loop" but you actually moved the
>> > loop in alloc_init_pte().
>> >
>> > I'm proposing a simpler patch below (only lightly tested on VE/C-A9).
>> > The only difference is that we do more flush_pmd_entry() calls but I'm
>> > not really bothered, it's during boot and you won't notice.
>> >
>> >
>> > diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
>> > index 9c82f98..eaa8ba8 100644
>> > --- a/arch/arm/include/asm/pgtable.h
>> > +++ b/arch/arm/include/asm/pgtable.h
>> > @@ -205,6 +205,11 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
>> >
>> >  #define pte_present_user(pte)  (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
>> >
>> > +#define section_addr_end(addr, end)                                            \
>> > +({     unsigned long __boundary = ((addr) + SECTION_SIZE) & SECTION_MASK;      \
>> > +       (__boundary - 1 < (end) - 1)? __boundary: (end);                        \
>> > +})
>> > +
>> >  #if __LINUX_ARM_ARCH__ < 6
>> >  static inline void __sync_icache_dcache(pte_t pteval)
>> >  {
>> > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>> > index 9f06102..0d0faed 100644
>> > --- a/arch/arm/mm/mmu.c
>> > +++ b/arch/arm/mm/mmu.c
>> > @@ -581,34 +581,19 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
>> >                                       const struct mem_type *type)
>> >  {
>> >         pmd_t *pmd = pmd_offset(pud, addr);
>> > +       unsigned long next;
>> >
>> > -       /*
>> > -        * Try a section mapping - end, addr and phys must all be aligned
>> > -        * to a section boundary.  Note that PMDs refer to the individual
>> > -        * L1 entries, whereas PGDs refer to a group of L1 entries making
>> > -        * up one logical pointer to an L2 table.
>> > -        */
>> > -       if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
>> > -               pmd_t *p = pmd;
>> > -
>> > -#ifndef CONFIG_ARM_LPAE
>> > -               if (addr & SECTION_SIZE)
>> > -                       pmd++;
>> > -#endif
>> > -
>> > -               do {
>> > +       do {
>> > +               next = section_addr_end(addr, end);
>> > +               /* try section mapping first */
>> > +               if (((addr | next | phys) & ~SECTION_MASK) == 0) {
>> >                         *pmd = __pmd(phys | type->prot_sect);
>> > -                       phys += SECTION_SIZE;
>> > -               } while (pmd++, addr += SECTION_SIZE, addr != end);
>> > -
>> > -               flush_pmd_entry(p);
>> > -       } else {
>> > -               /*
>> > -                * No need to loop; pte's aren't interested in the
>> > -                * individual L1 entries.
>> > -                */
>> > -               alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
>> > -       }
>> > +                       flush_pmd_entry(pmd);
>> > +               } else {
>> > +                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
>>
>> aren't you wasting memory here? The pte doesn't alloc a full page, but
>> the memblock allocator allocates a full page right?
>>
>> I thought this was the rationale behind Russell's previous comments on
>> Santosh's earlier patch version.
>
> You are right, it's allocating more ptes. Than we can use pmd_addr_end.
> I'll go back to the code.
>
don't get me wrong, I strongly prefer keeping that loop in
alloc_init_section, the other way it was weird to read, felt like
shoehorning something, but you may have to keep a pointer around for
unused part of a page for pte or something, not sure what ends up
being nicest.

-Christoffer

^ permalink raw reply

* [RFC PATCH] arm: decompressor: initialize PIC offset base register for uClinux tools
From: Jonathan Austin @ 2013-02-01 16:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301291453530.6300@xanadu.home>

Hi Nicolas, thanks for the comments,

On 29/01/13 20:13, Nicolas Pitre wrote:
> On Tue, 29 Jan 2013, Jonathan Austin wrote:
> 
>> Before jumping to (position independent) C-code from the decompressor's
>> assembler world we set-up the C environment. This setup currently does not
>> set r9, which for arm-none-uclinux-uclibceabi should be the PIC offset base
>> register (IE should point to the beginning of the GOT).
>>
>> Currently, therefore, in order to build working kernels that use the
>> decompressor it is necessary to use an arm-linux-gnueabi toolchain, or
>> similar. uClinux toolchains cause a Prefetch Abort to occur at the beginning
>> of the decompress_kernel function.
>>
>> This patch allows uClinux toolchains to build bootable zImages by setting r9
>> to the beginning of the GOT when __uClinux__ is defined, allowing the
>> decompressor's C functions to work correctly.
>>
>> Signed-off-by: Jonathan Austin <jonathan.austin@arm.com>
>> ---
>>
>> One other possibility would be to specify -mno-single-pic-base when building
>> the decompressor. This works around the problem, but forces the compiler to
>> generate less optimal code.
> 
> How "less optimal"?  How much bigger/slower is it?
> If not significant enough then going with -mno-single-pic-base might be
> fine.

Code that needs to access anything global will need to derive the location
of the GOT for itself, but there's a possible upside there that there's an
extra free register (r9 can be used as a general purpose register...)

The patch would look like:
-----8<-------
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 5cad8a6..afed28e 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 -ccflags-y := -fpic -fno-builtin -I$(obj)
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
 asflags-y := -Wa,-march=all -DZIMAGE
  # Supply kernel BSS size to the decompressor via a linker symbol.
------>8---------


I did a fairly crude benchmark - count how many instructions we need in
order to finish decompressing the kernel...

Setup r9 correctly:       129,976,282
Use -mno-single-pic-base: 124,826,778

(this was done using an R-class model and a magic semi-hosting call to pause
the model at the end of the decompress_kernel function)

So, it seems like the extra register means there's actually a 4% *win* 
in instruction terms from using -mno-single-pic-base

That said, I've still made some comments/amendments below...

> 
>>   arch/arm/boot/compressed/head.S |    4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index fe4d9c3..4491e75 100644
>> --- a/arch/arm/boot/compressed/head.S
>> +++ b/arch/arm/boot/compressed/head.S
>> @@ -410,6 +410,10 @@ wont_overwrite:
>>    *   sp  = stack pointer
>>    */
>>   		orrs	r1, r0, r5
>> +#ifdef __uClinux__
>> +		mov	r9, r11			@ PIC offset base register
>> +		addne	r9, r9, r0		@ Also needs relocating
>> +#endif
>>   		beq	not_relocated
> 
> Please don't insert your code between the orrs and the beq as those two
> go logically together.

I'd initially done this in order to change only one site - as we need to
set r9 and then add the offset I was using the condition code to test r0...

However, this was silly - I think I can just do it in one instruction:

add   r9, r11, r0

In the case that we're not relocated, r0 should be 0 anyway...

> 
> In fact, the best location for this would probably be between the
> wont_overwrite label and the comment that immediately follows it. And
> then, those comments that follow until the branch into C code should be
> updated accordingly.


Okay, assuming I've understood you correctly, you're suggesting something
like this:

-----8<-------

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index fe4d9c3..d81efbd 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -396,6 +396,9 @@ dtb_check_done:
                mov     pc, r0
  wont_overwrite:
+#ifdef __uClinux__
+               add     r9, r11, r0             @ uClinux PIC offset base register
+#endif
 /*
  * If delta is zero, we are running@the address we were linked at.
  *   r0  = delta
@@ -405,6 +408,7 @@ wont_overwrite:
  *   r5  = appended dtb size (0 if not present)
  *   r7  = architecture ID
  *   r8  = atags pointer
+ *   r9  = GOT start (for uClinux ABI), relocated
  *   r11 = GOT start
  *   r12 = GOT end
  *   sp  = stack pointer
@@ -470,6 +474,7 @@ not_relocated:      mov     r0, #0
  *   r4  = kernel execution address
  *   r7  = architecture ID
  *   r8  = atags pointer
+ *   r9  = GOT start (for uClinux ABI)
  */
                mov     r0, r4
                mov     r1, sp                  @ malloc space above stack
------->8-----------


The question that now occurs is whether we should just set r9 whether or not
we're using a uClinux toolchain - I don't think it is going to hurt as the
arm-linux-gnueabi world can happily clobber it with no bad consequences...

But after all this, it seems that just using -mno-single-pic base as in the patch
above is best...

Thoughts?

Jonny

^ permalink raw reply related

* [PATCH V2 1/6] pinctrl: pinctrl-single: use arch_initcall and module_exit
From: Tony Lindgren @ 2013-02-01 17:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdbf7TwrjfT2rhqQFGc3yh_Nt117RtzQO2y6g5Ddx5Ay_w@mail.gmail.com>

* Linus Walleij <linus.walleij@linaro.org> [130129 03:03]:
> On Tue, Jan 29, 2013 at 8:38 AM, Vishwanathrao Badarkhe, Manish
> <manishv.b@ti.com> wrote:
> 
> > Currently, I2C driver gets probed before pinctrl driver.
> > To achieve I2C pin muxing via pinctrl driver before I2C
> > probe get called, register pinctrl driver in arch_initcall.
> > Also, add module_exit to unregister pinctrl driver.
> >
> > Signed-off-by: Vishwanathrao Badarkhe, Manish <manishv.b@ti.com>
> 
> So your I2C driver is not returning -EPROBE_DEFER
> if it cannot find its pins?
> 
> Hm, well I can live with this, if Tony ACKs it.

Hmm pinctrl is before i2c in drivers/Makefile.
Making initcalls happen earlier and earlier is usually the
wrong way to go. Sounds like there's some other issue here
that needs to be fixed instead.

Regards,

Tony

^ permalink raw reply

* [PATCH V2 1/6] pinctrl: pinctrl-single: use arch_initcall and module_exit
From: Tony Lindgren @ 2013-02-01 17:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201170906.GE22517@atomide.com>

* Tony Lindgren <tony@atomide.com> [130201 09:12]:
> * Linus Walleij <linus.walleij@linaro.org> [130129 03:03]:
> > On Tue, Jan 29, 2013 at 8:38 AM, Vishwanathrao Badarkhe, Manish
> > <manishv.b@ti.com> wrote:
> > 
> > > Currently, I2C driver gets probed before pinctrl driver.
> > > To achieve I2C pin muxing via pinctrl driver before I2C
> > > probe get called, register pinctrl driver in arch_initcall.
> > > Also, add module_exit to unregister pinctrl driver.
> > >
> > > Signed-off-by: Vishwanathrao Badarkhe, Manish <manishv.b@ti.com>
> > 
> > So your I2C driver is not returning -EPROBE_DEFER
> > if it cannot find its pins?
> > 
> > Hm, well I can live with this, if Tony ACKs it.
> 
> Hmm pinctrl is before i2c in drivers/Makefile.
> Making initcalls happen earlier and earlier is usually the
> wrong way to go. Sounds like there's some other issue here
> that needs to be fixed instead.

Let me guess: The i2c driver is wrongly set to run with
arch_initcall?
 
> Regards,
> 
> Tony
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply

* [PATCH v3 11/15] ARM: vexpress/dcscb: do not hardcode number of CPUs per cluster
From: Nicolas Pitre @ 2013-02-01 17:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510B5942.20307@ti.com>

On Fri, 1 Feb 2013, Santosh Shilimkar wrote:

> On Tuesday 29 January 2013 01:21 PM, Nicolas Pitre wrote:
> > If 4 CPUs are assumed, the A15x1-A7x1 model configuration would never
> > shut down the initial cluster as the 0xf reset bit mask will never be
> > observed.  Let's construct this mask based on the provided information
> > in the DCSCB config register for the number of CPUs per cluster.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> >   arch/arm/mach-vexpress/dcscb.c | 14 ++++++++++----
> >   1 file changed, 10 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c
> > index f993608944..8d363357ef 100644
> > --- a/arch/arm/mach-vexpress/dcscb.c
> > +++ b/arch/arm/mach-vexpress/dcscb.c
> > @@ -46,10 +46,12 @@ static arch_spinlock_t dcscb_lock =
> > __ARCH_SPIN_LOCK_UNLOCKED;
> > 
> >   static void __iomem *dcscb_base;
> >   static int dcscb_use_count[4][2];
> > +static int dcscb_mcpm_cpu_mask[2];
> s/2/MAX_CLUSTERS ?

No.  The DCSCB (*dual* cluster system control block) does manage only 2 
clusters, regardless of the MAX_CLUSTERS definition which might increase 
in the future.

> Apart from above minor question,
> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 

^ permalink raw reply

* [PATCH v3 03/15] ARM: mcpm: introduce helpers for platform coherency exit/setup
From: Nicolas Pitre @ 2013-02-01 17:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510B4E2B.1030104@ti.com>

On Fri, 1 Feb 2013, Santosh Shilimkar wrote:

> On Thursday 31 January 2013 10:46 PM, Nicolas Pitre wrote:
> > On Thu, 31 Jan 2013, Santosh Shilimkar wrote:
> > 
> > > On Tuesday 29 January 2013 01:20 PM, Nicolas Pitre wrote:
> > > > From: Dave Martin <dave.martin@linaro.org>
> > > > 
> > > > This provides helper methods to coordinate between CPUs coming down
> > > > and CPUs going up, as well as documentation on the used algorithms,
> > > > so that cluster teardown and setup
> > > > operations are not done for a cluster simultaneously.
> > > > 
> > > > For use in the power_down() implementation:
> > > >     * __mcpm_cpu_going_down(unsigned int cluster, unsigned int cpu)
> > > >     * __mcpm_outbound_enter_critical(unsigned int cluster)
> > > >     * __mcpm_outbound_leave_critical(unsigned int cluster)
> > > >     * __mcpm_cpu_down(unsigned int cluster, unsigned int cpu)
> > > > 
> > > > The power_up_setup() helper should do platform-specific setup in
> > > > preparation for turning the CPU on, such as invalidating local caches
> > > > or entering coherency.  It must be assembler for now, since it must
> > > > run before the MMU can be switched on.  It is passed the affinity level
> > > > which should be initialized.
> > > > 
> > > > Because the mcpm_sync_struct content is looked-up and modified
> > > > with the cache enabled or disabled depending on the code path, it is
> > > > crucial to always ensure proper cache maintenance to update main memory
> > > > right away.  Therefore, any cached write must be followed by a cache
> > > > clean operation and any cached read must be preceded by a cache
> > > > invalidate operation (actually a cache flush i.e. clean+invalidate to
> > > > avoid discarding possible concurrent writes) on the accessed memory.
> > > > 
> > > > Also, in order to prevent a cached writer from interfering with an
> > > > adjacent non-cached writer, we ensure each state variable is located to
> > > > a separate cache line.
> > > > 
> > > > Thanks to Nicolas Pitre and Achin Gupta for the help with this
> > > > patch.
> > > > 
> > > > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > > > ---
> > > [..]
> > > 
> > > > diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c
> > > > index c8c0e2113e..2b83121966 100644
> > > > --- a/arch/arm/common/mcpm_entry.c
> > > > +++ b/arch/arm/common/mcpm_entry.c
> > > > @@ -18,6 +18,7 @@
> > > >    #include <asm/proc-fns.h>
> > > >    #include <asm/cacheflush.h>
> > > >    #include <asm/idmap.h>
> > > > +#include <asm/cputype.h>
> > > > 
> > > >    extern volatile unsigned long
> > > > mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER];
> > > > 
> > > [...]
> > > 
> > > > +/*
> > > > + * Ensure preceding writes to *p by other CPUs are visible to
> > > > + * subsequent reads by this CPU.  We must be careful not to
> > > > + * discard data simultaneously written by another CPU, hence the
> > > > + * usage of flush rather than invalidate operations.
> > > > + */
> > > > +static void __sync_range_r(volatile void *p, size_t size)
> > > > +{
> > > > +	char *_p = (char *)p;
> > > > +
> > > > +#ifdef CONFIG_OUTER_CACHE
> > > > +	if (outer_cache.flush_range) {
> > > > +
> > > You don't need above #ifdef. In case of non-outer
> > > cache the function pointer is null anyways.
> > 
> > We do need the #ifdef, because if CONFIG_OUTER_CACHE is not selected
> > then the outer_cache structure simply doesn't exist.
> > 
> You are right. #ifdef in middle of the code looks bit ugly and hence
> was thinking to avoid it.
> 
> > > 		/*
> > > > +		 * Ensure dirty data migrated from other CPUs into our cache
> > > > +		 * are cleaned out safely before the outer cache is cleaned:
> > > > +		 */
> > > > +		__cpuc_clean_dcache_area(_p, size);
> > > > +
> > > > +		/* Clean and invalidate stale data for *p from outer ... */
> > > > +		outer_flush_range(__pa(_p), __pa(_p + size));
> > > > +	}
> > > > +#endif
> > > > +
> > > > +	/* ... and inner cache: */
> > > > +	__cpuc_flush_dcache_area(_p, size);
> > > This will be un-necessary when inner cache is available, no ?
> > > May be you can re-arrange the code like below, unless and until
> > > you would like to invalidate any speculative fetches during the
> > > outer_flush_range()
> > > 
> > > 	__cpuc_clean_dcache_area(_p, size);
> > > 	if (outer_cache.flush_range)
> > > 		outer_flush_range(__pa(_p), __pa(_p + size));
> > 
> > As you said, the code is sequenced that way to get rid of potential
> > speculative fetch that could happen right before L2 is flushed.
> > 
> Thanks for clarifying it. It makes sense.

May I translate this into an ACK tag?  ;-)


Nicolas

^ permalink raw reply

* [PATCH v3 07/15] ARM: vexpress: Select the correct SMP operations at run-time
From: Nicolas Pitre @ 2013-02-01 17:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510B5584.6020800@ti.com>

On Fri, 1 Feb 2013, Santosh Shilimkar wrote:

> On Tuesday 29 January 2013 01:21 PM, Nicolas Pitre wrote:
> > From: Jon Medhurst <tixy@linaro.org>
> > 
> The patch deserves couple of lines of description here.

Yes, Tixy has split it into 2 patches with proper description which 
should be part of the next round.


> 
> > Signed-off-by: Jon Medhurst <tixy@linaro.org>
> > ---
> >   arch/arm/include/asm/mach/arch.h |  3 +++
> >   arch/arm/kernel/setup.c          |  5 ++++-
> >   arch/arm/mach-vexpress/core.h    |  2 ++
> >   arch/arm/mach-vexpress/platsmp.c | 12 ++++++++++++
> >   arch/arm/mach-vexpress/v2m.c     |  2 +-
> >   5 files changed, 22 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/include/asm/mach/arch.h
> > b/arch/arm/include/asm/mach/arch.h
> > index 917d4fcfd9..3d01c6d6c3 100644
> > --- a/arch/arm/include/asm/mach/arch.h
> > +++ b/arch/arm/include/asm/mach/arch.h
> > @@ -17,8 +17,10 @@ struct pt_regs;
> >   struct smp_operations;
> >   #ifdef CONFIG_SMP
> >   #define smp_ops(ops) (&(ops))
> > +#define smp_init_ops(ops) (&(ops))
> >   #else
> >   #define smp_ops(ops) (struct smp_operations *)NULL
> > +#define smp_init_ops(ops) (void (*)(void))NULL
> >   #endif
> > 
> >   struct machine_desc {
> > @@ -42,6 +44,7 @@ struct machine_desc {
> >   	unsigned char		reserve_lp2 :1;	/* never has lp2	*/
> >   	char			restart_mode;	/* default restart mode	*/
> >   	struct smp_operations	*smp;		/* SMP operations	*/
> > +	void			(*smp_init)(void);
> >   	void			(*fixup)(struct tag *, char **,
> >   					 struct meminfo *);
> >   	void			(*reserve)(void);/* reserve mem blocks	*/
> > diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> > index 3f6cbb2e3e..41edca8582 100644
> > --- a/arch/arm/kernel/setup.c
> > +++ b/arch/arm/kernel/setup.c
> > @@ -768,7 +768,10 @@ void __init setup_arch(char **cmdline_p)
> >   	arm_dt_init_cpu_maps();
> >   #ifdef CONFIG_SMP
> >   	if (is_smp()) {
> > -		smp_set_ops(mdesc->smp);
> > +		if(mdesc->smp_init)
> > +			(*mdesc->smp_init)();
> > +		else
> > +			smp_set_ops(mdesc->smp);
> >   		smp_init_cpus();
> >   	}
> >   #endif
> > diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
> > index f134cd4a85..3a761fd76c 100644
> > --- a/arch/arm/mach-vexpress/core.h
> > +++ b/arch/arm/mach-vexpress/core.h
> > @@ -6,6 +6,8 @@
> > 
> >   void vexpress_dt_smp_map_io(void);
> > 
> > +void vexpress_smp_init_ops(void);
> > +
> >   extern struct smp_operations	vexpress_smp_ops;
> > 
> >   extern void vexpress_cpu_die(unsigned int cpu);
> > diff --git a/arch/arm/mach-vexpress/platsmp.c
> > b/arch/arm/mach-vexpress/platsmp.c
> > index c5d70de9bb..667344b479 100644
> > --- a/arch/arm/mach-vexpress/platsmp.c
> > +++ b/arch/arm/mach-vexpress/platsmp.c
> > @@ -12,6 +12,7 @@
> >   #include <linux/errno.h>
> >   #include <linux/smp.h>
> >   #include <linux/io.h>
> > +#include <linux/of.h>
> >   #include <linux/of_fdt.h>
> >   #include <linux/vexpress.h>
> > 
> > @@ -206,3 +207,14 @@ struct smp_operations __initdata vexpress_smp_ops = {
> >   	.cpu_die		= vexpress_cpu_die,
> >   #endif
> >   };
> > +
> > +void __init vexpress_smp_init_ops(void)
> > +{
> > +	struct smp_operations *ops = &vexpress_smp_ops;
> > +#ifdef CONFIG_CLUSTER_PM
> See if you can avoid this #ifdef in the middle of function.
> 
> Reviewed-by: Santosh Shilimkar<santosh.shilimkar@ti.com>
> 

^ permalink raw reply

* [PATCH v4 02/13] ARM: LPAE: use phys_addr_t in alloc_init_pud()
From: Subash Patel @ 2013-02-01 17:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301312218270.6300@xanadu.home>

Hi Nicolas,

On Thursday 31 January 2013 07:35 PM, Nicolas Pitre wrote:
> On Fri, 1 Feb 2013, Hui Wang wrote:
>
>> Cyril Chemparathy wrote:
>>> From: Vitaly Andrianov <vitalya@ti.com>
>>>
>>> This patch fixes the alloc_init_pud() function to use phys_addr_t instead of
>>> unsigned long when passing in the phys argument.
>>>
>>> This is an extension to commit 97092e0c56830457af0639f6bd904537a150ea4a
>>> (ARM:
>>> pgtable: use phys_addr_t for physical addresses), which applied similar
>>> changes
>>> elsewhere in the ARM memory management code.
>>>
>>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>>> Signed-off-by: Cyril Chemparathy <cyril@ti.com>
>>> Acked-by: Nicolas Pitre <nico@linaro.org>
>>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>>> ---
>>>   arch/arm/mm/mmu.c |    3 ++-
>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>>> index 9f06102..ef43689 100644
>>> --- a/arch/arm/mm/mmu.c
>>> +++ b/arch/arm/mm/mmu.c
>>> @@ -612,7 +612,8 @@ static void __init alloc_init_section(pud_t *pud,
>>> unsigned long addr,
>>>   }
>>>    static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
>>> -	unsigned long end, unsigned long phys, const struct mem_type *type)
>>> +				  unsigned long end, phys_addr_t phys,
>>> +				  const struct mem_type *type)
>>>
>> The change is correct but seems useless so far. This function only be called
>> from map_lowmem and devicemaps_init, from i know neither lowmem nor device io
>> registers of existing platforms exceed 32bit address.
>
> It is not because you are not aware of any existing platforms with RAM
> or device IO above the 4GB mark that they don't exist.
>
> For example, some LPAE systems have all their RAM located above the 4G
> physical address mark. A simple (potentially non DMA capable) alias
> exists in the low 32-bit address space to allow the system to boot and
> switch to the real physical RAM addresses once the MMU is turned on.
> Some of that RAM is still qualified as "low mem" i.e. the portion of RAM
> that the kernel keeps permanently mapped in the 32-bit virtual space
> even if all of it is above the 4G mark in physical space.

I think he is right. You cannot have low_mem and devices in 36-bit 
areas. Atleast this is what I saw in one of the platforms on which I 
tested these patches. I am not sure what you mean by hardware address 
aliasing(as I have real RAM), but we need 32-bit areas to boot the CPU 
and I have mapped them for the LOW_MEM. But, I have used 36-bit areas 
for the HIGH_MEM. Since you said about aliasing DDR area in 32-bits, and 
then switching to 36-bit RAM, does the dma of the devices still use 
32-bit aliased addresses?

I haven't tested a configuration where LOW_MEM can have both 32-bit and 
36-bit DDR PA though. I think its not possible too.

Regards,
Subash


>
>
> Nicolas
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply

* [PATCH 00/15] OMAP SHAM & AES Crypto Updates
From: Paul Walmsley @ 2013-02-01 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130128191635.GA14158@animalcreek.com>

Hi Mark

On Mon, 28 Jan 2013, Mark A. Greer wrote:

> On Thu, Jan 17, 2013 at 03:27:28PM -0700, Mark A. Greer wrote:
> > On Thu, Jan 17, 2013 at 07:13:36PM +0000, Paul Walmsley wrote:
> > > On Tue, 8 Jan 2013, Mark A. Greer wrote:
> > > 
> > > > On Sun, Dec 23, 2012 at 08:40:43AM +0000, Paul Walmsley wrote:
> 
> > > What do you think about adding an am35xx_es11plus_hwmod_ocp_ifs[] array to 
> > > omap_hwmod_3xxx_data.c for these secure hwmods?  That carries the implicit 
> > > and possibly wrong assumption that it's likely to be ES1.0 devices that 
> > > are missing the SHAM/AES, but it seems unlikely that TI would have 
> > > multiple silicon revs running around claiming to be ES1.1?  Or maybe I'm 
> > > just being na?ve.
> > 
> > Something like that makes sense to me.  I'll re-read my email, etc. and
> > see if I can find something to help us figure it out.
> 
> I couldn't find any information that helped with this so AFAIK there is no
> good way to tell if a particular am35xx has the crypto hardware available
> or not.

I was thinking that we might assume that they are present on AM35xx 
ES1.1+.  If the TI folks are saying that they aren't available on only a 
few early devices, I'd guess that means ES1.0.  I personally have never 
seen an ES1.0 AM35xx device... 

Discriminating between ES1.0 and ES1.1+ should be pretty easy in the hwmod 
init...

>  At this point, I vote for moving 'omap3xxx_l4_core__sham' and
> 'omap3xxx_l4_core__aes' from omap3xxx_gp_hwmod_ocp_ifs[] and putting them
> in omap34xx_hwmod_ocp_ifs[] and omap36xx_hwmod_ocp_ifs[].  

I'm pretty sure that's going to break on HS OMAPs, like the HS OMAP3430 in 
the N900.  I don't think those IP blocks are directly accessible from 
Linux on most HS setups, although this might vary by device.  I'd feel 
more comfortable if you created an omap34xx_gp_hwmod_ocp_ifs[] list and an 
omap36xx_gp_hwmod_ocp_ifs[] list.  We should probably get rid of 
omap3xxx_gp_hwmod_ocp_ifs[] altogether.

> That should be safe in general and if someone with an am35xx wants to 
> use those modules, they can edit am35xx_hwmod_ocp_ifs[] locally.

If you want to just leave them commented in am35xx_hwmod_ocp_ifs[], rather 
than enabling them for ES1.1+ AM35xx, that's fine with me too, since we 
don't know that they are ES-level-based.  Maybe put a comment there that 
says that these are likely to be present, but no one seems to know for 
certain?  Seems ludicrous, but I guess that's what we're reduced to!


- Paul

^ permalink raw reply

* [PATCH 5/5] s5p-fimc: Redefine platform data structure for fimc-is
From: Kukjin Kim @ 2013-02-01 17:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <510BA174.1010602@samsung.com>

Sylwester Nawrocki wrote:
> 
> On 01/30/2013 06:23 PM, Sylwester Nawrocki wrote:
> > Newer Exynos4 SoC are equipped with a local camera ISP that
> > controls external raw image sensor directly. Such sensors
> > can be connected through FIMC-LITEn (and MIPI-CSISn) IPs to
> > the ISP, which then feeds image data to the FIMCn IP. Thus
> > there can be two busses associated with an image source
> > (sensor). Rename struct s5p_fimc_isp_info describing external
> > image sensor (video decoder) to struct fimc_source_info to
> > avoid confusion. bus_type is split into fimc_bus_type and
> > sensor_bus_type. The bus type enumeration is extended to
> > include both FIMC Writeback input types.
> >
> > The bus_type enumeration and the data structure name in the
> > board files are modified according to the above changes.
> >
> > Cc: Kukjin Kim <kgene.kim@samsung.com>
> > Cc: linux-samsung-soc at vger.kernel.org
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> Kukjin, can I please have your ack on this patch so it can be
> merged through the media tree ?
> 
Sure, why not? Please go ahead with my ack:

Acked-by: Kukjin Kim <kgene.kim@samsung.com>

^ permalink raw reply

* [PATCH v2 4/4] irqchip: gic: Perform the gic_secondary_init() call via CPU notifier
From: Nicolas Pitre @ 2013-02-01 17:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359729522.3256.4.camel@linaro1.home>

On Fri, 1 Feb 2013, Jon Medhurst (Tixy) wrote:

> On Thu, 2013-01-31 at 15:31 -0500, Nicolas Pitre wrote:
> > On Thu, 31 Jan 2013, Russell King - ARM Linux wrote:
> > 
> > > On Thu, Jan 31, 2013 at 12:32:11PM -0500, Nicolas Pitre wrote:
> > > > On Thu, 31 Jan 2013, Russell King - ARM Linux wrote:
> > > > 
> > > > > I haven't tried Versatile Express yet as it has the TC2 tile on, and I
> > > > > don't yet a boot loader on it which is capable of TFTP (which makes it
> > > > > rather useless to me - I've been saying this for a time now but this is
> > > > > probably the first time publically.)  I'm thinking about putting the
> > > > > CA9x4 tile back on because that's a lot more functionally useful to me
> > > > > than TC2.
> > > > 
> > > > You might be interested by this then:
> > > > 
> > > > http://lists.linaro.org/pipermail/linaro-dev/2012-October/014136.html
> > > 
> > > Great news.  Everyone has been telling me that there's no uboot for TC2,
> > > or "we think Linaro might have something but we don't really know".
> > 
> > Note that I cobbled those instructions on my own and the result is not 
> > officially supported by Linaro.  This is obviously not suitable for 
> > setting up products or demo systems, but for a kernel developer I think 
> > such a setup is invaluable.
> 
> If I remember correctly, you will also only get 1GB of RAM available not
> the 2GB most TC2 boards have. (I did take a quick look at hacking U-Boot
> to get around that but couldn't get anything to work.)

I simply added "mem=2048m at 0x80000000" to my kernel cmdline.


Nicolas

^ permalink raw reply

* [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses
From: Catalin Marinas @ 2013-02-01 17:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANOGCgMbzEWpJQE8PH2nS9_wa0DP_14E4=whGgKxWGJ_HpwomQ@mail.gmail.com>

On Fri, Feb 01, 2013 at 04:40:35PM +0000, Christoffer Dall wrote:
> On Fri, Feb 1, 2013 at 11:37 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> > On Fri, Feb 01, 2013 at 04:32:54PM +0000, Christoffer Dall wrote:
> >> On Fri, Feb 1, 2013 at 11:26 AM, Catalin Marinas
> >> > --- a/arch/arm/mm/mmu.c
> >> > +++ b/arch/arm/mm/mmu.c
> >> > @@ -581,34 +581,19 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
> >> >                                       const struct mem_type *type)
> >> >  {
> >> >         pmd_t *pmd = pmd_offset(pud, addr);
> >> > +       unsigned long next;
> >> >
> >> > -       /*
> >> > -        * Try a section mapping - end, addr and phys must all be aligned
> >> > -        * to a section boundary.  Note that PMDs refer to the individual
> >> > -        * L1 entries, whereas PGDs refer to a group of L1 entries making
> >> > -        * up one logical pointer to an L2 table.
> >> > -        */
> >> > -       if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
> >> > -               pmd_t *p = pmd;
> >> > -
> >> > -#ifndef CONFIG_ARM_LPAE
> >> > -               if (addr & SECTION_SIZE)
> >> > -                       pmd++;
> >> > -#endif
> >> > -
> >> > -               do {
> >> > +       do {
> >> > +               next = section_addr_end(addr, end);
> >> > +               /* try section mapping first */
> >> > +               if (((addr | next | phys) & ~SECTION_MASK) == 0) {
> >> >                         *pmd = __pmd(phys | type->prot_sect);
> >> > -                       phys += SECTION_SIZE;
> >> > -               } while (pmd++, addr += SECTION_SIZE, addr != end);
> >> > -
> >> > -               flush_pmd_entry(p);
> >> > -       } else {
> >> > -               /*
> >> > -                * No need to loop; pte's aren't interested in the
> >> > -                * individual L1 entries.
> >> > -                */
> >> > -               alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
> >> > -       }
> >> > +                       flush_pmd_entry(pmd);
> >> > +               } else {
> >> > +                       alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
> >>
> >> aren't you wasting memory here? The pte doesn't alloc a full page, but
> >> the memblock allocator allocates a full page right?
> >>
> >> I thought this was the rationale behind Russell's previous comments on
> >> Santosh's earlier patch version.
> >
> > You are right, it's allocating more ptes. Than we can use pmd_addr_end.
> > I'll go back to the code.
> >
> don't get me wrong, I strongly prefer keeping that loop in
> alloc_init_section, the other way it was weird to read, felt like
> shoehorning something, but you may have to keep a pointer around for
> unused part of a page for pte or something, not sure what ends up
> being nicest.

Another try. This time I kept the same logic as before but added a loop
on the outside (and indented the code). With classic MMU
pmd_addr_end(addr, end) always return end, so the logic doesn't change.
With LPAE we should get the standard looping over pmd entries. Again,
only tested on C-A9.


diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9f06102..47154f3 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -581,34 +581,36 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
 				      const struct mem_type *type)
 {
 	pmd_t *pmd = pmd_offset(pud, addr);
+	unsigned long next;
 
-	/*
-	 * Try a section mapping - end, addr and phys must all be aligned
-	 * to a section boundary.  Note that PMDs refer to the individual
-	 * L1 entries, whereas PGDs refer to a group of L1 entries making
-	 * up one logical pointer to an L2 table.
-	 */
-	if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
-		pmd_t *p = pmd;
+	do {
+		next = pmd_addr_end(addr, end);
+
+		/*
+		 * Try a section mapping - next, addr and phys must all be
+		 * aligned to a section boundary.  Note that PMDs refer to the
+		 * individual L1 entries, whereas PGDs refer to a group of L1
+		 * entries making up one logical pointer to an L2 table.
+		 */
+		if (((addr | next | phys) & ~SECTION_MASK) == 0) {
+			pmd_t *p = pmd;
 
 #ifndef CONFIG_ARM_LPAE
-		if (addr & SECTION_SIZE)
-			pmd++;
+			if (addr & SECTION_SIZE)
+				pmd++;
 #endif
+			do {
+				*pmd = __pmd(phys | type->prot_sect);
+				phys += SECTION_SIZE;
+			} while (pmd++, addr += SECTION_SIZE, addr != next);
 
-		do {
-			*pmd = __pmd(phys | type->prot_sect);
-			phys += SECTION_SIZE;
-		} while (pmd++, addr += SECTION_SIZE, addr != end);
-
-		flush_pmd_entry(p);
-	} else {
-		/*
-		 * No need to loop; pte's aren't interested in the
-		 * individual L1 entries.
-		 */
-		alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
-	}
+			flush_pmd_entry(p);
+		} else {
+			alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys), type);
+			phys += next - addr;
+			pmd++;
+		}
+	} while (addr = next, addr != end);
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,

^ permalink raw reply related

* [PATCH v2 19/27] pci: PCIe driver for Marvell Armada 370/XP systems
From: Arnd Bergmann @ 2013-02-01 17:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130201162638.GT23505@n2100.arm.linux.org.uk>

On Friday 01 February 2013, Russell King - ARM Linux wrote:
> On Fri, Feb 01, 2013 at 04:07:49PM +0000, Arnd Bergmann wrote:
> > On Friday 01 February 2013, Thomas Petazzoni wrote:
> > > So there is really a range of I/O addresses associated to it, even
> > > though the device will apparently not use it. Would it be possible to
> > > detect that the I/O range is not used by the device, and therefore
> > > avoid the allocation of an address decoding window for this I/O range?
> > 
> > I suspect it just gets disabled because the port number 0xc0010000 is
> > larger than IO_PORT_LIMIT and we cannot access that offset inside
> > of the virtual memory window we use for PIO.
> 
> You're running into that trap again which you fall into on other
> architectures.
> 
> If you arrange for your PCI IO space to start at 0 rather than the
> physical address that it appears on your CPU, then you shouldn't
> end up with it extending up to something at 0xcXXXXXXX.
> 
> Remember that we should be ensuring that inb(0) hits the first address
> of the cross-subarch PCI IO area - this alway requires that any sub-arch
> taking part in a multiplatform kernel must start its IO space addresses
> at 0 and not the physical address on the local CPU.

Yes, that was my point. I think in this case, the bug is in the new
of_pci_process_ranges functions, which returns a 'struct resource'
translated into IORESOURCE_MEM space, but with the type set
to IORESOURCE_IO. This resource then gets passed to 
pci_add_resource_offset().

	Arnd

^ permalink raw reply

* [PATCHv3 for soc 0/4] Enabling socfpga on hardware
From: dinguyen at altera.com @ 2013-02-01 17:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Dinh Nguyen <dinguyen@altera.com>

V3:
- Addressed comments from Olof Johansson and Russell King
- Received Acked-by and Tested-by Stephen Warren
- Received Signed-off-by Pavel Machek

V2:
- Remove patch that adds clock entries in the socfpga.dtsi as this
should accompany a rework in drivers/clk and will done in a different
patch series.
- Removed I-cache invalidate from v7_invalidate_l1
- Defined cpu1-start-addr as a device tree entry
- Removed the need to use CONFIG_VMSPLIT_2G

Dinh Nguyen (4):
  arm: socfpga: Add new device tree source for actual socfpga HW
  arm: socfpga: Add entries to enable make dtbs socfpga
  arm: Add v7_invalidate_l1 to cache-v7.S
  arm: socfpga: Add SMP support for actual socfpga harware

 .../bindings/arm/altera/socfpga-system.txt         |    2 +
 arch/arm/boot/dts/Makefile                         |    2 +
 arch/arm/boot/dts/socfpga.dtsi                     |   22 +++----
 arch/arm/boot/dts/socfpga_cyclone5.dts             |   34 ++++++++++-
 arch/arm/boot/dts/socfpga_vt.dts                   |   64 ++++++++++++++++++++
 arch/arm/mach-imx/headsmp.S                        |   47 --------------
 arch/arm/mach-shmobile/headsmp.S                   |   48 ---------------
 arch/arm/mach-socfpga/core.h                       |    4 +-
 arch/arm/mach-socfpga/headsmp.S                    |   16 +++--
 arch/arm/mach-socfpga/platsmp.c                    |    3 +-
 arch/arm/mach-socfpga/socfpga.c                    |    7 ++-
 arch/arm/mach-tegra/headsmp.S                      |   43 -------------
 arch/arm/mm/cache-v7.S                             |   46 ++++++++++++++
 13 files changed, 179 insertions(+), 159 deletions(-)
 create mode 100644 arch/arm/boot/dts/socfpga_vt.dts

-- 
1.7.9.5

^ permalink raw reply


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