* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEB
From: Marek Szyprowski @ 2012-12-03 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121202140644.GP30633@8bytes.org>
On 12/2/2012 3:06 PM, Joerg Roedel wrote:
> Hi Marek,
>
> On Mon, Nov 26, 2012 at 11:57:19AM +0100, Marek Szyprowski wrote:
>
> > I've took all the patches to the next-dma-debug branch in my tree, I sorry
> > that You have to wait so long for it. My branch is based on Joerg's
> > dma-debug branch and I've included it for testing in linux-next branch.
>
> The patches are now two times in next. One version from my tree and one
> from yours. Please remove the version from your tree, the patches should
> go upstream via my dma-debug branch.
Ok, I've removed them from my dma-mapping-next tree. Please add/cherry-pick
the missing patch for ARM architecture, which I've accidentally already
pushed to mainline some time ago and then reverted. See commit
871ae57adc5ed092 (and 697575896670ba).
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply
* Re: [PATCH 1/1] ARM: shmobile: Remove duplicate inclusion of dma-mapping.h in setup-r8a7740.c
From: Simon Horman @ 2012-12-03 7:29 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <1353393549-1532-1-git-send-email-sachin.kamat@linaro.org>
On Mon, Dec 03, 2012 at 09:43:14AM +0530, Sachin Kamat wrote:
> On 30 November 2012 14:26, Simon Horman <horms@verge.net.au> wrote:
> > On Tue, Nov 27, 2012 at 09:05:25AM +0530, Sachin Kamat wrote:
> >> ping
> >
> > Sorry for missing this. I have applied it now and
>
> Thanks Simon.
>
> > I expect it will be included in 3.9.
>
> Oh. I thought it might get included in 3.8 itself.
Sorry, due to the path that patches for shmobile take to the kernel
its already a bit too late for 3.8.
^ permalink raw reply
* Re: [PATCH 1/1] ARM: shmobile: Remove duplicate inclusion of dma-mapping.h in setup-r8a7740.c
From: Sachin Kamat @ 2012-12-03 4:25 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <1353393549-1532-1-git-send-email-sachin.kamat@linaro.org>
On 30 November 2012 14:26, Simon Horman <horms@verge.net.au> wrote:
> On Tue, Nov 27, 2012 at 09:05:25AM +0530, Sachin Kamat wrote:
>> ping
>
> Sorry for missing this. I have applied it now and
Thanks Simon.
> I expect it will be included in 3.9.
Oh. I thought it might get included in 3.8 itself.
--
With warm regards,
Sachin
^ permalink raw reply
* Re: [Patch v4 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Jianguo Wu @ 2012-12-03 2:23 UTC (permalink / raw)
To: Wen Congyang
Cc: x86, linux-mm, linux-kernel, linuxppc-dev, linux-acpi, linux-s390,
linux-sh, linux-ia64, cmetcalf, sparclinux, David Rientjes,
Jiang Liu, Len Brown, benh, paulus, Christoph Lameter,
Minchan Kim, Andrew Morton, KOSAKI Motohiro, Yasuaki Ishimatsu
In-Reply-To: <50B80FB1.6040906@cn.fujitsu.com>
Hi Congyang,
This is the new version.
Thanks,
Jianguo Wu.
Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
include/linux/mm.h | 1 +
mm/sparse-vmemmap.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++
mm/sparse.c | 3 +-
3 files changed, 234 insertions(+), 1 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5657670..1f26af5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1642,6 +1642,7 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
void vmemmap_populate_print_last(void);
void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
unsigned long size);
+void vmemmap_free(struct page *memmap, unsigned long nr_pages);
enum mf_flags {
MF_COUNT_INCREASED = 1 << 0,
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 1b7e22a..748732d 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -29,6 +29,10 @@
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
+#ifdef CONFIG_MEMORY_HOTREMOVE
+#include <asm/tlbflush.h>
+#endif
+
/*
* Allocate a block of memory to be used to back the virtual memory map
* or to back the page tables that are used to create the mapping.
@@ -224,3 +228,230 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
vmemmap_buf_end = NULL;
}
}
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+
+#define PAGE_INUSE 0xFD
+
+static void vmemmap_free_pages(struct page *page, int order)
+{
+ struct zone *zone;
+ unsigned long magic;
+
+ magic = (unsigned long) page->lru.next;
+ if (magic = SECTION_INFO || magic = MIX_SECTION_INFO) {
+ put_page_bootmem(page);
+
+ zone = page_zone(page);
+ zone_span_writelock(zone);
+ zone->present_pages++;
+ zone_span_writeunlock(zone);
+ totalram_pages++;
+ } else
+ free_pages((unsigned long)page_address(page), order);
+}
+
+static void free_pte_table(pmd_t *pmd)
+{
+ pte_t *pte, *pte_start;
+ int i;
+
+ pte_start = (pte_t *)pmd_page_vaddr(*pmd);
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+ pte = pte_start + i;
+ if (pte_val(*pte))
+ return;
+ }
+
+ /* free a pte talbe */
+ vmemmap_free_pages(pmd_page(*pmd), 0);
+ spin_lock(&init_mm.page_table_lock);
+ pmd_clear(pmd);
+ spin_unlock(&init_mm.page_table_lock);
+}
+
+static void free_pmd_table(pud_t *pud)
+{
+ pmd_t *pmd, *pmd_start;
+ int i;
+
+ pmd_start = (pmd_t *)pud_page_vaddr(*pud);
+ for (i = 0; i < PTRS_PER_PMD; i++) {
+ pmd = pmd_start + i;
+ if (pmd_val(*pmd))
+ return;
+ }
+
+ /* free a pmd talbe */
+ vmemmap_free_pages(pud_page(*pud), 0);
+ spin_lock(&init_mm.page_table_lock);
+ pud_clear(pud);
+ spin_unlock(&init_mm.page_table_lock);
+}
+
+static void free_pud_table(pgd_t *pgd)
+{
+ pud_t *pud, *pud_start;
+ int i;
+
+ pud_start = (pud_t *)pgd_page_vaddr(*pgd);
+ for (i = 0; i < PTRS_PER_PUD; i++) {
+ pud = pud_start + i;
+ if (pud_val(*pud))
+ return;
+ }
+
+ /* free a pud table */
+ vmemmap_free_pages(pgd_page(*pgd), 0);
+ spin_lock(&init_mm.page_table_lock);
+ pgd_clear(pgd);
+ spin_unlock(&init_mm.page_table_lock);
+}
+
+static int split_large_page(pte_t *kpte, unsigned long address, pte_t *pbase)
+{
+ struct page *page = pmd_page(*(pmd_t *)kpte);
+ int i = 0;
+ unsigned long magic;
+ unsigned long section_nr;
+
+ __split_large_page(kpte, address, pbase);
+ __flush_tlb_all();
+
+ magic = (unsigned long) page->lru.next;
+ if (magic = SECTION_INFO) {
+ section_nr = pfn_to_section_nr(page_to_pfn(page));
+ while (i < PTRS_PER_PMD) {
+ page++;
+ i++;
+ get_page_bootmem(section_nr, page, SECTION_INFO);
+ }
+ }
+
+ return 0;
+}
+
+static void vmemmap_pte_remove(pmd_t *pmd, unsigned long addr, unsigned long end)
+{
+ pte_t *pte;
+ unsigned long next;
+ void *page_addr;
+
+ pte = pte_offset_kernel(pmd, addr);
+ for (; addr < end; pte++, addr += PAGE_SIZE) {
+ next = (addr + PAGE_SIZE) & PAGE_MASK;
+ if (next > end)
+ next = end;
+
+ if (pte_none(*pte))
+ continue;
+ if (IS_ALIGNED(addr, PAGE_SIZE) &&
+ IS_ALIGNED(next, PAGE_SIZE)) {
+ vmemmap_free_pages(pte_page(*pte), 0);
+ spin_lock(&init_mm.page_table_lock);
+ pte_clear(&init_mm, addr, pte);
+ spin_unlock(&init_mm.page_table_lock);
+ } else {
+ /*
+ * Removed page structs are filled with 0xFD.
+ */
+ memset((void *)addr, PAGE_INUSE, next - addr);
+ page_addr = page_address(pte_page(*pte));
+
+ if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
+ spin_lock(&init_mm.page_table_lock);
+ pte_clear(&init_mm, addr, pte);
+ spin_unlock(&init_mm.page_table_lock);
+ }
+ }
+ }
+
+ free_pte_table(pmd);
+ __flush_tlb_all();
+}
+
+static void vmemmap_pmd_remove(pud_t *pud, unsigned long addr, unsigned long end)
+{
+ unsigned long next;
+ pmd_t *pmd;
+
+ pmd = pmd_offset(pud, addr);
+ for (; addr < end; addr = next, pmd++) {
+ next = pmd_addr_end(addr, end);
+ if (pmd_none(*pmd))
+ continue;
+
+ if (cpu_has_pse) {
+ unsigned long pte_base;
+
+ if (IS_ALIGNED(addr, PMD_SIZE) &&
+ IS_ALIGNED(next, PMD_SIZE)) {
+ vmemmap_free_pages(pmd_page(*pmd),
+ get_order(PMD_SIZE));
+ spin_lock(&init_mm.page_table_lock);
+ pmd_clear(pmd);
+ spin_unlock(&init_mm.page_table_lock);
+ continue;
+ }
+
+ /*
+ * We use 2M page, but we need to remove part of them,
+ * so split 2M page to 4K page.
+ */
+ pte_base = get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
+ if (!pte_base) {
+ WARN_ON(1);
+ continue;
+ }
+
+ split_large_page((pte_t *)pmd, addr, (pte_t *)pte_base);
+ __flush_tlb_all();
+
+ spin_lock(&init_mm.page_table_lock);
+ pmd_populate_kernel(&init_mm, pmd, (pte_t *)pte_base);
+ spin_unlock(&init_mm.page_table_lock);
+ }
+
+ vmemmap_pte_remove(pmd, addr, next);
+ }
+
+ free_pmd_table(pud);
+ __flush_tlb_all();
+}
+
+static void vmemmap_pud_remove(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ unsigned long next;
+ pud_t *pud;
+
+ pud = pud_offset(pgd, addr);
+ for (; addr < end; addr = next, pud++) {
+ next = pud_addr_end(addr, end);
+ if (pud_none(*pud))
+ continue;
+
+ vmemmap_pmd_remove(pud, addr, next);
+ }
+
+ free_pud_table(pgd);
+ __flush_tlb_all();
+}
+
+void vmemmap_free(struct page *memmap, unsigned long nr_pages)
+{
+ unsigned long addr = (unsigned long)memmap;
+ unsigned long end = (unsigned long)(memmap + nr_pages);
+ unsigned long next;
+
+ for (; addr < end; addr = next) {
+ pgd_t *pgd = pgd_offset_k(addr);
+
+ next = pgd_addr_end(addr, end);
+ if (!pgd_present(*pgd))
+ continue;
+
+ vmemmap_pud_remove(pgd, addr, next);
+ sync_global_pgds(addr, next - 1);
+ }
+}
+#endif
diff --git a/mm/sparse.c b/mm/sparse.c
index fac95f2..4060229 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -615,10 +615,11 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
}
static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
{
- return; /* XXX: Not implemented yet */
+ vmemmap_free(memmap, nr_pages);
}
static void free_map_bootmem(struct page *page, unsigned long nr_pages)
{
+ vmemmap_free(page, nr_pages);
}
#else
static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
--
1.7.6.1
On 2012/11/30 9:45, Wen Congyang wrote:
> At 11/28/2012 05:40 PM, Jianguo Wu Wrote:
>> Hi Congyang,
>>
>> I think vmemmap's pgtable pages should be freed after all entries are cleared, I have a patch to do this.
>> The code logic is the same as [Patch v4 09/12] memory-hotplug: remove page table of x86_64 architecture.
>>
>> How do you think about this?
>>
>> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> ---
>> include/linux/mm.h | 1 +
>> mm/sparse-vmemmap.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> mm/sparse.c | 5 +-
>> 3 files changed, 218 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 5657670..1f26af5 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1642,6 +1642,7 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
>> void vmemmap_populate_print_last(void);
>> void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
>> unsigned long size);
>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages);
>>
>> enum mf_flags {
>> MF_COUNT_INCREASED = 1 << 0,
>> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
>> index 1b7e22a..242cb28 100644
>> --- a/mm/sparse-vmemmap.c
>> +++ b/mm/sparse-vmemmap.c
>> @@ -29,6 +29,10 @@
>> #include <asm/pgalloc.h>
>> #include <asm/pgtable.h>
>>
>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>> +#include <asm/tlbflush.h>
>> +#endif
>> +
>> /*
>> * Allocate a block of memory to be used to back the virtual memory map
>> * or to back the page tables that are used to create the mapping.
>> @@ -224,3 +228,213 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
>> vmemmap_buf_end = NULL;
>> }
>> }
>> +
>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>> +static void vmemmap_free_pages(struct page *page, int order)
>> +{
>> + struct zone *zone;
>> + unsigned long magic;
>> +
>> + magic = (unsigned long) page->lru.next;
>> + if (magic = SECTION_INFO || magic = MIX_SECTION_INFO) {
>> + put_page_bootmem(page);
>> +
>> + zone = page_zone(page);
>> + zone_span_writelock(zone);
>> + zone->present_pages++;
>> + zone_span_writeunlock(zone);
>> + totalram_pages++;
>> + } else {
>> + if (is_vmalloc_addr(page_address(page)))
>> + vfree(page_address(page));
>
> Hmm, vmemmap doesn't use vmalloc() to allocate memory.
>
>> + else
>> + free_pages((unsigned long)page_address(page), order);
>> + }
>> +}
>> +
>> +static void free_pte_table(pmd_t *pmd)
>> +{
>> + pte_t *pte, *pte_start;
>> + int i;
>> +
>> + pte_start = (pte_t *)pmd_page_vaddr(*pmd);
>> + for (i = 0; i < PTRS_PER_PTE; i++) {
>> + pte = pte_start + i;
>> + if (pte_val(*pte))
>> + return;
>> + }
>> +
>> + /* free a pte talbe */
>> + vmemmap_free_pages(pmd_page(*pmd), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_clear(pmd);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static void free_pmd_table(pud_t *pud)
>> +{
>> + pmd_t *pmd, *pmd_start;
>> + int i;
>> +
>> + pmd_start = (pmd_t *)pud_page_vaddr(*pud);
>> + for (i = 0; i < PTRS_PER_PMD; i++) {
>> + pmd = pmd_start + i;
>> + if (pmd_val(*pmd))
>> + return;
>> + }
>> +
>> + /* free a pmd talbe */
>> + vmemmap_free_pages(pud_page(*pud), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pud_clear(pud);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static void free_pud_table(pgd_t *pgd)
>> +{
>> + pud_t *pud, *pud_start;
>> + int i;
>> +
>> + pud_start = (pud_t *)pgd_page_vaddr(*pgd);
>> + for (i = 0; i < PTRS_PER_PUD; i++) {
>> + pud = pud_start + i;
>> + if (pud_val(*pud))
>> + return;
>> + }
>> +
>> + /* free a pud table */
>> + vmemmap_free_pages(pgd_page(*pgd), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pgd_clear(pgd);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static int split_large_page(pte_t *kpte, unsigned long address, pte_t *pbase)
>> +{
>> + struct page *page = pmd_page(*(pmd_t *)kpte);
>> + int i = 0;
>> + unsigned long magic;
>> + unsigned long section_nr;
>> +
>> + __split_large_page(kpte, address, pbase);
>> + __flush_tlb_all();
>> +
>> + magic = (unsigned long) page->lru.next;
>> + if (magic = SECTION_INFO) {
>> + section_nr = pfn_to_section_nr(page_to_pfn(page));
>> + while (i < PTRS_PER_PMD) {
>> + page++;
>> + i++;
>> + get_page_bootmem(section_nr, page, SECTION_INFO);
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void vmemmap_pte_remove(pmd_t *pmd, unsigned long addr, unsigned long end)
>> +{
>> + pte_t *pte;
>> + unsigned long next;
>> +
>> + pte = pte_offset_kernel(pmd, addr);
>> + for (; addr < end; pte++, addr += PAGE_SIZE) {
>> + next = (addr + PAGE_SIZE) & PAGE_MASK;
>> + if (next > end)
>> + next = end;
>> +
>> + if (pte_none(*pte))
>> + continue;
>> + if (IS_ALIGNED(addr, PAGE_SIZE) &&
>> + IS_ALIGNED(end, PAGE_SIZE)) {
>> + vmemmap_free_pages(pte_page(*pte), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pte_clear(&init_mm, addr, pte);
>> + spin_unlock(&init_mm.page_table_lock);
>
> If addr or end is not alianed with PAGE_SIZE, you may leak some
> memory.
>
>> + }
>> + }
>> +
>> + free_pte_table(pmd);
>> + __flush_tlb_all();
>> +}
>> +
>> +static void vmemmap_pmd_remove(pud_t *pud, unsigned long addr, unsigned long end)
>> +{
>> + unsigned long next;
>> + pmd_t *pmd;
>> +
>> + pmd = pmd_offset(pud, addr);
>> + for (; addr < end; addr = next, pmd++) {
>> + next = pmd_addr_end(addr, end);
>> + if (pmd_none(*pmd))
>> + continue;
>> +
>> + if (cpu_has_pse) {
>> + unsigned long pte_base;
>> +
>> + if (IS_ALIGNED(addr, PMD_SIZE) &&
>> + IS_ALIGNED(next, PMD_SIZE)) {
>> + vmemmap_free_pages(pmd_page(*pmd),
>> + get_order(PMD_SIZE));
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_clear(pmd);
>> + spin_unlock(&init_mm.page_table_lock);
>> + continue;
>> + }
>> +
>> + /*
>> + * We use 2M page, but we need to remove part of them,
>> + * so split 2M page to 4K page.
>> + */
>> + pte_base = get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
>
> get_zeored_page() may fail. You should handle this error.
>
>> + split_large_page((pte_t *)pmd, addr, (pte_t *)pte_base);
>> + __flush_tlb_all();
>> +
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_populate_kernel(&init_mm, pmd, (pte_t *)pte_base);
>> + spin_unlock(&init_mm.page_table_lock);
>> + }
>> +
>> + vmemmap_pte_remove(pmd, addr, next);
>> + }
>> +
>> + free_pmd_table(pud);
>> + __flush_tlb_all();
>> +}
>> +
>> +static void vmemmap_pud_remove(pgd_t *pgd, unsigned long addr, unsigned long end)
>> +{
>> + unsigned long next;
>> + pud_t *pud;
>> +
>> + pud = pud_offset(pgd, addr);
>> + for (; addr < end; addr = next, pud++) {
>> + next = pud_addr_end(addr, end);
>> + if (pud_none(*pud))
>> + continue;
>> +
>> + vmemmap_pmd_remove(pud, addr, next);
>> + }
>> +
>> + free_pud_table(pgd);
>> + __flush_tlb_all();
>> +}
>> +
>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages)
>> +{
>> + unsigned long addr = (unsigned long)memmap;
>> + unsigned long end = (unsigned long)(memmap + nr_pages);
>> + unsigned long next;
>> +
>> + for (; addr < end; addr = next) {
>> + pgd_t *pgd = pgd_offset_k(addr);
>> +
>> + next = pgd_addr_end(addr, end);
>> + if (!pgd_present(*pgd))
>> + continue;
>> +
>> + vmemmap_pud_remove(pgd, addr, next);
>> + sync_global_pgds(addr, next);
>
> The parameter for sync_global_pgds() is [start, end], not
> [start, end)
>
>> + }
>> +}
>> +#endif
>> diff --git a/mm/sparse.c b/mm/sparse.c
>> index fac95f2..3a16d68 100644
>> --- a/mm/sparse.c
>> +++ b/mm/sparse.c
>> @@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
>> /* This will make the necessary allocations eventually. */
>> return sparse_mem_map_populate(pnum, nid);
>> }
>> -static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
>> +static void __kfree_section_memmap(struct page *page, unsigned long nr_pages)
> Why do you change this line?
>
>> {
>> - return; /* XXX: Not implemented yet */
>> + vmemmap_free(page, nr_pages);
>> }
>> static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>> {
>> + vmemmap_free(page, nr_pages);
>> }
>> #else
>> static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
>
>
> .
>
^ permalink raw reply related
* Re: [GIT PULL v2] Renesas ARM-based SoC maintainers for v3.8 #1
From: Simon Horman @ 2012-12-02 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121130165250.GB697@quad.lixom.net>
On Fri, Nov 30, 2012 at 08:52:50AM -0800, Olof Johansson wrote:
> On Thu, Nov 29, 2012 at 09:00:19AM +0900, Simon Horman wrote:
> > Hi Olof, Hi Arnd,
> >
> > Please consider the following maintainers change for 3.8.
> >
> > ----------------------------------------------------------------
> > 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://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git maintainers
>
> THanks, pulled into next/fixes-non-critical, since we've likely sent our last
> fixes batch to Linus.
Thanks, its clearly not a critical fix.
^ permalink raw reply
* Re: [PATCH 0/9] dma_debug: add debug_dma_mapping_error support to architectures that support DMA_DEB
From: Joerg Roedel @ 2012-12-02 14:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50B34B0F.3080204@samsung.com>
Hi Marek,
On Mon, Nov 26, 2012 at 11:57:19AM +0100, Marek Szyprowski wrote:
> I've took all the patches to the next-dma-debug branch in my tree, I sorry
> that You have to wait so long for it. My branch is based on Joerg's
> dma-debug branch and I've included it for testing in linux-next branch.
The patches are now two times in next. One version from my tree and one
from yours. Please remove the version from your tree, the patches should
go upstream via my dma-debug branch.
Joerg
^ permalink raw reply
* Re: [PATCH v2 00/77] SH pin control and GPIO rework with OF support
From: Linus Walleij @ 2012-12-01 22:55 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <1353974596-30033-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
On Tue, Nov 27, 2012 at 1:01 AM, Laurent Pinchart
<laurent.pinchart+renesas@ideasonboard.com> wrote:
> Here's the second version of the SH pin control and GPIO rework patches. I've
> added OF support for PFC instantiation and GPIO mappings that was missing from
> v1. PINCTRL bindings are still missing and will come soon.
So I've tried the only way I could to review this by cloning your tree
and actually inspecting the end result ... overall it's looking very good!
Here are assorted comments:
- Some use of __devicexit/__devinit, this will be deleted in the v3.8
merge window so just remove this everywhere.
- You're using the method to add ranges from the pinctrl side of
things. This is basically deprecated with the changes to gpiolib
I make in this merge window. If you study the way I changed
the pinctrl-u300.c and pinctrl-coh901.c to switch the registration
from being done in the pin controller to being done in the
gpiolib part, you will get the picture. The big upside is that
(A) makes the pin and GPIO references to the local GPIO
chip and pin controller and (B) that this supports adding ranges
from the device tree, which is probably what you want in the
end...
- The above probably means you can get rid of
sh_pfc_register_gpiochip() and decouple the pinctrl
and gpiolib code like I did in my patch set
(commit 8604ac34e in the pinctrl tree) and just
initialize the GPIO with some module_init().
But I might be wrong!
- sh_pfc_register_pinctrl() in pinctrl.c is using kzalloc/kfree,
but since it has a struct sh_pfc, which contains a
struct device *, I suspect you can use devm_kzalloc()
and cut the kfree():s. This probably applies in more
places in the driver.
- core.c contains pfc_ioremap() and pfc_iounmap()
which actually seem to exist much due to the fact
that devm_kzalloc() and devm_ioremap_nocache() did not
exist at the time. By using devm_* helpers and
maybe also inlining the code I think it'll look way
smoother.
- sh_pfc.h contains this:
typedef unsigned short pinmux_enum_t;
typedef unsigned short pinmux_flag_t;
But custom typedefs in the kernel is discouraged unless
there is a good reason for. What about you search/replace
this thing with u16 everywhere. I really like u16...
I can see macros building up some gigantic bit pattern in
these but in the end it's still just 16 unsigned bits.
The name "pinmux_enum_t" is very dangerously
close to the builting "enum" so it scares me a bit
for that reason too.
- sf_pfc.h contains a number of structs which I just
have no chance of understanding unless they are
supplied with something real nice like kerneldoc,
struct pinmux_gpio, pinmux_cfg_reg, pinmux_data_reg,
pinmux_irq, pinmux_range and sh_pfc_soc_info all
need some doc I think, I just don't understand these
structs.
- Same goes for the helper macros.
- In core.h document struct pfc_window, i.e. what are
these windows? What do we mean by a window?
How many of them exist in a certain configuration
typically? etc, stuff you want to know when reading
the code.
- struct sh_pfc is however quite self-explanatory.
- The pfc-* drivers include things like:
#include <cpu/sh7785.h>
#include <mach/r8a7740.h>
#include <mach/irqs.h>
#include <mach/r8a7779.h>
#include <mach/sh73a0.h>
#include <mach/irqs.h>
Why? Especially <mach/irqs.h> would be nice to
get rid of, as it sort of defeats the idea of passing
IRQs as resources or allocating them dynamically.
In some cases it seems these includes are just
surplus, so please look over this...
- This stuff in setup_data_regs():
rp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
drp->reg_width);
You know, I think shadow registers is just another name
for regmap-mmio. Please consult
drivers/base/regmap/regmap-mmio.c and tell me if I'm
wrong. It's not like I'm going to require you to convert this
to regmap from day 1 if this is legacy stuff but it's probably
the same thing.
- In core.c, gpio_read_raw_reg() and gpio_write_raw_reg()
are looking like marshalling functions to me. This is also
what regmap is about. Marshalling and caching/shadow.
If you keep the functions as they are, atleast rename them
to sh_pfc_* because the gpio_* namespace is for gpiolib.
(There are a few other functions that need to be prefixed
in that file by the way.)
- While keeping Magnus' and Paul's names as authors in the
files it would be proper if you atleast add your own name since
you've probably written most of the code in these files now.
Also for MODULE_AUTHOR().
Let's have this patchset finished for v3.9 say? :-)
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 3/5] ARM: mach-shmobile: sh73a0: Initialise MMCIF using DT
From: Simon Horman @ 2012-12-01 0:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3094701.LTMQnxTPNp@avalon>
On Fri, Nov 30, 2012 at 01:30:44PM +0100, Laurent Pinchart wrote:
> Hi Simon,
>
> Thank you for the patch.
>
> On Friday 30 November 2012 17:44:43 Simon Horman wrote:
> > From: Simon Horman <horms+renesas@verge.net.au>
> >
> > This device also requires a voltage regulator which
> > should be defined in a board-specific maner. An example
> > dts snipped follows.
> >
> > / {
> > fixedregulator1v8: fixedregulator@0 {
> > compatible = "regulator-fixed";
> > regulator-name = "fixed-1.8V";
> > regulator-min-microvolt = <1800000>;
> > regulator-max-microvolt = <1800000>;
> > };
> > };
> >
> > &mmcif {
> > vmmc-supply = <&fixedregulator1v8>;
> > vqmmc-supply = <&fixedregulator1v8>;
> > };
> >
> > Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> >
> > ---
> >
> > v2
> > * Removed SDHI intitialisation as the driver needs updating first
> > * Moved MMC DT from sh73a0.dtsi to sh73a0-reference.dtsi
> > as it is not appropriate for use by sh73a0-kzm9g.dts yet.
> > This is because sh73a0-kzm9g.dts and board-kzm9g.c use
> > both the GIC and INTC interrupt controllers to provide
> > access to a rich set of devices. This is achieved by initilising
> > the interrupt controllers using C code. Work on allowing the INC
> > controller to be initialised using DT is in progress, however,
> > until that is complete only GIC may be initialised using DT.
> > * Add extra entries to clock-sh73a0.c:lookups[] and
> > remove auxdata. Ultimtely the clocks will be described
> > in DT, but the code isn't there yet.
>
> Could you please add this as a TO-DO item either in the commit message or in
> arch/arm/mach-shmobile/clock-sh73a0.c ?
Sure, will do.
^ permalink raw reply
* Re: [PATCH 01/17] ARM: shmobile: fix memory size for kota2_defconfig
From: Simon Horman @ 2012-12-01 0:26 UTC (permalink / raw)
To: Olof Johansson
Cc: Arnd Bergmann, linux-arm-kernel, arm, linux-kernel, Paul Mundt,
Magnus Damm, linux-sh
In-Reply-To: <CAOesGMg6afPjBc82FEOwzwn-nBAFPY7K_udJRJO1bBrtCk3Yvg@mail.gmail.com>
On Fri, Nov 30, 2012 at 02:10:47PM -0800, Olof Johansson wrote:
> Hi,
>
> On Thu, Oct 4, 2012 at 1:58 AM, Simon Horman <horms@verge.net.au> wrote:
> > On Thu, Oct 04, 2012 at 08:34:54AM +0000, Arnd Bergmann wrote:
> >> On Wednesday 03 October 2012, Simon Horman wrote:
> >> > I looked through my fines and found a config that I believe
> >> > worked with a derivative of 2.6.35.7.
> >> >
> >> > It has CONFIG_MEMORY_SIZE=0x1e800000.
> >> >
> >> > So what I suspect has happened is that an extra zero has crept into
> >> > arch/arm/configs/kota2_defconfig and the intended value is:
> >> >
> >> > CONFIG_MEMORY_SIZE=0x1e000000
> >> >
> >> > Unfortunately I do not have access to a board to test this,
> >> > nor am I aware of anyone who does.
> >>
> >> Ok, I'll drop this patch for now then, so we keep the warning around
> >> to remind us of the problem.
> >
> > Thanks. I have subsequently located a Kota2 board,
> > however it may be a little while before I get my hands on it.
>
> Gentle ping. I just came across this warning again so I figured I'd check.
Sorry, I still don't have a kota2 board.
However, I expect to obtain one within the next week.
^ permalink raw reply
* Re: [PATCH 01/17] ARM: shmobile: fix memory size for kota2_defconfig
From: Olof Johansson @ 2012-11-30 22:10 UTC (permalink / raw)
To: Simon Horman
Cc: Arnd Bergmann, linux-arm-kernel, arm, linux-kernel, Paul Mundt,
Magnus Damm, linux-sh
In-Reply-To: <20121004085857.GA7240@verge.net.au>
Hi,
On Thu, Oct 4, 2012 at 1:58 AM, Simon Horman <horms@verge.net.au> wrote:
> On Thu, Oct 04, 2012 at 08:34:54AM +0000, Arnd Bergmann wrote:
>> On Wednesday 03 October 2012, Simon Horman wrote:
>> > I looked through my fines and found a config that I believe
>> > worked with a derivative of 2.6.35.7.
>> >
>> > It has CONFIG_MEMORY_SIZE=0x1e800000.
>> >
>> > So what I suspect has happened is that an extra zero has crept into
>> > arch/arm/configs/kota2_defconfig and the intended value is:
>> >
>> > CONFIG_MEMORY_SIZE=0x1e000000
>> >
>> > Unfortunately I do not have access to a board to test this,
>> > nor am I aware of anyone who does.
>>
>> Ok, I'll drop this patch for now then, so we keep the warning around
>> to remind us of the problem.
>
> Thanks. I have subsequently located a Kota2 board,
> however it may be a little while before I get my hands on it.
Gentle ping. I just came across this warning again so I figured I'd check.
-Olof
^ permalink raw reply
* Re: [GIT PULL v2] Renesas ARM-based SoC maintainers for v3.8 #1
From: Olof Johansson @ 2012-11-30 16:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354147220-10552-1-git-send-email-horms@verge.net.au>
On Thu, Nov 29, 2012 at 09:00:19AM +0900, Simon Horman wrote:
> Hi Olof, Hi Arnd,
>
> Please consider the following maintainers change for 3.8.
>
> ----------------------------------------------------------------
> 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://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git maintainers
THanks, pulled into next/fixes-non-critical, since we've likely sent our last
fixes batch to Linus.
-Olof
^ permalink raw reply
* Re: [PATCH 3/5] ARM: mach-shmobile: sh73a0: Initialise MMCIF using DT
From: Laurent Pinchart @ 2012-11-30 12:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-4-git-send-email-horms@verge.net.au>
Hi Simon,
Thank you for the patch.
On Friday 30 November 2012 17:44:43 Simon Horman wrote:
> From: Simon Horman <horms+renesas@verge.net.au>
>
> This device also requires a voltage regulator which
> should be defined in a board-specific maner. An example
> dts snipped follows.
>
> / {
> fixedregulator1v8: fixedregulator@0 {
> compatible = "regulator-fixed";
> regulator-name = "fixed-1.8V";
> regulator-min-microvolt = <1800000>;
> regulator-max-microvolt = <1800000>;
> };
> };
>
> &mmcif {
> vmmc-supply = <&fixedregulator1v8>;
> vqmmc-supply = <&fixedregulator1v8>;
> };
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
>
> ---
>
> v2
> * Removed SDHI intitialisation as the driver needs updating first
> * Moved MMC DT from sh73a0.dtsi to sh73a0-reference.dtsi
> as it is not appropriate for use by sh73a0-kzm9g.dts yet.
> This is because sh73a0-kzm9g.dts and board-kzm9g.c use
> both the GIC and INTC interrupt controllers to provide
> access to a rich set of devices. This is achieved by initilising
> the interrupt controllers using C code. Work on allowing the INC
> controller to be initialised using DT is in progress, however,
> until that is complete only GIC may be initialised using DT.
> * Add extra entries to clock-sh73a0.c:lookups[] and
> remove auxdata. Ultimtely the clocks will be described
> in DT, but the code isn't there yet.
Could you please add this as a TO-DO item either in the commit message or in
arch/arm/mach-shmobile/clock-sh73a0.c ?
> ---
> arch/arm/boot/dts/sh73a0-reference.dtsi | 24 ++++++++++++++++++++++++
> arch/arm/mach-shmobile/clock-sh73a0.c | 1 +
> 2 files changed, 25 insertions(+)
> create mode 100644 arch/arm/boot/dts/sh73a0-reference.dtsi
>
> diff --git a/arch/arm/boot/dts/sh73a0-reference.dtsi
> b/arch/arm/boot/dts/sh73a0-reference.dtsi new file mode 100644
> index 0000000..d4bb012
> --- /dev/null
> +++ b/arch/arm/boot/dts/sh73a0-reference.dtsi
> @@ -0,0 +1,24 @@
> +/*
> + * Device Tree Source for the SH73A0 SoC
> + *
> + * Copyright (C) 2012 Renesas Solutions Corp.
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + */
> +
> +/include/ "sh73a0.dtsi"
> +
> +/ {
> + compatible = "renesas,sh73a0";
> +
> + mmcif: mmcif@0x10010000 {
> + compatible = "renesas,sh-mmcif";
> + reg = <0xe6bd0000 0x100>;
> + interrupt-parent = <&gic>;
> + interrupts = <0 140 0x4
> + 0 141 0x4>;
> + reg-io-width = <4>;
> + };
> +};
> diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c
> b/arch/arm/mach-shmobile/clock-sh73a0.c index 8bc7a2b..0908123 100644
> --- a/arch/arm/mach-shmobile/clock-sh73a0.c
> +++ b/arch/arm/mach-shmobile/clock-sh73a0.c
> @@ -576,6 +576,7 @@ static struct clk_lookup lookups[] = {
> CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
> CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
> CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
> + CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
> CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
> CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
> CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH] mmc: sh_mobile_sdhi: fix clock frequency printing
From: Simon Horman @ 2012-11-30 9:02 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-mmc, linux-sh, Chris Ball
In-Reply-To: <Pine.LNX.4.64.1211281023310.1710@axis700.grange>
On Wed, Nov 28, 2012 at 10:24:13AM +0100, Guennadi Liakhovetski wrote:
> During its probing the SDHI driver prints out the clock frequency, but
> does it wrongly, always reporting 0Hz. Use the MMC host frequency value
> to fix this issue.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> drivers/mmc/host/sh_mobile_sdhi.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
> index 22ac8e7..d6ff853 100644
> --- a/drivers/mmc/host/sh_mobile_sdhi.c
> +++ b/drivers/mmc/host/sh_mobile_sdhi.c
> @@ -248,7 +248,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
> dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
> mmc_hostname(host->mmc), (unsigned long)
> (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
> - mmc_data->hclk / 1000000);
> + host->mmc->f_max / 1000000);
>
> return ret;
>
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] mmc: sh_mmcif: remove unneeded clock connection ID
From: Simon Horman @ 2012-11-30 9:02 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-mmc, linux-sh, Chris Ball
In-Reply-To: <Pine.LNX.4.64.1211281006340.1710@axis700.grange>
On Wed, Nov 28, 2012 at 10:24:27AM +0100, Guennadi Liakhovetski wrote:
> MMCIF only uses one clock, all ARM and SuperH platforms register MMCIF
> clock lookup entries with no connection ID, hence it can be dropped in
> the driver too.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> drivers/mmc/host/sh_mmcif.c | 6 ++----
> 1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
> index d25bc97..358295e 100644
> --- a/drivers/mmc/host/sh_mmcif.c
> +++ b/drivers/mmc/host/sh_mmcif.c
> @@ -1310,7 +1310,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
> struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
> struct resource *res;
> void __iomem *reg;
> - char clk_name[8];
>
> irq[0] = platform_get_irq(pdev, 0);
> irq[1] = platform_get_irq(pdev, 1);
> @@ -1360,11 +1359,10 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
> pm_runtime_enable(&pdev->dev);
> host->power = false;
>
> - snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
> - host->hclk = clk_get(&pdev->dev, clk_name);
> + host->hclk = clk_get(&pdev->dev, NULL);
> if (IS_ERR(host->hclk)) {
> ret = PTR_ERR(host->hclk);
> - dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
> + dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
> goto eclkget;
> }
> ret = sh_mmcif_clk_update(host);
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] mmc: sh_mobile_sdhi: remove unneeded clock connection ID
From: Simon Horman @ 2012-11-30 8:59 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: linux-mmc, linux-sh, Chris Ball
In-Reply-To: <Pine.LNX.4.64.1211281016550.1710@axis700.grange>
On Wed, Nov 28, 2012 at 10:24:21AM +0100, Guennadi Liakhovetski wrote:
> SDHI only uses one clock, all ARM and SuperH platform register SDHI clock
> lookup entries with no connection ID, hence it can be dropped in the
> driver too.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> drivers/mmc/host/sh_mobile_sdhi.c | 6 ++----
> 1 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
> index 0bdc146..22ac8e7 100644
> --- a/drivers/mmc/host/sh_mobile_sdhi.c
> +++ b/drivers/mmc/host/sh_mobile_sdhi.c
> @@ -123,7 +123,6 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
> struct tmio_mmc_data *mmc_data;
> struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
> struct tmio_mmc_host *host;
> - char clk_name[8];
> int irq, ret, i = 0;
> bool multiplexed_isr = true;
>
> @@ -144,11 +143,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
> }
> }
>
> - snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
> - priv->clk = clk_get(&pdev->dev, clk_name);
> + priv->clk = clk_get(&pdev->dev, NULL);
> if (IS_ERR(priv->clk)) {
> - dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
> ret = PTR_ERR(priv->clk);
> + dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
> goto eclkget;
> }
>
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 1/1] ARM: shmobile: Remove duplicate inclusion of dma-mapping.h in setup-r8a7740.c
From: Simon Horman @ 2012-11-30 8:56 UTC (permalink / raw)
To: linux-sh
In-Reply-To: <1353393549-1532-1-git-send-email-sachin.kamat@linaro.org>
On Tue, Nov 27, 2012 at 09:05:25AM +0530, Sachin Kamat wrote:
> ping
Sorry for missing this. I have applied it now and
I expect it will be included in 3.9.
^ permalink raw reply
* [PATCH 5/5] ARM: mach-shmobile: kzm9g: Reference DT implementation
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-1-git-send-email-horms@verge.net.au>
From: Simon Horman <horms+renesas@verge.net.au>
Provide alternate board code for the kzm9g to demonstrate
how DT may be used given the current state of driver
device tree support. This is intended to act as a reference
for mach-shmobile developers.
Some notes:
* Brings up the GIC interrupt handler using device tree
* Brings up the following device using device tree:
- MMCIF (MMC)
* Does not bring up the INTC interrupt controller at all,
thus external devices may not be used
* Uses existing C code and not device tree to initialise the following,
which are needed for a working board:
- SCIF (Serial)
- CMT (Clock)
- PFC (GPIO)
To use this alternate board code instead of the normal board code,
CONFIG_MACH_KZM9G_REFERENCE should be selected in the kernel config.
And the sh73a0-kzm9g-reference.dtb flattened device tree blob should be used.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* Do not initialise touchscreen, it requires the INTC interrupt controller
but for now this configuration only has the GIC interrupt controller.
* Define mmcif and sdhi in SoC dtsi and reference in board dts.
* Do not initialise SDHI, the driver needs to be updated
---
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts | 37 ++++++++++
arch/arm/mach-shmobile/Kconfig | 10 +++
arch/arm/mach-shmobile/Makefile | 8 ++-
arch/arm/mach-shmobile/board-kzm9g-reference.c | 92 ++++++++++++++++++++++++
5 files changed, 148 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
create mode 100644 arch/arm/mach-shmobile/board-kzm9g-reference.c
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f37cf9f..c606375 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -77,7 +77,8 @@ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
r8a7740-armadillo800eva.dtb \
- sh73a0-kzm9g.dtb
+ sh73a0-kzm9g.dtb \
+ sh73a0-kzm9g-reference.dtb
dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
spear1340-evb.dtb
dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
new file mode 100644
index 0000000..588016e
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
@@ -0,0 +1,37 @@
+/*
+ * Device Tree Source for the KZM-A9-GT board
+ *
+ * Copyright (C) 2012 Horms Solutions Ltd.
+ *
+ * Based on sh73a0-kzm9g.dts
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+/include/ "sh73a0-reference.dtsi"
+
+/ {
+ model = "KZM-A9-GT";
+ compatible = "renesas,kzm9g-reference", "renesas,sh73a0";
+
+ memory {
+ device_type = "memory";
+ reg = <0x41000000 0x1e800000>;
+ };
+
+ fixedregulator1v8: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+};
+
+&mmcif {
+ vmmc-supply = <&fixedregulator1v8>;
+ vqmmc-supply = <&fixedregulator1v8>;
+};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 8ae100c..ca95c2b 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -136,6 +136,16 @@ config MACH_KZM9G
select SND_SOC_AK4642 if SND_SIMPLE_CARD
select USE_OF
+config MACH_KZM9G_REFERENCE
+ bool "KZM-A9-GT board - Reference Device Tree Implementation"
+ depends on MACH_KZM9G
+ ---help---
+ Use reference implementation of KZM-A9-GT board support
+ which makes as greater use of device tree at the expense
+ of not supporting a number of devices.
+
+ This is intended to aid developers
+
comment "SH-Mobile System Configuration"
config CPU_HAS_INTEVT
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e3556c6..7ffa428 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -51,7 +51,13 @@ obj-$(CONFIG_MACH_BONITO) += board-bonito.o
obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o
-obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
+ifeq ($(CONFIG_MACH_KZM9G),y)
+ifeq ($(CONFIG_MACH_KZM9G_REFERENCE),y)
+obj-y += board-kzm9g-reference.o
+else
+obj-y += board-kzm9g.o
+endif
+endif
# Framework support
obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c
new file mode 100644
index 0000000..29c334d
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c
@@ -0,0 +1,92 @@
+/*
+ * KZM-A9-GT board support - Reference Device Tree Implementation
+ *
+ * Copyright (C) 2012 Horms Solutions Ltd.
+ *
+ * Based on board-kzm9g.c
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/of_platform.h>
+#include <mach/sh73a0.h>
+#include <mach/common.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static void __init kzm_init(void)
+{
+ /* enable SCIFA4 */
+ gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
+ gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
+ gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
+
+ /* enable MMCIF */
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+ gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
+
+ /* I2C 3 */
+ gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
+ gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
+#endif
+
+ sh73a0_add_standard_devices_dt();
+}
+
+static void kzm9g_restart(char mode, const char *cmd)
+{
+#define RESCNT2 IOMEM(0xe6188020)
+ /* Do soft power on reset */
+ writel((1 << 31), RESCNT2);
+}
+
+static const char *kzm9g_boards_compat_dt[] __initdata = {
+ "renesas,kzm9g-reference",
+ NULL,
+};
+
+DT_MACHINE_START(KZM9G_DT, "kzm9g-reference")
+ .smp = smp_ops(sh73a0_smp_ops),
+ .map_io = sh73a0_map_io,
+ .init_early = sh73a0_add_early_devices_dt,
+ .nr_irqs = NR_IRQS_LEGACY,
+ .init_irq = sh73a0_init_irq_dt,
+ .handle_irq = gic_handle_irq,
+ .init_machine = kzm_init,
+ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ .restart = kzm9g_restart,
+ .dt_compat = kzm9g_boards_compat_dt,
+MACHINE_END
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/5] ARM: shmobile: kzm9g: use voltage regulators by default
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-1-git-send-email-horms@verge.net.au>
This is needed to initialise the MMCIF device in the
absence of platform data.
Signed-off-by: Simon Horman <horms@verge.net.au>
---
arch/arm/configs/kzm9g_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index c88b578..6d7fd53 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -83,6 +83,7 @@ CONFIG_I2C_CHARDEV=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_GPIO_PCF857X=y
# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
CONFIG_FB=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FRAMEBUFFER_CONSOLE=y
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/5] ARM: mach-shmobile: sh73a0: Initialise MMCIF using DT
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-1-git-send-email-horms@verge.net.au>
From: Simon Horman <horms+renesas@verge.net.au>
This device also requires a voltage regulator which
should be defined in a board-specific maner. An example
dts snipped follows.
/ {
fixedregulator1v8: fixedregulator@0 {
compatible = "regulator-fixed";
regulator-name = "fixed-1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
&mmcif {
vmmc-supply = <&fixedregulator1v8>;
vqmmc-supply = <&fixedregulator1v8>;
};
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* Removed SDHI intitialisation as the driver needs updating first
* Moved MMC DT from sh73a0.dtsi to sh73a0-reference.dtsi
as it is not appropriate for use by sh73a0-kzm9g.dts yet.
This is because sh73a0-kzm9g.dts and board-kzm9g.c use
both the GIC and INTC interrupt controllers to provide
access to a rich set of devices. This is achieved by initilising
the interrupt controllers using C code. Work on allowing the INC
controller to be initialised using DT is in progress, however,
until that is complete only GIC may be initialised using DT.
* Add extra entries to clock-sh73a0.c:lookups[] and
remove auxdata. Ultimtely the clocks will be described
in DT, but the code isn't there yet.
---
arch/arm/boot/dts/sh73a0-reference.dtsi | 24 ++++++++++++++++++++++++
arch/arm/mach-shmobile/clock-sh73a0.c | 1 +
2 files changed, 25 insertions(+)
create mode 100644 arch/arm/boot/dts/sh73a0-reference.dtsi
diff --git a/arch/arm/boot/dts/sh73a0-reference.dtsi b/arch/arm/boot/dts/sh73a0-reference.dtsi
new file mode 100644
index 0000000..d4bb012
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0-reference.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Device Tree Source for the SH73A0 SoC
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "sh73a0.dtsi"
+
+/ {
+ compatible = "renesas,sh73a0";
+
+ mmcif: mmcif@0x10010000 {
+ compatible = "renesas,sh-mmcif";
+ reg = <0xe6bd0000 0x100>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 140 0x4
+ 0 141 0x4>;
+ reg-io-width = <4>;
+ };
+};
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 8bc7a2b..0908123 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -576,6 +576,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/5] ARM: mach-shmobile: sh73a0: Minimal setup using DT
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-1-git-send-email-horms@verge.net.au>
From: Simon Horman <horms+renesas@verge.net.au>
Allow a minimal setup of the sh73a0 SoC using a flattened device tree.
* Configure the i2c controllers using a flattened device tree.
SCI serial controller and CMT clock source, whose drivers do not yet
support configuration using a flattened device tree, are still configured
using C code in order to allow booting of a board with this SoC.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* Add extra entries to clock-sh73a0.c:lookups[] and
remove auxdata. Ultimtely the clocks will be described
in DT, but the code isn't there yet.
* Use shmobile_setup_delay() and perform late initialisation of clocks
---
arch/arm/boot/dts/sh73a0.dtsi | 60 ++++++++++++++++++++++++++
arch/arm/mach-shmobile/clock-sh73a0.c | 5 +++
arch/arm/mach-shmobile/include/mach/common.h | 2 +
arch/arm/mach-shmobile/setup-sh73a0.c | 39 ++++++++++++++++-
4 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 77c8e43..fc7f0fd 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -38,4 +38,64 @@
reg = <0xf0001000 0x1000>,
<0xf0000100 0x100>;
};
+
+ i2c0: i2c@0xe6820000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,rmobile-iic";
+ reg = <0xe6820000 0x425>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 167 0x4
+ 0 168 0x4
+ 0 169 0x4
+ 0 170 0x4>;
+ };
+
+ i2c1: i2c@0xe6822000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,rmobile-iic";
+ reg = <0xe6822000 0x425>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 51 0x4
+ 0 52 0x4
+ 0 53 0x4
+ 0 54 0x4>;
+ };
+
+ i2c2: i2c@0xe6824000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,rmobile-iic";
+ reg = <0xe6824000 0x425>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 171 0x4
+ 0 172 0x4
+ 0 173 0x4
+ 0 174 0x4>;
+ };
+
+ i2c3: i2c@0xe6826000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,rmobile-iic";
+ reg = <0xe6826000 0x425>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 183 0x4
+ 0 184 0x4
+ 0 185 0x4
+ 0 186 0x4>;
+ };
+
+ i2c4: i2c@0xe6828000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "renesas,rmobile-iic";
+ reg = <0xe6828000 0x425>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 187 0x4
+ 0 188 0x4
+ 0 189 0x4
+ 0 190 0x4>;
+ };
};
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 516ff7f..8bc7a2b 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -545,6 +545,7 @@ static struct clk_lookup lookups[] = {
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+ CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
@@ -553,6 +554,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
+ CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
@@ -569,6 +571,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
@@ -579,7 +582,9 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
};
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index b50447e..06b905e 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -52,7 +52,9 @@ extern void sh73a0_init_irq(void);
extern void sh73a0_init_irq_dt(void);
extern void sh73a0_map_io(void);
extern void sh73a0_add_early_devices(void);
+extern void sh73a0_add_early_devices_dt(void);
extern void sh73a0_add_standard_devices(void);
+extern void sh73a0_add_standard_devices_dt(void);
extern void sh73a0_clock_init(void);
extern void sh73a0_pinmux_init(void);
extern struct clk sh73a0_extal1_clk;
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index eab1bae..f8bdac4 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/io.h>
@@ -35,6 +36,7 @@
#include <mach/irqs.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
+#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
@@ -779,7 +781,7 @@ static struct platform_device pmu_device = {
.resource = pmu_resources,
};
-static struct platform_device *sh73a0_early_devices[] __initdata = {
+static struct platform_device *sh73a0_early_devices_dt[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
@@ -790,6 +792,9 @@ static struct platform_device *sh73a0_early_devices[] __initdata = {
&scif7_device,
&scif8_device,
&cmt10_device,
+};
+
+static struct platform_device *sh73a0_early_devices[] __initdata = {
&tmu00_device,
&tmu01_device,
};
@@ -812,6 +817,8 @@ void __init sh73a0_add_standard_devices(void)
/* Clear software reset bit on SY-DMAC module */
__raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
+ platform_add_devices(sh73a0_early_devices_dt,
+ ARRAY_SIZE(sh73a0_early_devices_dt));
platform_add_devices(sh73a0_early_devices,
ARRAY_SIZE(sh73a0_early_devices));
platform_add_devices(sh73a0_late_devices,
@@ -830,6 +837,8 @@ static void __init sh73a0_earlytimer_init(void)
void __init sh73a0_add_early_devices(void)
{
+ early_platform_add_devices(sh73a0_early_devices_dt,
+ ARRAY_SIZE(sh73a0_early_devices_dt));
early_platform_add_devices(sh73a0_early_devices,
ARRAY_SIZE(sh73a0_early_devices));
@@ -839,3 +848,31 @@ void __init sh73a0_add_early_devices(void)
/* override timer setup with soc-specific code */
shmobile_timer.init = sh73a0_earlytimer_init;
}
+
+#ifdef CONFIG_USE_OF
+static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
+ {},
+};
+
+void __init sh73a0_add_early_devices_dt(void)
+{
+ shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
+
+ early_platform_add_devices(sh73a0_early_devices_dt,
+ ARRAY_SIZE(sh73a0_early_devices_dt));
+
+ /* setup early console here as well */
+ shmobile_setup_console();
+}
+
+void __init sh73a0_add_standard_devices_dt(void)
+{
+ /* clocks are setup late during boot in the case of DT */
+ sh73a0_clock_init();
+
+ platform_add_devices(sh73a0_early_devices_dt,
+ ARRAY_SIZE(sh73a0_early_devices_dt));
+ of_platform_populate(NULL, of_default_bus_match_table,
+ sh73a0_auxdata_lookup, NULL);
+}
+#endif /* CONFIG_USE_OF */
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/5] ARM: mach-shmobile: sh73a0: Allow initialisation of GIC by DT
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354265085-2444-1-git-send-email-horms@verge.net.au>
From: Simon Horman <horms+renesas@verge.net.au>
This allows the GIC interrupt controller of the sh73a0 SoC to be
initialised using a flattened device tree blob.
It does not allow the INTC interrupt controller which is also present on
the sh73a0 SoC to be enabled via device tree. Nor does it handle sharing
of interrupts between the GIC and INTC interrupt controllers.
This limits the usefulness of this code to applications which only wish to
access devices which use interrupts that can be handled by the GIC
interrupt controller. Other applications should, for now, continue using
non-device tree initialisation of the sh72a0 interrupt controllers.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/boot/dts/sh73a0.dtsi | 9 +++++++++
arch/arm/mach-shmobile/include/mach/common.h | 1 +
arch/arm/mach-shmobile/intc-sh73a0.c | 14 ++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 6b374ff..77c8e43 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -29,4 +29,13 @@
gpio-controller;
#gpio-cells = <2>;
};
+
+ gic: interrupt-controller@f0001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ interrupt-controller;
+ reg = <0xf0001000 0x1000>,
+ <0xf0000100 0x100>;
+ };
};
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index d47e215..b50447e 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -49,6 +49,7 @@ extern struct clk sh7372_extal1_clk;
extern struct clk sh7372_extal2_clk;
extern void sh73a0_init_irq(void);
+extern void sh73a0_init_irq_dt(void);
extern void sh73a0_map_io(void);
extern void sh73a0_add_early_devices(void);
extern void sh73a0_add_standard_devices(void);
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index f0c5e51..e492350 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/irq.h>
+#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/sh_intc.h>
#include <mach/intc.h>
@@ -464,3 +465,16 @@ void __init sh73a0_init_irq(void)
sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
}
+
+#ifdef CONFIG_OF
+static const struct of_device_id irq_of_match[] __initconst = {
+ { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+ { },
+};
+
+void __init sh73a0_init_irq_dt(void)
+{
+ of_irq_init(irq_of_match);
+ gic_arch_extn.irq_set_wake = sh73a0_set_wake;
+}
+#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/7 v2] ARM: mach-shmobile: kzm9g: Reference DT implementation
From: Simon Horman @ 2012-11-30 8:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
*** This series is wip and does not currently function
I am posting to provide a status update and ask for help ***
this is a second pass at at providing a refernce DT implementation
for the kzm9g baord which is intended to act as a guide for mach-shmobile
developers.
Major difference to v1:
* Drop touchscreen initialisation, it requires INTC
* Drop SDHI initialisation, the driver seems to need some work
* Add extra entries to clock-sh73a0.c:lookups[] and
remove auxdata. Ultimtely the clocks will be described
in DT, but the code isn't there yet.
* Drop MMCIF patch, it is not needed if regulators are enabled
* Drop PCF hacks, instead, the series is based on Laruent Pinchart's * series:
[PATCH v2 00/77] SH pin control and GPIO rework with OF support
* Use shmobile_setup_delay()
Unfortunately the last point seems to introduce problems.
It seems to prevent SMP from booting to the point of printing
anything on the early console. And with CONFIG_SMP disabled
the boot halts when the MMCIF driver initialisation calls mmc_delay().
I've poked around a bit but I haven't had any luck working out
why this is the case. I would appreciate any pointers on what to
investigate.
Git and diffstat information provided to aid review.
----------------------------------------------------------------
The following changes since commit 940956fe1d8de5cbcc963214fe592f76d8354bef:
ARM: shmobile: kzm9g: Add LED1-LED4 to the device tree (2012-11-27 00:59:10 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git devel/of-kzm9g
for you to fetch changes up to 7018db4354c445d401782dc38df5e2d8afb43bc2:
ARM: mach-shmobile: kzm9g: Reference DT implementation (2012-11-30 16:55:46 +0900)
----------------------------------------------------------------
Simon Horman (5):
ARM: mach-shmobile: sh73a0: Allow initialisation of GIC by DT
ARM: mach-shmobile: sh73a0: Minimal setup using DT
ARM: mach-shmobile: sh73a0: Initialise MMCIF using DT
ARM: shmobile: kzm9g: use voltage regulators by default
ARM: mach-shmobile: kzm9g: Reference DT implementation
arch/arm/boot/dts/Makefile | 3 +-
arch/arm/boot/dts/sh73a0-kzm9g-reference.dts | 37 ++++++++++
arch/arm/boot/dts/sh73a0-reference.dtsi | 24 +++++++
arch/arm/boot/dts/sh73a0.dtsi | 69 ++++++++++++++++++
arch/arm/configs/kzm9g_defconfig | 1 +
arch/arm/mach-shmobile/Kconfig | 10 +++
arch/arm/mach-shmobile/Makefile | 8 ++-
arch/arm/mach-shmobile/board-kzm9g-reference.c | 92 ++++++++++++++++++++++++
arch/arm/mach-shmobile/clock-sh73a0.c | 6 ++
arch/arm/mach-shmobile/include/mach/common.h | 3 +
arch/arm/mach-shmobile/intc-sh73a0.c | 14 ++++
arch/arm/mach-shmobile/setup-sh73a0.c | 39 +++++++++-
12 files changed, 303 insertions(+), 3 deletions(-)
create mode 100644 arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
create mode 100644 arch/arm/boot/dts/sh73a0-reference.dtsi
create mode 100644 arch/arm/mach-shmobile/board-kzm9g-reference.c
^ permalink raw reply
* Re: [Patch v4 00/12] memory-hotplug: hot-remove physical memory
From: Tang Chen @ 2012-11-30 6:37 UTC (permalink / raw)
To: Andrew Morton
Cc: Wen Congyang, x86, linux-mm, linux-kernel, linuxppc-dev,
linux-acpi, linux-s390, linux-sh, linux-ia64, cmetcalf,
sparclinux, David Rientjes, Jiang Liu, Len Brown, benh, paulus,
Christoph Lameter, Minchan Kim, KOSAKI Motohiro,
Yasuaki Ishimatsu, Jianguo Wu
In-Reply-To: <20121127112741.b616c2f6.akpm@linux-foundation.org>
Hi Andrew,
On 11/28/2012 03:27 AM, Andrew Morton wrote:
>>
>> - acpi framework
>> https://lkml.org/lkml/2012/10/26/175
>
> What's happening with the acpi framework? has it received any feedback
> from the ACPI developers?
About ACPI framework, we are trying to do the following.
The memory device can be removed by 2 ways:
1. send eject request by SCI
2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject
In the 1st case, acpi_memory_disable_device() will be called.
In the 2nd case, acpi_memory_device_remove() will be called.
acpi_memory_device_remove() will also be called when we unbind the
memory device from the driver acpi_memhotplug or a driver
initialization fails.
acpi_memory_disable_device() has already implemented a code which
offlines memory and releases acpi_memory_info struct . But
acpi_memory_device_remove() has not implemented it yet.
So the patch prepares the framework for hot removing memory and
adds the framework into acpi_memory_device_remove().
All the ACPI related patches have been put into the linux-next branch
of the linux-pm.git tree as v3.8 material.Please refer to the following
url.
https://lkml.org/lkml/2012/11/2/160
So for now, with this patch set, we can do memory hot-remove on x86_64
linux.
I do hope you would merge them before 3.8-rc1, so that we can use this
functionality in 3.8.
As we are still testing all memory hotplug related functionalities, I
hope we can do the bug fix during 3.8 rc.
Thanks. :)
^ permalink raw reply
* Re: [Patch v4 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Yasuaki Ishimatsu @ 2012-11-30 2:55 UTC (permalink / raw)
To: Jianguo Wu
Cc: Wen Congyang, x86, linux-mm, linux-kernel, linuxppc-dev,
linux-acpi, linux-s390, linux-sh, linux-ia64, cmetcalf,
sparclinux, David Rientjes, Jiang Liu, Len Brown, benh, paulus,
Christoph Lameter, Minchan Kim, Andrew Morton, KOSAKI Motohiro
In-Reply-To: <50B81E50.9050101@huawei.com>
Hi Jianguo,
2012/11/30 11:47, Jianguo Wu wrote:
> Hi Congyang,
>
> Thanks for your review and comments.
>
> On 2012/11/30 9:45, Wen Congyang wrote:
>
>> At 11/28/2012 05:40 PM, Jianguo Wu Wrote:
>>> Hi Congyang,
>>>
>>> I think vmemmap's pgtable pages should be freed after all entries are cleared, I have a patch to do this.
>>> The code logic is the same as [Patch v4 09/12] memory-hotplug: remove page table of x86_64 architecture.
>>>
>>> How do you think about this?
>>>
>>> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
>>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>>> ---
>>> include/linux/mm.h | 1 +
>>> mm/sparse-vmemmap.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>> mm/sparse.c | 5 +-
>>> 3 files changed, 218 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>>> index 5657670..1f26af5 100644
>>> --- a/include/linux/mm.h
>>> +++ b/include/linux/mm.h
>>> @@ -1642,6 +1642,7 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
>>> void vmemmap_populate_print_last(void);
>>> void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
>>> unsigned long size);
>>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages);
>>>
>>> enum mf_flags {
>>> MF_COUNT_INCREASED = 1 << 0,
>>> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
>>> index 1b7e22a..242cb28 100644
>>> --- a/mm/sparse-vmemmap.c
>>> +++ b/mm/sparse-vmemmap.c
>>> @@ -29,6 +29,10 @@
>>> #include <asm/pgalloc.h>
>>> #include <asm/pgtable.h>
>>>
>>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>>> +#include <asm/tlbflush.h>
>>> +#endif
>>> +
>>> /*
>>> * Allocate a block of memory to be used to back the virtual memory map
>>> * or to back the page tables that are used to create the mapping.
>>> @@ -224,3 +228,213 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
>>> vmemmap_buf_end = NULL;
>>> }
>>> }
>>> +
>>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>>> +static void vmemmap_free_pages(struct page *page, int order)
>>> +{
>>> + struct zone *zone;
>>> + unsigned long magic;
>>> +
>>> + magic = (unsigned long) page->lru.next;
>>> + if (magic = SECTION_INFO || magic = MIX_SECTION_INFO) {
>>> + put_page_bootmem(page);
>>> +
>>> + zone = page_zone(page);
>>> + zone_span_writelock(zone);
>>> + zone->present_pages++;
>>> + zone_span_writeunlock(zone);
>>> + totalram_pages++;
>>> + } else {
>>> + if (is_vmalloc_addr(page_address(page)))
>>> + vfree(page_address(page));
>>
>> Hmm, vmemmap doesn't use vmalloc() to allocate memory.
>>
>
> yes, this can be removed.
>
>>> + else
>>> + free_pages((unsigned long)page_address(page), order);
>>> + }
>>> +}
>>> +
>>> +static void free_pte_table(pmd_t *pmd)
>>> +{
>>> + pte_t *pte, *pte_start;
>>> + int i;
>>> +
>>> + pte_start = (pte_t *)pmd_page_vaddr(*pmd);
>>> + for (i = 0; i < PTRS_PER_PTE; i++) {
>>> + pte = pte_start + i;
>>> + if (pte_val(*pte))
>>> + return;
>>> + }
>>> +
>>> + /* free a pte talbe */
>>> + vmemmap_free_pages(pmd_page(*pmd), 0);
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pmd_clear(pmd);
>>> + spin_unlock(&init_mm.page_table_lock);
>>> +}
>>> +
>>> +static void free_pmd_table(pud_t *pud)
>>> +{
>>> + pmd_t *pmd, *pmd_start;
>>> + int i;
>>> +
>>> + pmd_start = (pmd_t *)pud_page_vaddr(*pud);
>>> + for (i = 0; i < PTRS_PER_PMD; i++) {
>>> + pmd = pmd_start + i;
>>> + if (pmd_val(*pmd))
>>> + return;
>>> + }
>>> +
>>> + /* free a pmd talbe */
>>> + vmemmap_free_pages(pud_page(*pud), 0);
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pud_clear(pud);
>>> + spin_unlock(&init_mm.page_table_lock);
>>> +}
>>> +
>>> +static void free_pud_table(pgd_t *pgd)
>>> +{
>>> + pud_t *pud, *pud_start;
>>> + int i;
>>> +
>>> + pud_start = (pud_t *)pgd_page_vaddr(*pgd);
>>> + for (i = 0; i < PTRS_PER_PUD; i++) {
>>> + pud = pud_start + i;
>>> + if (pud_val(*pud))
>>> + return;
>>> + }
>>> +
>>> + /* free a pud table */
>>> + vmemmap_free_pages(pgd_page(*pgd), 0);
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pgd_clear(pgd);
>>> + spin_unlock(&init_mm.page_table_lock);
>>> +}
>>> +
>>> +static int split_large_page(pte_t *kpte, unsigned long address, pte_t *pbase)
>>> +{
>>> + struct page *page = pmd_page(*(pmd_t *)kpte);
>>> + int i = 0;
>>> + unsigned long magic;
>>> + unsigned long section_nr;
>>> +
>>> + __split_large_page(kpte, address, pbase);
>>> + __flush_tlb_all();
>>> +
>>> + magic = (unsigned long) page->lru.next;
>>> + if (magic = SECTION_INFO) {
>>> + section_nr = pfn_to_section_nr(page_to_pfn(page));
>>> + while (i < PTRS_PER_PMD) {
>>> + page++;
>>> + i++;
>>> + get_page_bootmem(section_nr, page, SECTION_INFO);
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void vmemmap_pte_remove(pmd_t *pmd, unsigned long addr, unsigned long end)
>>> +{
>>> + pte_t *pte;
>>> + unsigned long next;
>>> +
>>> + pte = pte_offset_kernel(pmd, addr);
>>> + for (; addr < end; pte++, addr += PAGE_SIZE) {
>>> + next = (addr + PAGE_SIZE) & PAGE_MASK;
>>> + if (next > end)
>>> + next = end;
>>> +
>>> + if (pte_none(*pte))
>>> + continue;
>>> + if (IS_ALIGNED(addr, PAGE_SIZE) &&
>>> + IS_ALIGNED(end, PAGE_SIZE)) {
>>> + vmemmap_free_pages(pte_page(*pte), 0);
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pte_clear(&init_mm, addr, pte);
>>> + spin_unlock(&init_mm.page_table_lock);
>>
>> If addr or end is not alianed with PAGE_SIZE, you may leak some
>> memory.
>>
>
> yes, I think we can handle this situation with the method you mentioned in the change log:
> 1. When removing memory, the page structs of the revmoved memory are filled
> with 0xFD.
> 2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be cleared.
> In this case, the page used as PT/PMD can be freed.
>
> By the way, why is 0xFD?
There is no reason. I just filled the page with unique number.
Thanks,
Yasuaki Ishimatsu
>
>>> + }
>>> + }
>>> +
>>> + free_pte_table(pmd);
>>> + __flush_tlb_all();
>>> +}
>>> +
>>> +static void vmemmap_pmd_remove(pud_t *pud, unsigned long addr, unsigned long end)
>>> +{
>>> + unsigned long next;
>>> + pmd_t *pmd;
>>> +
>>> + pmd = pmd_offset(pud, addr);
>>> + for (; addr < end; addr = next, pmd++) {
>>> + next = pmd_addr_end(addr, end);
>>> + if (pmd_none(*pmd))
>>> + continue;
>>> +
>>> + if (cpu_has_pse) {
>>> + unsigned long pte_base;
>>> +
>>> + if (IS_ALIGNED(addr, PMD_SIZE) &&
>>> + IS_ALIGNED(next, PMD_SIZE)) {
>>> + vmemmap_free_pages(pmd_page(*pmd),
>>> + get_order(PMD_SIZE));
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pmd_clear(pmd);
>>> + spin_unlock(&init_mm.page_table_lock);
>>> + continue;
>>> + }
>>> +
>>> + /*
>>> + * We use 2M page, but we need to remove part of them,
>>> + * so split 2M page to 4K page.
>>> + */
>>> + pte_base = get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
>>
>> get_zeored_page() may fail. You should handle this error.
>>
>
> That means system is out of memory, I will trigger a bug_on.
>
>>> + split_large_page((pte_t *)pmd, addr, (pte_t *)pte_base);
>>> + __flush_tlb_all();
>>> +
>>> + spin_lock(&init_mm.page_table_lock);
>>> + pmd_populate_kernel(&init_mm, pmd, (pte_t *)pte_base);
>>> + spin_unlock(&init_mm.page_table_lock);
>>> + }
>>> +
>>> + vmemmap_pte_remove(pmd, addr, next);
>>> + }
>>> +
>>> + free_pmd_table(pud);
>>> + __flush_tlb_all();
>>> +}
>>> +
>>> +static void vmemmap_pud_remove(pgd_t *pgd, unsigned long addr, unsigned long end)
>>> +{
>>> + unsigned long next;
>>> + pud_t *pud;
>>> +
>>> + pud = pud_offset(pgd, addr);
>>> + for (; addr < end; addr = next, pud++) {
>>> + next = pud_addr_end(addr, end);
>>> + if (pud_none(*pud))
>>> + continue;
>>> +
>>> + vmemmap_pmd_remove(pud, addr, next);
>>> + }
>>> +
>>> + free_pud_table(pgd);
>>> + __flush_tlb_all();
>>> +}
>>> +
>>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> + unsigned long addr = (unsigned long)memmap;
>>> + unsigned long end = (unsigned long)(memmap + nr_pages);
>>> + unsigned long next;
>>> +
>>> + for (; addr < end; addr = next) {
>>> + pgd_t *pgd = pgd_offset_k(addr);
>>> +
>>> + next = pgd_addr_end(addr, end);
>>> + if (!pgd_present(*pgd))
>>> + continue;
>>> +
>>> + vmemmap_pud_remove(pgd, addr, next);
>>> + sync_global_pgds(addr, next);
>>
>> The parameter for sync_global_pgds() is [start, end], not
>> [start, end)
>>
>
> yes, thanks.
>
>>> + }
>>> +}
>>> +#endif
>>> diff --git a/mm/sparse.c b/mm/sparse.c
>>> index fac95f2..3a16d68 100644
>>> --- a/mm/sparse.c
>>> +++ b/mm/sparse.c
>>> @@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
>>> /* This will make the necessary allocations eventually. */
>>> return sparse_mem_map_populate(pnum, nid);
>>> }
>>> -static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
>>> +static void __kfree_section_memmap(struct page *page, unsigned long nr_pages)
>> Why do you change this line?
>>
>
> 0k, it is no need to change.
>
>>> {
>>> - return; /* XXX: Not implemented yet */
>>> + vmemmap_free(page, nr_pages);
>>> }
>>> static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>>> {
>>> + vmemmap_free(page, nr_pages);
>>> }
>>> #else
>>> static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
>>
>>
>> .
>>
>
>
>
^ permalink raw reply
* Re: [Patch v4 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Jianguo Wu @ 2012-11-30 2:47 UTC (permalink / raw)
To: Wen Congyang
Cc: x86, linux-mm, linux-kernel, linuxppc-dev, linux-acpi, linux-s390,
linux-sh, linux-ia64, cmetcalf, sparclinux, David Rientjes,
Jiang Liu, Len Brown, benh, paulus, Christoph Lameter,
Minchan Kim, Andrew Morton, KOSAKI Motohiro, Yasuaki Ishimatsu
In-Reply-To: <50B80FB1.6040906@cn.fujitsu.com>
Hi Congyang,
Thanks for your review and comments.
On 2012/11/30 9:45, Wen Congyang wrote:
> At 11/28/2012 05:40 PM, Jianguo Wu Wrote:
>> Hi Congyang,
>>
>> I think vmemmap's pgtable pages should be freed after all entries are cleared, I have a patch to do this.
>> The code logic is the same as [Patch v4 09/12] memory-hotplug: remove page table of x86_64 architecture.
>>
>> How do you think about this?
>>
>> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> ---
>> include/linux/mm.h | 1 +
>> mm/sparse-vmemmap.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> mm/sparse.c | 5 +-
>> 3 files changed, 218 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 5657670..1f26af5 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1642,6 +1642,7 @@ int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
>> void vmemmap_populate_print_last(void);
>> void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
>> unsigned long size);
>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages);
>>
>> enum mf_flags {
>> MF_COUNT_INCREASED = 1 << 0,
>> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
>> index 1b7e22a..242cb28 100644
>> --- a/mm/sparse-vmemmap.c
>> +++ b/mm/sparse-vmemmap.c
>> @@ -29,6 +29,10 @@
>> #include <asm/pgalloc.h>
>> #include <asm/pgtable.h>
>>
>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>> +#include <asm/tlbflush.h>
>> +#endif
>> +
>> /*
>> * Allocate a block of memory to be used to back the virtual memory map
>> * or to back the page tables that are used to create the mapping.
>> @@ -224,3 +228,213 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
>> vmemmap_buf_end = NULL;
>> }
>> }
>> +
>> +#ifdef CONFIG_MEMORY_HOTREMOVE
>> +static void vmemmap_free_pages(struct page *page, int order)
>> +{
>> + struct zone *zone;
>> + unsigned long magic;
>> +
>> + magic = (unsigned long) page->lru.next;
>> + if (magic = SECTION_INFO || magic = MIX_SECTION_INFO) {
>> + put_page_bootmem(page);
>> +
>> + zone = page_zone(page);
>> + zone_span_writelock(zone);
>> + zone->present_pages++;
>> + zone_span_writeunlock(zone);
>> + totalram_pages++;
>> + } else {
>> + if (is_vmalloc_addr(page_address(page)))
>> + vfree(page_address(page));
>
> Hmm, vmemmap doesn't use vmalloc() to allocate memory.
>
yes, this can be removed.
>> + else
>> + free_pages((unsigned long)page_address(page), order);
>> + }
>> +}
>> +
>> +static void free_pte_table(pmd_t *pmd)
>> +{
>> + pte_t *pte, *pte_start;
>> + int i;
>> +
>> + pte_start = (pte_t *)pmd_page_vaddr(*pmd);
>> + for (i = 0; i < PTRS_PER_PTE; i++) {
>> + pte = pte_start + i;
>> + if (pte_val(*pte))
>> + return;
>> + }
>> +
>> + /* free a pte talbe */
>> + vmemmap_free_pages(pmd_page(*pmd), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_clear(pmd);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static void free_pmd_table(pud_t *pud)
>> +{
>> + pmd_t *pmd, *pmd_start;
>> + int i;
>> +
>> + pmd_start = (pmd_t *)pud_page_vaddr(*pud);
>> + for (i = 0; i < PTRS_PER_PMD; i++) {
>> + pmd = pmd_start + i;
>> + if (pmd_val(*pmd))
>> + return;
>> + }
>> +
>> + /* free a pmd talbe */
>> + vmemmap_free_pages(pud_page(*pud), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pud_clear(pud);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static void free_pud_table(pgd_t *pgd)
>> +{
>> + pud_t *pud, *pud_start;
>> + int i;
>> +
>> + pud_start = (pud_t *)pgd_page_vaddr(*pgd);
>> + for (i = 0; i < PTRS_PER_PUD; i++) {
>> + pud = pud_start + i;
>> + if (pud_val(*pud))
>> + return;
>> + }
>> +
>> + /* free a pud table */
>> + vmemmap_free_pages(pgd_page(*pgd), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pgd_clear(pgd);
>> + spin_unlock(&init_mm.page_table_lock);
>> +}
>> +
>> +static int split_large_page(pte_t *kpte, unsigned long address, pte_t *pbase)
>> +{
>> + struct page *page = pmd_page(*(pmd_t *)kpte);
>> + int i = 0;
>> + unsigned long magic;
>> + unsigned long section_nr;
>> +
>> + __split_large_page(kpte, address, pbase);
>> + __flush_tlb_all();
>> +
>> + magic = (unsigned long) page->lru.next;
>> + if (magic = SECTION_INFO) {
>> + section_nr = pfn_to_section_nr(page_to_pfn(page));
>> + while (i < PTRS_PER_PMD) {
>> + page++;
>> + i++;
>> + get_page_bootmem(section_nr, page, SECTION_INFO);
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void vmemmap_pte_remove(pmd_t *pmd, unsigned long addr, unsigned long end)
>> +{
>> + pte_t *pte;
>> + unsigned long next;
>> +
>> + pte = pte_offset_kernel(pmd, addr);
>> + for (; addr < end; pte++, addr += PAGE_SIZE) {
>> + next = (addr + PAGE_SIZE) & PAGE_MASK;
>> + if (next > end)
>> + next = end;
>> +
>> + if (pte_none(*pte))
>> + continue;
>> + if (IS_ALIGNED(addr, PAGE_SIZE) &&
>> + IS_ALIGNED(end, PAGE_SIZE)) {
>> + vmemmap_free_pages(pte_page(*pte), 0);
>> + spin_lock(&init_mm.page_table_lock);
>> + pte_clear(&init_mm, addr, pte);
>> + spin_unlock(&init_mm.page_table_lock);
>
> If addr or end is not alianed with PAGE_SIZE, you may leak some
> memory.
>
yes, I think we can handle this situation with the method you mentioned in the change log:
1. When removing memory, the page structs of the revmoved memory are filled
with 0xFD.
2. All page structs are filled with 0xFD on PT/PMD, PT/PMD can be cleared.
In this case, the page used as PT/PMD can be freed.
By the way, why is 0xFD?
>> + }
>> + }
>> +
>> + free_pte_table(pmd);
>> + __flush_tlb_all();
>> +}
>> +
>> +static void vmemmap_pmd_remove(pud_t *pud, unsigned long addr, unsigned long end)
>> +{
>> + unsigned long next;
>> + pmd_t *pmd;
>> +
>> + pmd = pmd_offset(pud, addr);
>> + for (; addr < end; addr = next, pmd++) {
>> + next = pmd_addr_end(addr, end);
>> + if (pmd_none(*pmd))
>> + continue;
>> +
>> + if (cpu_has_pse) {
>> + unsigned long pte_base;
>> +
>> + if (IS_ALIGNED(addr, PMD_SIZE) &&
>> + IS_ALIGNED(next, PMD_SIZE)) {
>> + vmemmap_free_pages(pmd_page(*pmd),
>> + get_order(PMD_SIZE));
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_clear(pmd);
>> + spin_unlock(&init_mm.page_table_lock);
>> + continue;
>> + }
>> +
>> + /*
>> + * We use 2M page, but we need to remove part of them,
>> + * so split 2M page to 4K page.
>> + */
>> + pte_base = get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
>
> get_zeored_page() may fail. You should handle this error.
>
That means system is out of memory, I will trigger a bug_on.
>> + split_large_page((pte_t *)pmd, addr, (pte_t *)pte_base);
>> + __flush_tlb_all();
>> +
>> + spin_lock(&init_mm.page_table_lock);
>> + pmd_populate_kernel(&init_mm, pmd, (pte_t *)pte_base);
>> + spin_unlock(&init_mm.page_table_lock);
>> + }
>> +
>> + vmemmap_pte_remove(pmd, addr, next);
>> + }
>> +
>> + free_pmd_table(pud);
>> + __flush_tlb_all();
>> +}
>> +
>> +static void vmemmap_pud_remove(pgd_t *pgd, unsigned long addr, unsigned long end)
>> +{
>> + unsigned long next;
>> + pud_t *pud;
>> +
>> + pud = pud_offset(pgd, addr);
>> + for (; addr < end; addr = next, pud++) {
>> + next = pud_addr_end(addr, end);
>> + if (pud_none(*pud))
>> + continue;
>> +
>> + vmemmap_pmd_remove(pud, addr, next);
>> + }
>> +
>> + free_pud_table(pgd);
>> + __flush_tlb_all();
>> +}
>> +
>> +void vmemmap_free(struct page *memmap, unsigned long nr_pages)
>> +{
>> + unsigned long addr = (unsigned long)memmap;
>> + unsigned long end = (unsigned long)(memmap + nr_pages);
>> + unsigned long next;
>> +
>> + for (; addr < end; addr = next) {
>> + pgd_t *pgd = pgd_offset_k(addr);
>> +
>> + next = pgd_addr_end(addr, end);
>> + if (!pgd_present(*pgd))
>> + continue;
>> +
>> + vmemmap_pud_remove(pgd, addr, next);
>> + sync_global_pgds(addr, next);
>
> The parameter for sync_global_pgds() is [start, end], not
> [start, end)
>
yes, thanks.
>> + }
>> +}
>> +#endif
>> diff --git a/mm/sparse.c b/mm/sparse.c
>> index fac95f2..3a16d68 100644
>> --- a/mm/sparse.c
>> +++ b/mm/sparse.c
>> @@ -613,12 +613,13 @@ static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
>> /* This will make the necessary allocations eventually. */
>> return sparse_mem_map_populate(pnum, nid);
>> }
>> -static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
>> +static void __kfree_section_memmap(struct page *page, unsigned long nr_pages)
> Why do you change this line?
>
0k, it is no need to change.
>> {
>> - return; /* XXX: Not implemented yet */
>> + vmemmap_free(page, nr_pages);
>> }
>> static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>> {
>> + vmemmap_free(page, nr_pages);
>> }
>> #else
>> static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
>
>
> .
>
^ 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