* 3.7-rc-1 Release Causing application failure for compilation
From: Prabhakar Lad @ 2012-10-18 16:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi All,
I have updated to 3.7-rc1 kernel version with latest head with
commit-id 43c422eda99b894f18d1cca17bcd2401efaf7bd0
but when I try to cross compile the Application I am getting following errors.
/home/plad/ti/linus/linus/include/linux/types.h:14:26: error:
conflicting types for 'fd_set'
/home/plad/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/select.h:78:5:
note: previous declaration of 'fd_set' was here
/home/plad/ti/linus/linus/include/linux/types.h:15:25: error:
conflicting types for 'dev_t'
/home/plad/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/types.h:61:17:
note: previous declaration of 'dev_t' was here
/home/plad/ti/linus/linus/include/linux/types.h:17:26: error:
conflicting types for 'mode_t'
/home/plad/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/types.h:71:18:
note: previous declaration of 'mode_t' was here
/home/plad/ti/linus/linus/include/linux/types.h:25:26: error:
conflicting types for 'timer_t'
/home/plad/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/time.h:104:19:
note: previous declaration of 'timer_t' was here
/home/plad/ti/linus/linus/include/linux/types.h:134:23: error:
conflicting types for 'blkcnt_t'
/home/plad/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/types.h:236:20:
note: previous declaration of 'blkcnt_t' was here
I use the codesourcery toolchain for cross compiling the applications
for ARM. The same compiler is used to build the uImage for ARM, but
when I try building the apps I see this issue. Can any help me out in
fixing this.
Regards,
--Prabhakar Lad
^ permalink raw reply
* [PATCH 1/5] ARM: OMAP2+: gpmc: Fix kernel BUG for DT boot mode
From: Hiremath, Vaibhav @ 2012-10-18 16:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <507DB9EC.9060407@ti.com>
On Wed, Oct 17, 2012 at 01:17:56, Hunter, Jon wrote:
>
> On 10/15/2012 02:16 PM, Richard Cochran wrote:
> > From: hvaibhav at ti.com <hvaibhav@ti.com>
> >
> > With recent changes in omap gpmc driver code, in case of DT
> > boot mode, where bootloader does not configure gpmc cs space
> > will result into kernel BUG() inside gpmc_mem_init() function,
> > as gpmc cs0 gpmc_config7[0].csvalid bit is set to '1' and
> > gpmc_config7[0].baseaddress is set to '0' on reset.
>
> I am not sure I completely follow the logic here.
>
> Won't this problem occur if the bootloader does not configure the gpmc
> cs space AND we are not using DT?
>
That's what exactly the above comment describes.
> Is the csvalid bit set because we are booting from the internal ROM?
>
As per TRM, the reset value of the CS0_valis bit is set to 0. I have pasted
TRM statement below -
"Chip-select enable (reset value is 1 for CS[0] and 0 for CS[1-5])."
And same applies to OMAP3 family of devices.
> I guess I don't see why csvalid bit being set and a base-address of 0x0
> should not be allowed. That should be a valid combination.
>
Yes, agreed.
> One problem I see with gpmc_mem_init() is that it assumes that
> BOOT_ROM_SPACE is 1MB for all devices starting at 0x0 apart from the
> apollon board. For newer devices such as OMAP4, there is only 48KB of
> internal ROM and only mapped to 0x0 when booting from internal ROM. So
> this needs to be fixed.
>
> How much internal ROM does the AM335x have and where is it mapped?
>
AM33xx memory map is something like,
Boot ROM 0x4000_0000 0x4001_FFFF 128KB
0x4002_0000 0x4002_BFFF 48KB 32-bit Ex/R(1) - Public
Reserved 0x4002_C000 0x400F_FFFF 848KB Reserved
Reserved 0x4010_0000 0x401F_FFFF 1MB Reserved
Reserved 0x4020_0000 0x402E_FFFF 960KB Reserved
Reserved 0x402f_0000 0x4020_03FF 64KB Reserved
SRAM internal 0x402F_0400 0x402F_FFFF 32-bit Ex/R/W(1)
> > This use-case is applicable for any board/EVM which doesn't have
> > any peripheral connected to gpmc cs0, for example BeagleXM and
> > BeagleBone, so DT boot mode fails.
> >
> > This patch adds of_have_populated_dt() check before creating
> > device, so that for DT boot mode, gpmc probe will not be called
> > which is expected behavior, as gpmc is not supported yet from DT.
>
> Yes, but we do actually still allow some platform devices to be probed
> (such as dmtimers) when booting with DT that don't support DT yet. So
> this change prevents us from using the gpmc on boards when booting with DT.
>
The idea here was,
In order to use GPMC in meaningful way, where some peripheral is connected
to the GPMC, you must create platform_device for the probe to happen
properly. Now all the devices I know so far, we have gpmc_smsc911x_init(),
omap_nand_flash_init(), etc...
These api's are getting called only through machine_desc.init_xxx callbacks,
And in case of DT, we have centralized machine_desc definition for all
platforms (board-generic.c). So even though you want to use GPMC for DT boot
mode, you can not make use of peripheral without changing board-files to
change to create platform_device.
Does it make sense?
> I am not convinced that this is addressing the underlying problem with
> gpmc_mem_init().
>
The patch you submitted is cleanup patch and is required irrespective of
this patch. I believe this patch is just makes sure that, if you are booting
from DT and you do not have meaningful DT node for GPMC and peripheral
interfaced to it, no point in probing it.
Does it make any sense???
On other hand, Your patch is anyway required, as that I would consider as
cleanup of existing code (in error handling).
Thanks,
Vaibhav
> Cheers
> Jon
>
^ permalink raw reply
* [RFC PATCH 6/6] ARM: mm: Transparent huge page support for non-LPAE systems.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
Much of the required code for THP has been implemented in the earlier non-LPAE
HugeTLB patch.
One more domain bits is used (to store whether or not the THP is splitting).
Some THP helper functions are defined; and we have to re-define pmd_page such
that it distinguishes between page tables and sections.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/include/asm/pgtable-2level.h | 68 ++++++++++++++++++++++++++++++++-
arch/arm/include/asm/pgtable-3level.h | 2 +
arch/arm/include/asm/pgtable.h | 7 +++-
4 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9621d5f..d459673 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1773,7 +1773,7 @@ config SYS_SUPPORTS_HUGETLBFS
config HAVE_ARCH_TRANSPARENT_HUGEPAGE
def_bool y
- depends on ARM_LPAE
+ depends on SYS_SUPPORTS_HUGETLBFS
source "mm/Kconfig"
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 34f4775..67eabb4 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -179,6 +179,13 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
clean_pmd_entry(pmdp); \
} while (0)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define _PMD_HUGE(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+#else
+#define _PMD_HUGE(pmd) (0)
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
/* we don't need complex calculations here as the pmd is folded into the pgd */
#define pmd_addr_end(addr,end) (end)
@@ -197,7 +204,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
#define HPAGE_SHIFT PMD_SHIFT
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
-#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
#define HUGE_LINUX_PTE_COUNT (PAGE_OFFSET >> HPAGE_SHIFT)
@@ -209,6 +215,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
*/
#define PMD_DSECT_DIRTY (_AT(pmdval_t, 1) << 5)
#define PMD_DSECT_AF (_AT(pmdval_t, 1) << 6)
+#define PMD_DSECT_SPLITTING (_AT(pmdval_t, 1) << 7)
#define PMD_BIT_FUNC(fn,op) \
static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
@@ -261,8 +268,67 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
return __pmd(pmdval);
}
+#else
+#define HPAGE_SIZE 0
#endif /* CONFIG_SYS_SUPPORTS_HUGETLBFS */
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_mkhuge(pmd) (__pmd((pmd_val(pmd) & ~PMD_TYPE_MASK) | PMD_TYPE_SECT))
+
+PMD_BIT_FUNC(mkold, &= ~PMD_DSECT_AF);
+PMD_BIT_FUNC(mksplitting, |= PMD_DSECT_SPLITTING);
+PMD_BIT_FUNC(mkdirty, |= PMD_DSECT_DIRTY);
+PMD_BIT_FUNC(mkyoung, |= PMD_DSECT_AF);
+PMD_BIT_FUNC(mkwrite, |= PMD_SECT_AP_WRITE);
+PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
+
+#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_DSECT_SPLITTING)
+#define pmd_young(pmd) (pmd_val(pmd) & PMD_DSECT_AF)
+#define pmd_write(pmd) (pmd_val(pmd) & PMD_SECT_AP_WRITE)
+#define pmd_trans_huge(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+ /*
+ * for a section, we need to mask off more of the pmd
+ * before looking up the pfn
+ */
+ if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+ return __phys_to_pfn(pmd_val(pmd) & HPAGE_MASK);
+ else
+ return __phys_to_pfn(pmd_val(pmd) & PHYS_MASK);
+}
+
+static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
+{
+ pmd_t pmd = __pmd(__pfn_to_phys(pfn) | PMD_SECT_AP_READ | PMD_SECT_nG);
+
+ return pmd_modify(pmd, prot);
+}
+
+#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot);
+
+static inline int has_transparent_hugepage(void)
+{
+ return 1;
+}
+
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+static inline struct page *pmd_page(pmd_t pmd)
+{
+ /*
+ * for a section, we need to mask off more of the pmd
+ * before looking up the page as it is a section descriptor.
+ */
+ if (_PMD_HUGE(pmd))
+ return phys_to_page(pmd_val(pmd) & HPAGE_MASK);
+
+ return phys_to_page(pmd_val(pmd) & PHYS_MASK);
+}
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_PGTABLE_2LEVEL_H */
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 31c071f..8360814 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -197,6 +197,8 @@ PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
+
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
{
const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY;
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 767aa7c..2d96381 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -169,11 +169,14 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
{
+#ifdef SYS_SUPPORTS_HUGETLBFS
+ if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+ return __va(pmd_val(pmd) & HPAGE_MASK);
+#endif
+
return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
}
-#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
-
#ifndef CONFIG_HIGHPTE
#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
#define __pte_unmap(pte) do { } while (0)
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 5/6] ARM: mm: Transparent huge page support for LPAE systems.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
From: Catalin Marinas <catalin.marinas@arm.com>
The patch adds support for THP (transparent huge pages) to LPAE systems. When
this feature is enabled, the kernel tries to map anonymous pages as 2MB
sections where possible.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[steve.capper at arm.com: symbolic constants used, value of PMD_SECT_SPLITTING
adjusted, tlbflush.h included in pgtable.h]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/Kconfig | 4 ++
arch/arm/include/asm/pgtable-2level.h | 2 +
arch/arm/include/asm/pgtable-3level-hwdef.h | 2 +
arch/arm/include/asm/pgtable-3level.h | 57 +++++++++++++++++++++++++++
arch/arm/include/asm/pgtable.h | 4 +-
arch/arm/include/asm/tlb.h | 6 +++
arch/arm/include/asm/tlbflush.h | 2 +
arch/arm/mm/fsr-3level.c | 2 +-
8 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dd0a230..9621d5f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1771,6 +1771,10 @@ config SYS_SUPPORTS_HUGETLBFS
def_bool y
depends on ARM_LPAE || (!CPU_USE_DOMAINS && !MEMORY_FAILURE)
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ def_bool y
+ depends on ARM_LPAE
+
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index fd1d9be..34f4775 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -182,6 +182,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
/* we don't need complex calculations here as the pmd is folded into the pgd */
#define pmd_addr_end(addr,end) (end)
+#define pmd_present(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) != PMD_TYPE_FAULT)
+
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index d795282..53c7f67 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -38,6 +38,8 @@
*/
#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */
+#define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */
#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
#define PMD_SECT_nG (_AT(pmdval_t, 1) << 11)
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index d086f61..31c071f 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -85,6 +85,9 @@
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */
#define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */
+#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
+#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
+
/*
* To be used in assembly code with the upper page attributes.
*/
@@ -166,6 +169,60 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PMD_TYPE_MASK) | PMD_TYPE_SECT))
+#define pmd_present(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) != PMD_TYPE_FAULT)
+#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_trans_huge(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#endif
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
+PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
+PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
+PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
+
+#define pmd_mkhuge(pmd) (__pmd((pmd_val(pmd) & ~PMD_TYPE_MASK) | PMD_TYPE_SECT))
+
+#define pmd_pfn(pmd) ((pmd_val(pmd) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY;
+ pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
+ return pmd;
+}
+
+static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
+{
+ *pmdp = pmd;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ BUG_ON(addr >= TASK_SIZE);
+ pmd = __pmd(pmd_val(pmd) | PMD_SECT_nG);
+ set_pmd(pmdp, pmd);
+ flush_pmd_entry(pmdp);
+}
+
+static inline int has_transparent_hugepage(void)
+{
+ return 1;
+}
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_PGTABLE_3LEVEL_H */
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index c35bf46..767aa7c 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -24,6 +24,9 @@
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
+
+#include <asm/tlbflush.h>
+
#ifdef CONFIG_ARM_LPAE
#include <asm/pgtable-3level.h>
#else
@@ -163,7 +166,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_present(pmd) (pmd_val(pmd))
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
{
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 685e9e87..0fc2d9d 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -229,6 +229,12 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
#endif
}
+static inline void
+tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
+{
+ tlb_add_flush(tlb, addr);
+}
+
#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 6e924d3..907cede 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -505,6 +505,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
}
#endif
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+
#endif
#endif /* CONFIG_MMU */
diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c
index 05a4e94..47f4c6f 100644
--- a/arch/arm/mm/fsr-3level.c
+++ b/arch/arm/mm/fsr-3level.c
@@ -9,7 +9,7 @@ static struct fsr_info fsr_info[] = {
{ do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
{ do_bad, SIGBUS, 0, "reserved access flag fault" },
{ do_bad, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
- { do_bad, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
{ do_bad, SIGBUS, 0, "reserved permission fault" },
{ do_bad, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 4/6] ARM: mm: HugeTLB support for non-LPAE systems.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
Based on Bill Carson's HugeTLB patch, with the big difference being in the way
PTEs are passed back to the memory manager. Rather than store a "Linux Huge
PTE" separately; we make one up on the fly in huge_ptep_get. Also rather than
consider 16M supersections, we focus solely on 2x1M sections.
To construct a huge PTE on the fly we need additional information (such as the
accessed flag and dirty bit) which we choose to store in the domain bits of the
short section descriptor. In order to use these domain bits for storage, we need
to make ourselves a client for all 16 domains and this is done in head.S.
Storing extra information in the domain bits also makes it a lot easier to
implement Transparent Huge Pages, and some of the code in pgtable-2level.h is
arranged to facilitate THP support in a later patch.
Non-LPAE HugeTLB pages are incompatible with the huge page migration code
(enabled when CONFIG_MEMORY_FAILURE is selected) as that code dereferences PTEs
directly, rather than calling huge_ptep_get and set_huge_pte_at.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/include/asm/hugetlb-2level.h | 71 ++++++++++++++++++++
arch/arm/include/asm/hugetlb.h | 4 ++
arch/arm/include/asm/pgtable-2level.h | 79 +++++++++++++++++++++-
arch/arm/include/asm/tlb.h | 10 ++-
arch/arm/kernel/head.S | 10 ++-
arch/arm/mm/Makefile | 4 ++
arch/arm/mm/fault.c | 6 +-
arch/arm/mm/hugetlbpage-2level.c | 115 +++++++++++++++++++++++++++++++++
9 files changed, 293 insertions(+), 8 deletions(-)
create mode 100644 arch/arm/include/asm/hugetlb-2level.h
create mode 100644 arch/arm/mm/hugetlbpage-2level.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d863781..dd0a230 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1769,7 +1769,7 @@ config HW_PERF_EVENTS
config SYS_SUPPORTS_HUGETLBFS
def_bool y
- depends on ARM_LPAE
+ depends on ARM_LPAE || (!CPU_USE_DOMAINS && !MEMORY_FAILURE)
source "mm/Kconfig"
diff --git a/arch/arm/include/asm/hugetlb-2level.h b/arch/arm/include/asm/hugetlb-2level.h
new file mode 100644
index 0000000..3532b54
--- /dev/null
+++ b/arch/arm/include/asm/hugetlb-2level.h
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/include/asm/hugetlb-2level.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_2LEVEL_H
+#define _ASM_ARM_HUGETLB_2LEVEL_H
+
+
+pte_t huge_ptep_get(pte_t *ptep);
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
+
+static inline pte_t pte_mkhuge(pte_t pte) { return pte; }
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ pmd_t *pmdp = (pmd_t *) ptep;
+ set_pmd_at(mm, addr, pmdp, pmd_wrprotect(*pmdp));
+}
+
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ pmd_t *pmdp = (pmd_t *)ptep;
+ pte_t pte = huge_ptep_get(ptep);
+ pmd_clear(pmdp);
+
+ return pte;
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ int changed = !pte_same(huge_ptep_get(ptep), pte);
+
+ if (changed) {
+ set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+ huge_ptep_clear_flush(vma, addr, &pte);
+ }
+
+ return changed;
+}
+
+#endif /* _ASM_ARM_HUGETLB_2LEVEL_H */
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h
index 7af9cf6..1e92975 100644
--- a/arch/arm/include/asm/hugetlb.h
+++ b/arch/arm/include/asm/hugetlb.h
@@ -24,7 +24,11 @@
#include <asm/page.h>
+#ifdef CONFIG_ARM_LPAE
#include <asm/hugetlb-3level.h>
+#else
+#include <asm/hugetlb-2level.h>
+#endif
static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
unsigned long addr, unsigned long end,
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 662a00e..fd1d9be 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -163,7 +163,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
return (pmd_t *)pud;
}
-#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+#define pmd_bad(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_FAULT)
#define copy_pmd(pmdpd,pmdps) \
do { \
@@ -184,6 +184,83 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+
+#ifdef CONFIG_SYS_SUPPORTS_HUGETLBFS
+
+/*
+ * now follows some of the definitions to allow huge page support, we can't put
+ * these in the hugetlb source files as they are also required for transparent
+ * hugepage support.
+ */
+
+#define HPAGE_SHIFT PMD_SHIFT
+#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+
+#define HUGE_LINUX_PTE_COUNT (PAGE_OFFSET >> HPAGE_SHIFT)
+#define HUGE_LINUX_PTE_SIZE (HUGE_LINUX_PTE_COUNT * sizeof(pte_t *))
+#define HUGE_LINUX_PTE_INDEX(addr) (addr >> HPAGE_SHIFT)
+
+/*
+ * We re-purpose the following domain bits in the section descriptor
+ */
+#define PMD_DSECT_DIRTY (_AT(pmdval_t, 1) << 5)
+#define PMD_DSECT_AF (_AT(pmdval_t, 1) << 6)
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect, &= ~PMD_SECT_AP_WRITE);
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ pmd_t *pmdp, pmd_t pmd)
+{
+ /*
+ * we can sometimes be passed a pmd pointing to a level 2 descriptor
+ * from collapse_huge_page.
+ */
+ if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE) {
+ pmdp[0] = __pmd(pmd_val(pmd));
+ pmdp[1] = __pmd(pmd_val(pmd) + 256 * sizeof(pte_t));
+ } else {
+ pmdp[0] = __pmd(pmd_val(pmd)); /* first 1M section */
+ pmdp[1] = __pmd(pmd_val(pmd) + SECTION_SIZE); /* second 1M section */
+ }
+
+ flush_pmd_entry(pmdp);
+}
+
+#define HPMD_XLATE(res, cmp, from, to) do { if (cmp & from) res |= to; \
+ else res &= ~to; \
+ } while (0)
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ pmdval_t pmdval = pmd_val(pmd);
+ pteval_t newprotval = pgprot_val(newprot);
+
+ HPMD_XLATE(pmdval, newprotval, L_PTE_XN, PMD_SECT_XN);
+ HPMD_XLATE(pmdval, newprotval, L_PTE_SHARED, PMD_SECT_S);
+ HPMD_XLATE(pmdval, newprotval, L_PTE_YOUNG, PMD_DSECT_AF);
+ HPMD_XLATE(pmdval, newprotval, L_PTE_DIRTY, PMD_DSECT_DIRTY);
+
+ /* preserve bits C & B */
+ pmdval |= (newprotval & (3 << 2));
+
+ /* Linux PTE bit 4 corresponds to PMD TEX bit 0 */
+ HPMD_XLATE(pmdval, newprotval, 1 << 4, PMD_SECT_TEX(1));
+
+ if (newprotval & L_PTE_RDONLY)
+ pmdval &= ~PMD_SECT_AP_WRITE;
+ else
+ pmdval |= PMD_SECT_AP_WRITE;
+
+ return __pmd(pmdval);
+}
+
+#endif /* CONFIG_SYS_SUPPORTS_HUGETLBFS */
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_PGTABLE_2LEVEL_H */
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 99a1951..685e9e87 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -92,10 +92,16 @@ static inline void tlb_flush(struct mmu_gather *tlb)
static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr)
{
if (!tlb->fullmm) {
+ unsigned long size = PAGE_SIZE;
+
if (addr < tlb->range_start)
tlb->range_start = addr;
- if (addr + PAGE_SIZE > tlb->range_end)
- tlb->range_end = addr + PAGE_SIZE;
+
+ if (tlb->vma && is_vm_hugetlb_page(tlb->vma))
+ size = HPAGE_SIZE;
+
+ if (addr + size > tlb->range_end)
+ tlb->range_end = addr + size;
}
}
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 4eee351..860f08e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -410,13 +410,21 @@ __enable_mmu:
mov r5, #0
mcrr p15, 0, r4, r5, c2 @ load TTBR0
#else
+#ifndef CONFIG_SYS_SUPPORTS_HUGETLBFS
mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+#else
+ @ set ourselves as the client in all domains
+ @ this allows us to then use the 4 domain bits in the
+ @ section descriptors in our transparent huge pages
+ ldr r5, =0x55555555
+#endif /* CONFIG_SYS_SUPPORTS_HUGETLBFS */
+
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
-#endif
+#endif /* CONFIG_ARM_LPAE */
b __turn_mmu_on
ENDPROC(__enable_mmu)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 1560bbc..adf0b19 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -17,7 +17,11 @@ obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+ifeq ($(CONFIG_ARM_LPAE),y)
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage-3level.o
+else
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage-2level.o
+endif
obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 5dbf13f..0884936 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -488,13 +488,13 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
#endif /* CONFIG_MMU */
/*
- * Some section permission faults need to be handled gracefully.
- * They can happen due to a __{get,put}_user during an oops.
+ * A fault in a section will likely be due to a huge page, treat it
+ * as a page fault.
*/
static int
do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
- do_bad_area(addr, fsr, regs);
+ do_page_fault(addr, fsr, regs);
return 0;
}
diff --git a/arch/arm/mm/hugetlbpage-2level.c b/arch/arm/mm/hugetlbpage-2level.c
new file mode 100644
index 0000000..4b2b38c
--- /dev/null
+++ b/arch/arm/mm/hugetlbpage-2level.c
@@ -0,0 +1,115 @@
+/*
+ * arch/arm/mm/hugetlbpage-2level.c
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Copyright (C) 2012 ARM Ltd
+ * Copyright (C) 2012 Bill Carson.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+ return 0;
+}
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+ unsigned long addr, unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ pgd = pgd_offset(mm, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
+
+ return (pte_t *)pmd; /* our huge pte is actually a pmd */
+}
+
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ pmd_t *pmd, int write)
+{
+ struct page *page;
+ unsigned long pfn;
+
+ BUG_ON((pmd_val(*pmd) & PMD_TYPE_MASK) != PMD_TYPE_SECT);
+ pfn = ((pmd_val(*pmd) & HPAGE_MASK) >> PAGE_SHIFT);
+ page = pfn_to_page(pfn);
+ return page;
+}
+
+pte_t huge_ptep_get(pte_t *ptep)
+{
+ pmd_t *pmdp = (pmd_t*)ptep;
+ pmdval_t pmdval = pmd_val(*pmdp);
+ pteval_t retval;
+
+ if (!pmdval)
+ return __pte(0);
+
+ retval = (pteval_t) (pmdval & HPAGE_MASK);
+ HPMD_XLATE(retval, pmdval, PMD_SECT_XN, L_PTE_XN);
+ HPMD_XLATE(retval, pmdval, PMD_SECT_S, L_PTE_SHARED);
+ HPMD_XLATE(retval, pmdval, PMD_DSECT_AF, L_PTE_YOUNG);
+ HPMD_XLATE(retval, pmdval, PMD_DSECT_DIRTY, L_PTE_DIRTY);
+
+ /* preserve bits C & B */
+ retval |= (pmdval & (3 << 2));
+
+ /* PMD TEX bit 0 corresponds to Linux PTE bit 4 */
+ HPMD_XLATE(retval, pmdval, PMD_SECT_TEX(1), 1 << 4);
+
+ if (pmdval & PMD_SECT_AP_WRITE)
+ retval &= ~L_PTE_RDONLY;
+ else
+ retval |= L_PTE_RDONLY;
+
+ if ((pmdval & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+ retval |= L_PTE_VALID;
+
+ /* we assume all hugetlb pages are user */
+ retval |= L_PTE_USER;
+
+ return __pte(retval);
+}
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ pmdval_t pmdval = (pmdval_t) pte_val(pte);
+ pmd_t *pmdp = (pmd_t*) ptep;
+
+ pmdval &= HPAGE_MASK;
+ pmdval |= PMD_SECT_AP_READ | PMD_SECT_nG | PMD_TYPE_SECT;
+ pmdval = pmd_val(pmd_modify(__pmd(pmdval), __pgprot(pte_val(pte))));
+
+ __sync_icache_dcache(pte);
+
+ set_pmd_at(mm, addr, pmdp, __pmd(pmdval));
+}
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 3/6] ARM: mm: HugeTLB support for LPAE systems.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
From: Catalin Marinas <catalin.marinas@arm.com>
This patch adds support for hugetlbfs based on the x86 implementation.
It allows mapping of 2MB sections (see Documentation/vm/hugetlbpage.txt
for usage). The 64K pages configuration is not supported (section size
is 512MB in this case).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[steve.capper at arm.com: symbolic constants replace numbers in places.
Split up into multiple files, to simplify future non-LPAE support].
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/Kconfig | 4 +
arch/arm/include/asm/hugetlb-3level.h | 61 +++++++++++
arch/arm/include/asm/hugetlb.h | 83 ++++++++++++++
arch/arm/include/asm/pgtable-3level.h | 13 +++
arch/arm/mm/Makefile | 2 +
arch/arm/mm/dma-mapping.c | 2 +-
arch/arm/mm/hugetlbpage-3level.c | 190 +++++++++++++++++++++++++++++++++
arch/arm/mm/hugetlbpage.c | 65 +++++++++++
8 files changed, 419 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/include/asm/hugetlb-3level.h
create mode 100644 arch/arm/include/asm/hugetlb.h
create mode 100644 arch/arm/mm/hugetlbpage-3level.c
create mode 100644 arch/arm/mm/hugetlbpage.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 73067ef..d863781 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1767,6 +1767,10 @@ config HW_PERF_EVENTS
Enable hardware performance counter support for perf events. If
disabled, perf events will use software events only.
+config SYS_SUPPORTS_HUGETLBFS
+ def_bool y
+ depends on ARM_LPAE
+
source "mm/Kconfig"
config FORCE_MAX_ZONEORDER
diff --git a/arch/arm/include/asm/hugetlb-3level.h b/arch/arm/include/asm/hugetlb-3level.h
new file mode 100644
index 0000000..4868064
--- /dev/null
+++ b/arch/arm/include/asm/hugetlb-3level.h
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/asm/hugetlb-3level.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_3LEVEL_H
+#define _ASM_ARM_HUGETLB_3LEVEL_H
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+ return *ptep;
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h
new file mode 100644
index 0000000..7af9cf6
--- /dev/null
+++ b/arch/arm/include/asm/hugetlb.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/include/asm/hugetlb.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_H
+#define _ASM_ARM_HUGETLB_H
+
+#include <asm/page.h>
+
+#include <asm/hugetlb-3level.h>
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+ unsigned long addr, unsigned long end,
+ unsigned long floor,
+ unsigned long ceiling)
+{
+ free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+ unsigned long addr, unsigned long len)
+{
+ return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+ unsigned long addr, unsigned long len)
+{
+ struct hstate *h = hstate_file(file);
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (addr & ~huge_page_mask(h))
+ return -EINVAL;
+ return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+ return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+ return pte_wrprotect(pte);
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+ return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+ clear_bit(PG_dcache_clean, &page->flags);
+}
+
+#endif /* _ASM_ARM_HUGETLB_H */
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 0eaeb55..d086f61 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -62,6 +62,14 @@
#define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE)
/*
+ * Hugetlb definitions.
+ */
+#define HPAGE_SHIFT PMD_SHIFT
+#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+
+/*
* "Linux" PTE definitions for LPAE.
*
* These bits overlap with the hardware bits but the naming is preserved for
@@ -153,6 +161,11 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
+#define pte_huge(pte) ((pte_val(pte) & PMD_TYPE_MASK) == PMD_TYPE_SECT)
+
+#define pte_mkhuge(pte) (__pte((pte_val(pte) & ~PMD_TYPE_MASK) | PMD_TYPE_SECT))
+
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_PGTABLE_3LEVEL_H */
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 8a9c4cb..1560bbc 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
obj-$(CONFIG_HIGHMEM) += highmem.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage-3level.o
obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 477a2d2..3ced228 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -241,7 +241,7 @@ static void __dma_free_buffer(struct page *page, size_t size)
#ifdef CONFIG_MMU
#ifdef CONFIG_HUGETLB_PAGE
-#error ARM Coherent DMA allocator does not (yet) support huge TLB
+#warning ARM Coherent DMA allocator does not (yet) support huge TLB
#endif
static void *__alloc_from_contiguous(struct device *dev, size_t size,
diff --git a/arch/arm/mm/hugetlbpage-3level.c b/arch/arm/mm/hugetlbpage-3level.c
new file mode 100644
index 0000000..86474f0
--- /dev/null
+++ b/arch/arm/mm/hugetlbpage-3level.c
@@ -0,0 +1,190 @@
+/*
+ * arch/arm/mm/hugetlbpage-3level.c
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/mm/hugetlbpage.c
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+static unsigned long page_table_shareable(struct vm_area_struct *svma,
+ struct vm_area_struct *vma,
+ unsigned long addr, pgoff_t idx)
+{
+ unsigned long saddr = ((idx - svma->vm_pgoff) << PAGE_SHIFT) +
+ svma->vm_start;
+ unsigned long sbase = saddr & PUD_MASK;
+ unsigned long s_end = sbase + PUD_SIZE;
+
+ /* Allow segments to share if only one is marked locked */
+ unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED;
+ unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED;
+
+ /*
+ * match the virtual addresses, permission and the alignment of the
+ * page table page.
+ */
+ if (pmd_index(addr) != pmd_index(saddr) ||
+ vm_flags != svm_flags ||
+ sbase < svma->vm_start || svma->vm_end < s_end)
+ return 0;
+
+ return saddr;
+}
+
+static int vma_shareable(struct vm_area_struct *vma, unsigned long addr)
+{
+ unsigned long base = addr & PUD_MASK;
+ unsigned long end = base + PUD_SIZE;
+
+ /*
+ * check on proper vm_flags and page table alignment
+ */
+ if (vma->vm_flags & VM_MAYSHARE &&
+ vma->vm_start <= base && end <= vma->vm_end)
+ return 1;
+ return 0;
+}
+
+/*
+ * search for a shareable pmd page for hugetlb.
+ */
+static pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr,
+ pud_t *pud)
+{
+ struct vm_area_struct *vma = find_vma(mm, addr);
+ struct address_space *mapping = vma->vm_file->f_mapping;
+ pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
+ vma->vm_pgoff;
+ struct vm_area_struct *svma;
+ unsigned long saddr;
+ pte_t *spte = NULL;
+ pte_t *pte;
+
+ if (!vma_shareable(vma, addr))
+ return (pte_t *)pmd_alloc(mm, pud, addr);
+
+ mutex_lock(&mapping->i_mmap_mutex);
+ vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) {
+ if (svma == vma)
+ continue;
+
+ saddr = page_table_shareable(svma, vma, addr, idx);
+ if (saddr) {
+ spte = huge_pte_offset(svma->vm_mm, saddr);
+ if (spte) {
+ get_page(virt_to_page(spte));
+ break;
+ }
+ }
+ }
+
+ if (!spte)
+ goto out;
+
+ spin_lock(&mm->page_table_lock);
+ if (pud_none(*pud))
+ pud_populate(mm, pud, (pmd_t *)((unsigned long)spte & PAGE_MASK));
+ else
+ put_page(virt_to_page(spte));
+ spin_unlock(&mm->page_table_lock);
+out:
+ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ mutex_unlock(&mapping->i_mmap_mutex);
+ return pte;
+}
+
+/*
+ * unmap huge page backed by shared pte.
+ *
+ * Hugetlb pte page is ref counted at the time of mapping. If pte is shared
+ * indicated by page_count > 1, unmap is achieved by clearing pud and
+ * decrementing the ref count. If count == 1, the pte page is not shared.
+ *
+ * called with vma->vm_mm->page_table_lock held.
+ *
+ * returns: 1 successfully unmapped a shared pte page
+ * 0 the underlying pte page is not shared, or it is the last user
+ */
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+ pgd_t *pgd = pgd_offset(mm, *addr);
+ pud_t *pud = pud_offset(pgd, *addr);
+
+ BUG_ON(page_count(virt_to_page(ptep)) == 0);
+ if (page_count(virt_to_page(ptep)) == 1)
+ return 0;
+
+ pud_clear(pud);
+ put_page(virt_to_page(ptep));
+ *addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE;
+ return 1;
+}
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+ unsigned long addr, unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pte_t *pte = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ if (pud) {
+ BUG_ON(sz != PMD_SIZE);
+ if (pud_none(*pud))
+ pte = huge_pmd_share(mm, addr, pud);
+ else
+ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ }
+ BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
+
+ return pte;
+}
+
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ pmd_t *pmd, int write)
+{
+ struct page *page;
+
+ page = pte_page(*(pte_t *)pmd);
+ if (page)
+ page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
+ return page;
+}
+
+struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
+ pud_t *pud, int write)
+{
+ struct page *page;
+
+ page = pte_page(*(pte_t *)pud);
+ if (page)
+ page += ((address & ~PUD_MASK) >> PAGE_SHIFT);
+ return page;
+}
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c
new file mode 100644
index 0000000..32fe7fd
--- /dev/null
+++ b/arch/arm/mm/hugetlbpage.c
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mm/hugetlbpage.c
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/mm/hugetlbpage.c
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_present(*pgd)) {
+ pud = pud_offset(pgd, addr);
+ if (pud_present(*pud))
+ pmd = pmd_offset(pud, addr);
+ }
+
+ return (pte_t *)pmd;
+}
+
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ int write)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+int pmd_huge(pmd_t pmd)
+{
+ return (pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT;
+}
+
+int pud_huge(pud_t pud)
+{
+ return 0;
+}
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 2/6] ARM: mm: Add support for flushing HugeTLB pages.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
On ARM we use the __flush_dcache_page function to flush the dcache of pages
when needed; usually when the PG_dcache_clean bit is unset and we are setting a
PTE.
A HugeTLB page is represented as a compound page consisting of an array of
pages. Thus to flush the dcache of a HugeTLB page, one must flush more than a
single page.
This patch modifies __flush_dcache_page such that all constituent pages of a
HugeTLB page are flushed.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/mm/flush.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 1c8f7f5..0a69cb8 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -17,6 +17,7 @@
#include <asm/highmem.h>
#include <asm/smp_plat.h>
#include <asm/tlbflush.h>
+#include <linux/hugetlb.h>
#include "mm.h"
@@ -168,17 +169,21 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
* coherent with the kernels mapping.
*/
if (!PageHighMem(page)) {
- __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+ __cpuc_flush_dcache_area(page_address(page), (PAGE_SIZE << compound_order(page)));
} else {
- void *addr = kmap_high_get(page);
- if (addr) {
- __cpuc_flush_dcache_area(addr, PAGE_SIZE);
- kunmap_high(page);
- } else if (cache_is_vipt()) {
- /* unmapped pages might still be cached */
- addr = kmap_atomic(page);
- __cpuc_flush_dcache_area(addr, PAGE_SIZE);
- kunmap_atomic(addr);
+ unsigned long i;
+ for(i = 0; i < (1 << compound_order(page)); i++) {
+ struct page *cpage = page + i;
+ void *addr = kmap_high_get(cpage);
+ if (addr) {
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_high(cpage);
+ } else if (cache_is_vipt()) {
+ /* unmapped pages might still be cached */
+ addr = kmap_atomic(cpage);
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_atomic(addr);
+ }
}
}
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 1/6] ARM: mm: correct pte_same behaviour for LPAE.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576942-25299-1-git-send-email-steve.capper@arm.com>
For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
that are written to a page table but not for ptes created with mk_pte.
This can cause some comparison tests made by pte_same to fail spuriously and
lead to other problems.
To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
present before running the comparison.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/include/asm/pgtable-2level.h | 5 +++++
arch/arm/include/asm/pgtable-3level.h | 5 +++++
arch/arm/include/asm/pgtable.h | 23 +++++++++++++++++++++++
3 files changed, 33 insertions(+)
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 2317a71..662a00e 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -125,6 +125,11 @@
#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
/*
+ * for 2 levels of paging we don't mask off any bits when comparing present ptes
+ */
+#define L_PTE_CMP_MASKOFF 0
+
+/*
* These are the memory types, defined to be compatible with
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
*/
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index b249035..0eaeb55 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -84,6 +84,11 @@
#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
/*
+ * we need to mask off PTE_EXT_NG when comparing present ptes.
+ */
+#define L_PTE_CMP_MASKOFF PTE_EXT_NG
+
+/*
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
*/
#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 08c1231..c35bf46 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -248,6 +248,29 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
}
/*
+ * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
+ * that are written to a page table but not for ptes created with mk_pte.
+ *
+ * This can cause some comparison tests made by pte_same to fail spuriously and
+ * lead to other problems.
+ *
+ * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
+ * present before running the comparison.
+ */
+#define __HAVE_ARCH_PTE_SAME
+static inline int pte_same(pte_t pte_a, pte_t pte_b)
+{
+ pteval_t vala = pte_val(pte_a), valb = pte_val(pte_b);
+ if (pte_present(pte_a))
+ vala &= ~L_PTE_CMP_MASKOFF;
+
+ if (pte_present(pte_b))
+ valb &= ~L_PTE_CMP_MASKOFF;
+
+ return vala == valb;
+}
+
+/*
* Encode and decode a swap entry. Swap entries are stored in the Linux
* page tables as follows:
*
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 0/6] ARM: mm: HugeTLB + THP support.
From: Steve Capper @ 2012-10-18 16:15 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
The following patches bring both HugeTLB support and Transparent HugePage (THP)
support to ARM.
Both short descriptors (non-LPAE) and long descriptors (LPAE) are supported.
The non-LPAE HugeTLB code is based on patches by Bill Carson [1], but instead of
allocating extra memory to store "Linux PTEs", it re-purposes the domain bits
of section descriptors and constructs huge Linux PTEs on demand.
As PMDs are walked directly by the kernel THP functions (there are no
huge_pmd_offset style functions), any "linux PMD"/"hardware PMD" distinction
would require some re-working of the ARM PMD/PTE code. Use of the domain bits
allows for a more straightforward THP implementation.
Some general HugeTLB code relating to huge page migration on memory failure
(CONFIG_MEMORY_FAILURE) de-references huge pte_t *s directly rather than use
the huge_ptep_get and set_huge_pte_at functions. Thus this config option is
incompatible with non-LPAE hugepages. At the moment I can only see x86 using
CONFIG_MEMORY_FAILURE though.
For non-LPAE, I make an assumption about how the memory type is mapped between
linux PTE and section descriptor. Ideally I would like to look this information
up, possibly from get_mem_types(MT_MEMORY). Comments on an elegant way of
achieving this are welcome.
Non-LPAE code was tested on a Versatile Express (V2P-CA15_A7 Cortex A15 tile),
Tegra 2 TrimSlice and RealView ARM11MPCore.
The LPAE code manipulates the hardware page tables directly as the long
descriptors are wide enough to contain all the Linux PTE information.
The LPAE code has been tested on a Versatile Express: V2F-2XV6 Cortex A15 and
V2P-CA15_A7 Cortex A15 tiles.
This patch set requires the following to be applied on top of 3.7-rc1:
"ARM: mm: introduce L_PTE_VALID for page table entries"
(PROT_NONE series, posted by Will on linux-arm-kernel)
- http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/126130.html
"mm: thp: Set the accessed flag for old pages on access fault."
(posted by Will on linux-mm)
- http://marc.info/?l=linux-kernel&m=135048927416117&w=2
Cheers,
--
Steve
[1] - http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/084359.html
Catalin Marinas (2):
ARM: mm: HugeTLB support for LPAE systems.
ARM: mm: Transparent huge page support for LPAE systems.
Steve Capper (4):
ARM: mm: correct pte_same behaviour for LPAE.
ARM: mm: Add support for flushing HugeTLB pages.
ARM: mm: HugeTLB support for non-LPAE systems.
ARM: mm: Transparent huge page support for non-LPAE systems.
arch/arm/Kconfig | 8 ++
arch/arm/include/asm/hugetlb-2level.h | 71 ++++++++++
arch/arm/include/asm/hugetlb-3level.h | 61 +++++++++
arch/arm/include/asm/hugetlb.h | 87 ++++++++++++
arch/arm/include/asm/pgtable-2level.h | 152 ++++++++++++++++++++-
arch/arm/include/asm/pgtable-3level-hwdef.h | 2 +
arch/arm/include/asm/pgtable-3level.h | 77 +++++++++++
arch/arm/include/asm/pgtable.h | 34 ++++-
arch/arm/include/asm/tlb.h | 16 ++-
arch/arm/include/asm/tlbflush.h | 2 +
arch/arm/kernel/head.S | 10 +-
arch/arm/mm/Makefile | 6 +
arch/arm/mm/dma-mapping.c | 2 +-
arch/arm/mm/fault.c | 6 +-
arch/arm/mm/flush.c | 25 ++--
arch/arm/mm/fsr-3level.c | 2 +-
arch/arm/mm/hugetlbpage-2level.c | 115 ++++++++++++++++
arch/arm/mm/hugetlbpage-3level.c | 190 +++++++++++++++++++++++++++
arch/arm/mm/hugetlbpage.c | 65 +++++++++
19 files changed, 909 insertions(+), 22 deletions(-)
create mode 100644 arch/arm/include/asm/hugetlb-2level.h
create mode 100644 arch/arm/include/asm/hugetlb-3level.h
create mode 100644 arch/arm/include/asm/hugetlb.h
create mode 100644 arch/arm/mm/hugetlbpage-2level.c
create mode 100644 arch/arm/mm/hugetlbpage-3level.c
create mode 100644 arch/arm/mm/hugetlbpage.c
--
1.7.9.5
^ permalink raw reply
* discrepancy while save and restore of debounce registers
From: Jon Hunter @ 2012-10-18 16:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1BAFE6F6C881BF42822005164F1491C33EAAA89B@DBDE01.ent.ti.com>
Hi Gururaja,
On 10/18/2012 12:31 AM, Hebbar, Gururaja wrote:
> Jon,
>
> On Thu, Oct 18, 2012 at 02:42:01, Hunter, Jon wrote:
[snip]
>>> My doubt/questions are
>>> 1. Why should debounce registers be updated only when it's accessed previously?
>>
>> If debounce is not being used by any of the gpios, then there is no need
>> to restore them as there are no bits set. So this makes sense and saves
>> a couple register writes.
>
> What I want to know is that other than saving register writes, is there any
> other important stuff that specifies this requirement.
>From a HW perspective, none that I can see.
>From a SW perspective, yes, as I mentioned if you restore these
registers without first initialising the context variables where these
registers are stored, then you may be restoring unknown values to the
registers and that is bad.
>>> 2. What is the relation between updating debounce registers and crash seen on
>>> others registers?
>>
>> This I am not sure about. I gave this a quick try on my omap3430 beagle
>> board, but I did not see any side-effects from doing this. However, if
>> you are always restoring the debounce context regardless of whether
>> debounce is being used, then you could be writing bad values to the
>> debounce registers as the context variables bank->context.debouce and
>> bank->context.debouce_en may not initialised. So that is bad. However,
>> that said I am still not sure how this could cause a crash.
>>
>> Can you share more details on ...
>
> Sorry for missing below details in first post.
>
>> 1. The OMAP platform you are using?
>
> I was trying this on TI AM335x platform (repo below). On AM335x EVM board
>
> http://arago-project.org/git/projects/?p=linux-am33x.git;a=shortlog;
> h=refs/heads/v3.2-staging
>
>> 2. What linux distro/environment you are using?
>
> Arago AM335x PSP release (linux 3.2 + am335x patch-set)
>
>> 3. If there are any specific steps to reproduce this 100% of the time?
>
> On top of this tree, try suspend/resume using "echo mem > /syspower/state"
I have a beagle-bone but unfortunately, suspend does not appear to be
supported in the mainline kernel yet so I am unable to test this on the
am335x on the mainline.
Have you compared the gpio driver from your v3.2 branch with the current
mainline to see how different this code is? Ideally, it would be good to
test on the mainline kernel for another data point to see if this is
local to your branch.
Cheers
Jon
^ permalink raw reply
* [PATCH 3/5] net: davinci_mdio: Fix type mistake in calling runtime-pm api
From: Hiremath, Vaibhav @ 2012-10-18 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <62191bdcb85ab48f5ea16fe69c2f92aa9e9a0a8b.1350327325.git.richardcochran@gmail.com>
On Tue, Oct 16, 2012 at 00:46:33, Richard Cochran wrote:
> From: Vaibhav Hiremath <hvaibhav@ti.com>
>
> By mistake (most likely a copy-paste), instead of pm_runtime_get_sync()
> api, driver is calling pm_runtime_put_sync() api in resume callback
> function. The bug was introduced by commit id (ae2c07aaf74:
> davinci_mdio: runtime PM support).
>
> Now, the reason why it didn't impact functionality is, the patch has
> been tested on AM335x-EVM and BeagleBone platform while submitting;
> and in case of AM335x the MDIO driver doesn't control the module
> enable/disable part, which is handled by CPSW driver.
>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
Thanks for submitting the patches, I couldn't able to do it for almost 2
weeks now. I really appreciate it.
Thanks,
Vaibhav
> ---
> drivers/net/ethernet/ti/davinci_mdio.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
> index 51a96db..ae74280 100644
> --- a/drivers/net/ethernet/ti/davinci_mdio.c
> +++ b/drivers/net/ethernet/ti/davinci_mdio.c
> @@ -465,7 +465,7 @@ static int davinci_mdio_resume(struct device *dev)
> u32 ctrl;
>
> spin_lock(&data->lock);
> - pm_runtime_put_sync(data->dev);
> + pm_runtime_get_sync(data->dev);
>
> /* restart the scan state machine */
> ctrl = __raw_readl(&data->regs->control);
> --
> 1.7.2.5
>
>
^ permalink raw reply
* [PATCH 4/5] net: cpsw: Add parent<->child relation support between cpsw and mdio
From: Hiremath, Vaibhav @ 2012-10-18 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9a4368fa1264f573072544a34169a3f0f8797989.1350327325.git.richardcochran@gmail.com>
On Tue, Oct 16, 2012 at 00:46:34, Richard Cochran wrote:
> From: Vaibhav Hiremath <hvaibhav@ti.com>
>
> CPGMAC SubSystem consist of various sub-modules, like, mdio, cpdma,
> cpsw, etc... These sub-modules are also used in some of Davinci family
> of devices. Now based on requirement, use-case and available technology
> nodes the integration of these sub-modules varies across devices.
>
> So coming back to Linux net driver, currently separate and independent
> platform devices & drivers for CPSW and MDIO is implemented. In case of
> Davinci they both has separate control, from resources perspective,
> like clock.
>
> In case of AM33XX, the resources are shared and only one register
> bit-field is provided to control module/clock enable/disable, makes it
> difficult to handle common resource.
>
> So the solution here implemented in this patch is,
>
> Create parent<->child relationship between both the drivers, making
> CPSW as a parent and MDIO as its child and enumerate all the child nodes
> under cpsw module.
> Both the drivers will function exactly the way it was operating before,
> including runtime-pm functionality. No change is required in MDIO driver
> (for that matter to any child driver).
>
> As this is only supported during DT boot, the parent<->child relationship
> is created and populated in DT execution flow. The only required change
> is inside DTS file, making MDIO as a child to CPSW node.
>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> ---
> drivers/net/ethernet/ti/cpsw.c | 16 ++++++++++++++--
> 1 files changed, 14 insertions(+), 2 deletions(-)
>
Thanks for stepping ahead and submitting patches from my tree.
Thanks,
Vaibhav
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index df55e24..fb1a692 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -827,7 +827,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
> }
> data->mac_control = prop;
>
> - for_each_child_of_node(node, slave_node) {
> + for_each_node_by_name(slave_node, "slave") {
> struct cpsw_slave_data *slave_data = data->slave_data + i;
> const char *phy_id = NULL;
> const void *mac_addr = NULL;
> @@ -862,6 +862,14 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
> i++;
> }
>
> + /*
> + * Populate all the child nodes here...
> + */
> + ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
> + /* We do not want to force this, as in some cases may not have child */
> + if (ret)
> + pr_warn("Doesn't have any child node\n");
> +
> return 0;
>
> error_ret:
> @@ -895,6 +903,11 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
> priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
> priv->rx_packet_max = max(rx_packet_max, 128);
>
> + /*
> + * This may be required here for child devices.
> + */
> + pm_runtime_enable(&pdev->dev);
> +
> if (cpsw_probe_dt(&priv->data, pdev)) {
> pr_err("cpsw: platform data missing\n");
> ret = -ENODEV;
> @@ -921,7 +934,6 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
> for (i = 0; i < data->slaves; i++)
> priv->slaves[i].slave_num = i;
>
> - pm_runtime_enable(&pdev->dev);
> priv->clk = clk_get(&pdev->dev, "fck");
> if (IS_ERR(priv->clk)) {
> dev_err(&pdev->dev, "fck is not found\n");
> --
> 1.7.2.5
>
>
^ permalink raw reply
* [PATCH 2/3] RTC: omap-rtc: enable pm_runtime
From: Vaibhav Hiremath @ 2012-10-18 16:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350575631-15523-2-git-send-email-zonque@gmail.com>
On 10/18/2012 9:23 PM, Daniel Mack wrote:
> This is needed as preparation for platforms where using pm runtime usage
> is mandatory.
>
> Signed-off-by: Daniel Mack <zonque@gmail.com>
It looks like, you just duplicated effort here.
RTC patches have been already submitted quite some time back for AM33xx,
probably you missed to do google before spending time on this.
Patch Series -
http://www.mail-archive.com/davinci-linux-open-source at linux.davincidsp.com/msg23253.html
Denial,
It would be really helpful if you could test these patches and ack them.
Just FYI, we have bunch of parallel activities going inside team to
upstream all the patches/module/drivers/features, so to avoid such
duplication of effort, I suggest you to google for the patches or ping
on mailing list.
Thanks,
Vaibhav
> ---
> drivers/rtc/rtc-omap.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
> index 0b614e3..baa876e 100644
> --- a/drivers/rtc/rtc-omap.c
> +++ b/drivers/rtc/rtc-omap.c
> @@ -17,6 +17,7 @@
> #include <linux/module.h>
> #include <linux/ioport.h>
> #include <linux/delay.h>
> +#include <linux/pm_runtime.h>
> #include <linux/rtc.h>
> #include <linux/bcd.h>
> #include <linux/platform_device.h>
> @@ -322,6 +323,9 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
> goto fail;
> }
>
> + pm_runtime_enable(&pdev->dev);
> + pm_runtime_get_sync(&pdev->dev);
> +
> rtc = rtc_device_register(pdev->name, &pdev->dev,
> &omap_rtc_ops, THIS_MODULE);
> if (IS_ERR(rtc)) {
> @@ -420,6 +424,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
> free_irq(omap_rtc_alarm, rtc);
>
> rtc_device_unregister(rtc);
> + pm_runtime_put_sync(&pdev->dev);
> + pm_runtime_disable(&pdev->dev);
> iounmap(rtc_base);
> release_mem_region(mem->start, resource_size(mem));
> return 0;
> @@ -442,11 +448,15 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
> else
> rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
>
> + pm_runtime_put_sync(&pdev->dev);
> +
> return 0;
> }
>
> static int omap_rtc_resume(struct platform_device *pdev)
> {
> + pm_runtime_get_sync(&pdev->dev);
> +
> if (device_may_wakeup(&pdev->dev))
> disable_irq_wake(omap_rtc_alarm);
> else
>
^ permalink raw reply
* [PATCH] ARM: mach-imx: Support for DryIce RTC in i.MX53
From: Roland Stigge @ 2012-10-18 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576370-29098-1-git-send-email-stigge@antcom.de>
This patch enables support for i.MX53 in addition to i.MX25 by providing a
dummy clock on i.MX53 since this one doesn't have a separate clock for internal
RTC but the driver requests one.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
arch/arm/mach-imx/clk-imx51-imx53.c | 1 +
1 file changed, 1 insertion(+)
--- linux-2.6.orig/arch/arm/mach-imx/clk-imx51-imx53.c
+++ linux-2.6/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -467,6 +467,7 @@ int __init mx53_clocks_init(unsigned lon
clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can");
clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can");
clk_register_clkdev(clk[can2_serial_gate], "per", "53fcc000.can");
+ clk_register_clkdev(clk[dummy], NULL, "53fa4000.rtc");
/* set SDHC root clock to 200MHZ*/
clk_set_rate(clk[esdhc_a_podf], 200000000);
^ permalink raw reply
* [PATCH 2/2] rtc-imxdi: Add devicetree support
From: Roland Stigge @ 2012-10-18 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350576370-29098-1-git-send-email-stigge@antcom.de>
This patch adds device tree support to the rtc-imxdi driver.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
Documentation/devicetree/bindings/rtc/imxdi-rtc.txt | 17 +++++++++++++++++
drivers/rtc/rtc-imxdi.c | 11 +++++++++++
2 files changed, 28 insertions(+)
--- /dev/null
+++ linux-2.6/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt
@@ -0,0 +1,17 @@
+* i.MX25 Real Time Clock controller
+
+This binding supports the following chips: i.MX25, i.MX53
+
+Required properties:
+- compatible: should be: "fsl,imx25-rtc"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: rtc alarm interrupt
+
+Example:
+
+rtc at 80056000 {
+ compatible = "fsl,imx53-rtc", "fsl,imx25-rtc";
+ reg = <0x80056000 2000>;
+ interrupts = <29>;
+};
--- linux-2.6.orig/drivers/rtc/rtc-imxdi.c
+++ linux-2.6/drivers/rtc/rtc-imxdi.c
@@ -37,6 +37,7 @@
#include <linux/rtc.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include <linux/of.h>
/* DryIce Register Definitions */
@@ -493,10 +494,20 @@ static int __devexit dryice_rtc_remove(s
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id dryice_dt_ids[] = {
+ { .compatible = "fsl,imx25-rtc" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, dryice_dt_ids);
+#endif
+
static struct platform_driver dryice_rtc_driver = {
.driver = {
.name = "imxdi_rtc",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dryice_dt_ids),
},
.remove = __devexit_p(dryice_rtc_remove),
};
^ permalink raw reply
* [PATCH 1/2] rtc-imxdi: Support for i.MX53
From: Roland Stigge @ 2012-10-18 16:06 UTC (permalink / raw)
To: linux-arm-kernel
This patch enables support for i.MX53 in addition to i.MX25 by enabling the
driver on ARCH_MXC generally.
Signed-off-by: Roland Stigge <stigge@antcom.de>
---
drivers/rtc/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-2.6.orig/drivers/rtc/Kconfig
+++ linux-2.6/drivers/rtc/Kconfig
@@ -768,7 +768,7 @@ config RTC_DRV_DAVINCI
config RTC_DRV_IMXDI
tristate "Freescale IMX DryIce Real Time Clock"
- depends on SOC_IMX25
+ depends on ARCH_MXC
help
Support for Freescale IMX DryIce RTC
^ permalink raw reply
* [GIT PULL] DeviceTree fixes for 3.7
From: Rob Herring @ 2012-10-18 16:02 UTC (permalink / raw)
To: linux-arm-kernel
Linus,
Please pull DeviceTree fixes for 3.7.
Rob
The following changes since commit ddffeb8c4d0331609ef2581d84de4d763607bd37:
Linux 3.7-rc1 (2012-10-14 14:41:04 -0700)
are available in the git repository at:
git://sources.calxeda.com/kernel/linux.git tags/dt-fixes-for-3.7
for you to fetch changes up to 205a8eb7ce713c7f1722297dd97d19dcea6f266c:
dtc: fix for_each_*() to skip first object if deleted (2012-10-17 15:53:04 -0500)
----------------------------------------------------------------
DeviceTree fixes for 3.7
A handful of fixes:
- a fix for dtc from upstream
- sparse fixes in DeviceTree code
- stub of_get_child_by_name for !OF builds
----------------------------------------------------------------
Kim Phillips (3):
of/address: sparse fixes
of/irq: sparse fixes
of/platform: sparse fix
Olof Johansson (1):
of: add stub of_get_child_by_name for non-OF builds
Stephen Warren (1):
dtc: fix for_each_*() to skip first object if deleted
drivers/of/address.c | 24 ++++++++++++------------
drivers/of/irq.c | 8 +++++---
drivers/of/platform.c | 2 +-
include/linux/of.h | 7 +++++++
include/linux/of_address.h | 4 ++--
include/linux/of_irq.h | 4 ++--
scripts/dtc/dtc.h | 44 ++++++++++----------------------------------
7 files changed, 39 insertions(+), 54 deletions(-)
^ permalink raw reply
* [PATCH 3/3] RTC: omap-rtc: add DT bindings
From: Daniel Mack @ 2012-10-18 15:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350575631-15523-1-git-send-email-zonque@gmail.com>
This adds bindings for the OMAP RTC driver.
There are currently two compatible string it matches, "ti,omap-rtc" and
"ti,am33xx-rtc". This is done because the AM33xx needs extra registers
to be written in order to unlock the register set.
Also, the OMAP_RTC_OSC_REG can be set up via DT, in particular two bits:
32KCLK_EN - Selects external clock source, namely
rtc_32k_clk_rtc_32k_clk that is from the
32-kHz oscillator
32KCLK_SEL - 32-kHz clock enable post clock mux of
rtc_32k_clk_rtc_32k_aux_clk and
rtc_32k_clk_rtc_32k_clk
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
Documentation/devicetree/bindings/rtc/omap-rtc.txt | 25 +++++++
drivers/rtc/rtc-omap.c | 78 ++++++++++++++++++++++
2 files changed, 103 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/omap-rtc.txt
diff --git a/Documentation/devicetree/bindings/rtc/omap-rtc.txt b/Documentation/devicetree/bindings/rtc/omap-rtc.txt
new file mode 100644
index 0000000..a2abc9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/omap-rtc.txt
@@ -0,0 +1,25 @@
+* OMAP RTC
+
+Required properties:
+- compatible : Should be "ti,omap-rtc" or "ti,am33xx-rtc"
+
+
+Optional properties for AM33xx
+- ti,rtc-external-osc - Selects external clock source, namely
+ rtc_32k_clk_rtc_32k_clk that is from the
+ 32-kHz oscillator
+
+- ti,rtc-32clk-enable - 32-kHz clock enable post clock mux of
+ rtc_32k_clk_rtc_32k_aux_clk and
+ rtc_32k_clk_rtc_32k_clk
+
+Example for AM33xx:
+
+rtc at 44e3e000 {
+ compatible = "marvell,am33xx-rtc";
+ reg = <0x44e3e000 0x1000>;
+ interrupts = <75 76>;
+ ti,hwmods = "rtc";
+ ti,rtc-32clk-enable;
+ ti,rtc-external-osc;
+};
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index baa876e..5529719 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -21,6 +21,8 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <asm/io.h>
@@ -65,6 +67,9 @@
#define OMAP_RTC_COMP_MSB_REG 0x50
#define OMAP_RTC_OSC_REG 0x54
+#define AM33XX_RTC_KICK0R_REG 0x6c
+#define AM33XX_RTC_KICK1R_REG 0x70
+
/* OMAP_RTC_CTRL_REG bit fields: */
#define OMAP_RTC_CTRL_SPLIT (1<<7)
#define OMAP_RTC_CTRL_DISABLE (1<<6)
@@ -286,6 +291,76 @@ static struct rtc_class_ops omap_rtc_ops = {
static int omap_rtc_alarm;
static int omap_rtc_timer;
+enum {
+ OMAP_RTC_HW_OMAP = 0,
+ OMAP_RTC_HW_AM33XX,
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id of_omap_rtc_match[] = {
+ {
+ .compatible = "ti,omap-rtc",
+ .data = (void *) OMAP_RTC_HW_OMAP,
+ },
+ {
+ .compatible = "ti,am33xx-rtc",
+ .data = (void *) OMAP_RTC_HW_AM33XX,
+ },
+ { }
+};
+
+static int omap_rtc_probe_dt(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match;
+ int hw_type;
+ u32 val;
+
+ match = of_match_device(of_omap_rtc_match, &pdev->dev);
+
+ if (!match)
+ return 0;
+
+ hw_type = (int) match->data;
+
+ if (hw_type == OMAP_RTC_HW_AM33XX) {
+ /*
+ * From the datasheet:
+ *
+ * The kick registers (KICKnR) are used to enable and disable
+ * write protection on the RTC registers. Out of reset, the RTC
+ * registers are write-protected. To disable write protection,
+ * correct keys must be written to the KICKnR registers. The
+ * Kick0 register allows writing to unlock the kick0 data.
+ */
+ __raw_writel(0x83e70b13, rtc_base + AM33XX_RTC_KICK0R_REG);
+ __raw_writel(0x95a4f1e0, rtc_base + AM33XX_RTC_KICK1R_REG);
+
+ /* Set RTC_OSC_REG */
+ val = __raw_readl(rtc_base + OMAP_RTC_OSC_REG);
+ if (of_get_property(np, "ti,rtc-32clk-enable", NULL))
+ val |= (1 << 6);
+ else
+ val &= ~(1 << 6);
+
+ if (of_get_property(np, "ti,rtc-external-osc", NULL))
+ val |= (1 << 3);
+ else
+ val &= ~(1 << 3);
+
+ __raw_writel(val, rtc_base + OMAP_RTC_OSC_REG);
+ }
+
+ return 0;
+}
+
+#else
+static int omap_rtc_probe_dt(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
static int __init omap_rtc_probe(struct platform_device *pdev)
{
struct resource *res, *mem;
@@ -326,6 +401,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
+ omap_rtc_probe_dt(pdev);
+
rtc = rtc_device_register(pdev->name, &pdev->dev,
&omap_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
@@ -483,6 +560,7 @@ static struct platform_driver omap_rtc_driver = {
.driver = {
.name = "omap_rtc",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(of_omap_rtc_match),
},
};
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/3] RTC: omap-rtc: enable pm_runtime
From: Daniel Mack @ 2012-10-18 15:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350575631-15523-1-git-send-email-zonque@gmail.com>
This is needed as preparation for platforms where using pm runtime usage
is mandatory.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/rtc/rtc-omap.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 0b614e3..baa876e 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/platform_device.h>
@@ -322,6 +323,9 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
goto fail;
}
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
rtc = rtc_device_register(pdev->name, &pdev->dev,
&omap_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
@@ -420,6 +424,8 @@ static int __exit omap_rtc_remove(struct platform_device *pdev)
free_irq(omap_rtc_alarm, rtc);
rtc_device_unregister(rtc);
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
iounmap(rtc_base);
release_mem_region(mem->start, resource_size(mem));
return 0;
@@ -442,11 +448,15 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
else
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+ pm_runtime_put_sync(&pdev->dev);
+
return 0;
}
static int omap_rtc_resume(struct platform_device *pdev)
{
+ pm_runtime_get_sync(&pdev->dev);
+
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(omap_rtc_alarm);
else
--
1.7.11.7
^ permalink raw reply related
* [PATCH 1/3] RTC: omap-rtc: enable for SOC_AM33XX
From: Daniel Mack @ 2012-10-18 15:53 UTC (permalink / raw)
To: linux-arm-kernel
The same IP is found on AM33xx as well, so let users select it.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/rtc/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 19c03ab..5cb5be7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -777,7 +777,7 @@ config RTC_DRV_IMXDI
config RTC_DRV_OMAP
tristate "TI OMAP1"
- depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX
+ depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX
help
Say "yes" here to support the real time clock on TI OMAP1 and
DA8xx/OMAP-L13x chips. This driver can also be built as a
--
1.7.11.7
^ permalink raw reply related
* [PATCH v2 1/5] ARM: bcm476x: Add platform infrastructure
From: Domenico Andreoli @ 2012-10-18 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201210181348.02110.arnd@arndb.de>
On Thu, Oct 18, 2012 at 01:48:01PM +0000, Arnd Bergmann wrote:
> On Sunday 14 October 2012, Domenico Andreoli wrote:
> > From: Domenico Andreoli <domenico.andreoli@linux.com>
> >
> > Platform infrastructure for the Broadcom BCM476x ARMv6 SoCs.
>
> Hi Domenico,
Hi Arnd,
> All your patches look good to me now, except for one thing throughout
> the bindings:
>
> > Index: b/Documentation/devicetree/bindings/arm/bcm476x.txt
> > ===================================================================
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/bcm476x.txt
> > @@ -0,0 +1,15 @@
> > +Broadcom BCM4760 and BCM4761 SoCs device tree bindings
> > +------------------------------------------------------
> > +
> > +Boards with the BCM4760 SoC shall have the following properties:
> > +
> > +Required root node property:
> > +
> > +compatible = "brcm,bcm4760";
> > +
> > +
> > +Boards with the BCM4761 SoC shall have the following properties:
> > +
> > +Required root node property:
> > +
> > +compatible = "brcm,bcm4761";
>
> I probably wasn't clear enough with my request to have specific
> chip identifiers in the device tree "compatible" nodes. The idea
> generally is that for completely identical hardware blocks, you
> just need to put the first known variant into the driver, e.g.
> "brcm,bcm4760-system-timer", and in case of a later chip that
> is compatible with it, you list both "brcm,bcm4760-system-timer"
> and "brcm,bcm4761-system-timer" in the compatible property of the
> device tree. The way you did it is also correct and works, but
> is a bit less common.
>
> How do you want to merge your patches? The preferred way from
> our side is to get a pull request from you sent to arm at kernel.org
> with Cc to the linux-arm-kernel mailing list, but we can also
> pick up the patches separately if necessary.
so the above becomes:
Index: b/Documentation/devicetree/bindings/arm/bcm476x.txt
===================================================================
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm476x.txt
@@ -0,0 +1,15 @@
+Broadcom BCM4760 and BCM4761 SoCs device tree bindings
+------------------------------------------------------
+
+Boards with the BCM4760 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "brcm,bcm4760";
+
+
+Boards with the BCM4761 SoC shall have the following properties:
+
+Required root node property:
+
+compatible = "brcm,bcm4760", "brcm,bcm4761";
and the dt_mach in the board file is left only with "brcm,bcm4760" until
required otherwise. The same applies to drivers.
Does the order matter?
> For the patches that go into different directories like the clk
> and the clocksource drivers, please Cc the respective subsystem
> maintainers and ask them for an Ack. It certainly makes sense
> for a new platform port to get merged through the arm-soc tree,
> but any future improvements should normally just go through the
> subsystem trees.
I'd prefer patches but only because I've not any public git repository. If
the git pull is much more preferred, I surely can manage it.
Thanks,
Domenico
^ permalink raw reply
* [PATCH] dma: add new DMA control commands
From: Jassi Brar @ 2012-10-18 15:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMiH66H=VMEgHFMdEhCTqA5AtVw6iN97-cbwUd86Ghd77OLcWA@mail.gmail.com>
On 18 October 2012 20:48, Huang Shijie <shijie8@gmail.com> wrote:
> On Thu, Oct 18, 2012 at 5:29 AM, Jassi Brar <jaswinder.singh@linaro.org> wrote:
>> On 18 October 2012 12:15, Huang Shijie <b32955@freescale.com> wrote:
>>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>>
>>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>>> to dmaengine. Can be done in tx_submit callback.
>>>> Similarly remove the clock when dma transaction gets completed.
>>>
>>> I ever thought this method too.
>>>
>>> But it will become low efficient in the following case:
>>>
>>> Assuming the gpmi-nand driver has to read out 1024 pages in one _SINGLE_
>>> read operation.
>>> The gpmi-nand will submit the descriptor to dmaengine per page. So with your
>>> method,
>>> the system will repeat the enable/disable dma clock 1024 time. At every
>>> enable/disable dma clock,
>>> the system has to enable the clock chain and it's parents ...
>>>
>>> But with this patch, we only need to enable/disable dma clock one time, just
>>> at we select the nand chip.
>>>
>> If the clock is the dmac's property (not channels'), the toggling
>> seems too aggressive.
>> You could try using runtime_suspend/resume for clock
>> disabling/enabling. How about employing autosuspend with a few ms
>> delay?
>
> Yes, employing the autosuspend is workable method too.o
> But it's a little more complicated then this patch. You have to create
> a thread or workqueue to
> do the job.
>
I am not sure why you would need to create any thread/workqueue ?
Just pm_runtime_put_autosuspend() in drivers/ to see how it works.
^ permalink raw reply
* [PATCH] dma: add new DMA control commands
From: Huang Shijie @ 2012-10-18 15:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJe_ZhfarH-HpJkEOpH=jY1Gc-UPEyuA4bJ4LSQES7Uyea2BQw@mail.gmail.com>
On Thu, Oct 18, 2012 at 5:29 AM, Jassi Brar <jaswinder.singh@linaro.org> wrote:
> On 18 October 2012 12:15, Huang Shijie <b32955@freescale.com> wrote:
>> ? 2012?10?18? 14:18, Vinod Koul ??:
>>
>>> Why cant you do start (prepare clock etc) when you submit the descriptor
>>> to dmaengine. Can be done in tx_submit callback.
>>> Similarly remove the clock when dma transaction gets completed.
>>
>> I ever thought this method too.
>>
>> But it will become low efficient in the following case:
>>
>> Assuming the gpmi-nand driver has to read out 1024 pages in one _SINGLE_
>> read operation.
>> The gpmi-nand will submit the descriptor to dmaengine per page. So with your
>> method,
>> the system will repeat the enable/disable dma clock 1024 time. At every
>> enable/disable dma clock,
>> the system has to enable the clock chain and it's parents ...
>>
>> But with this patch, we only need to enable/disable dma clock one time, just
>> at we select the nand chip.
>>
> If the clock is the dmac's property (not channels'), the toggling
> seems too aggressive.
> You could try using runtime_suspend/resume for clock
> disabling/enabling. How about employing autosuspend with a few ms
> delay?
Yes, employing the autosuspend is workable method too.o
But it's a little more complicated then this patch. You have to create
a thread or workqueue to
do the job.
What's more, I think other DMA engine may also meets the same issue as
the mxs-dma, such as the imx-sdma.
It's somehow a common issue to disable the clocks when no one use the
DMA engine.
Do you also suggest employing the autosuspend? Why not use a simple
way to handle this issue?
When the dma device want to use a DMA engine, it just needs to issue a
DMA_START command.
thanks
Huang Shijie
Huang Shijie
^ permalink raw reply
* [PATCH 1/2] video: Add support for the Solomon SSD1307 OLED Controller
From: Maxime Ripard @ 2012-10-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50761BB0.3080507@gmx.de>
Hi Florian,
Le 11/10/2012 03:06, Florian Tobias Schandinat a ?crit :
> Hi Maxime,
>
> On 09/25/2012 10:06 AM, Maxime Ripard wrote:
>> Hello Florian,
>>
>> Le 21/09/2012 16:04, Maxime Ripard a ?crit :
>>> Le 20/09/2012 18:33, Maxime Ripard a ?crit :
>>>> This patch adds support for the Solomon SSD1307 OLED
>>>> controller found on the Crystalfontz CFA10036 board.
>>>>
>>>> This controller can drive a display with a resolution up
>>>> to 128x39 and can operate over I2C or SPI.
>>>>
>>>> The current driver has only been tested on the CFA-10036,
>>>> that is using this controller over I2C to driver a 96x16
>>>> OLED screen.
>>>>
>>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>> Cc: Brian Lilly <brian@crystalfontz.com>
>>>
>>> Would you consider merging this patch or review it?
>>> It has been around for quite some time now and has not received any
>>> comments for at least the 2 last versions, so I guess there is not much
>>> left holding it back (unless, of course, if you have some comments to
>>> address), and I really would like to have it in 3.7.
>>
>> I guess we missed the 3.7 merge here. That's no big deal, but I sent the
>> patch series on a regular basis, starting 07/17 (sent new versions on
>> 07/31, 08/23, 09/05 and 09/20), addressed all the issues that were
>> raised, and never got any feedback from you, either positive or
>> negative. The patches affecting the MX28 device trees have already been
>> merged by Shawn Guo into its tree, so only the driver and the bindings
>> remain to be merged. So I'm kind of lost on what should I do here?
>>
>> Is it because I have an obviously broken driver or you don't have enough
>> time, or you don't want to merge drivers for such type of low resolution
>> controllers, or any other reason?
>
> I don't see any reason to not support low resolutions, might be a nice
> status monitor for embedded devices.
> It's not your fault. It's just that for the past two months writing my
> thesis reduced my free time (and hence the time that I could potentially
> use for reviewing patches) to approximately zero. While I managed to get
> some smaller patches done, there really wasn't any time to process the
> 3-4 completely new things pending and some scarier patches which touch
> the core infrastructure.
> I think that it should be better soon, at least my thesis is now done,
> but I also have to fix up the rest of my life that was neglected while
> writing, including my paid jobs.
Ok, that's fine :)
How do you want to proceed? To you want me to resend the patchset, or
you will review this one when you will have some time?
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] dma: add new DMA control commands
From: Huang Shijie @ 2012-10-18 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201210181251.15116.marex@denx.de>
On Thu, Oct 18, 2012 at 6:51 AM, Marek Vasut <marex@denx.de> wrote:
> Dear Huang Shijie,
>
>> ? 2012?10?18? 16:49, Marek Vasut ??:
>> > Dear Huang Shijie,
>> >
>> >> ? 2012?10?18? 16:16, Marek Vasut ??:
>> >>> So we can't stream data from the chip? About time to adjust the MTD
>> >>> framework to allow that. Maybe implement a command queue?
>> >>
>> >> IMHO, it's not possible. Because the READ-PAGE(00h-30h) command needs to
>> >> check the busy status
>> >> which means we have to stop in the middle, so we can not chain the all
>> >> the read-pages DMA commands.
>> >
>> > Can the DMA not branch?
>>
>> it's too complicated to the MTD layer, as well as the gpmi driver.
>
> Can you please elaborate ?
could you read the nand spec about how to read a page out with the
READ-PAGE(00-30) command,
and tell me how to make the DMA branch?
I really have no idea about how to make the DMA branch.
thanks
Huang Shijie
.
> Best regards,
> Marek Vasut
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox