SUPERH platform development
 help / color / mirror / Atom feed
* [Patch v4 00/12] memory-hotplug: hot-remove physical memory
From: Wen Congyang @ 2012-11-27 10:00 UTC (permalink / raw)
  To: x86, linux-mm, linux-kernel, linuxppc-dev, linux-acpi, linux-s390,
	linux-sh, linux-ia64, cmetcalf, sparclinux
  Cc: David Rientjes, Jiang Liu, Len Brown, benh, paulus,
	Christoph Lameter, Minchan Kim, Andrew Morton, KOSAKI Motohiro,
	Yasuaki Ishimatsu, Jianguo Wu, Wen Congyang

The patch-set was divided from following thread's patch-set.
    https://lkml.org/lkml/2012/9/5/201

The last version of this patchset:
    https://lkml.org/lkml/2012/11/1/93

If you want to know the reason, please read following thread.

https://lkml.org/lkml/2012/10/2/83

The patch-set has only the function of kernel core side for physical
memory hot remove. So if you use the patch, please apply following
patches.

- bug fix for memory hot remove
  https://lkml.org/lkml/2012/10/31/269
  
- acpi framework
  https://lkml.org/lkml/2012/10/26/175

The patches can free/remove the following things:

  - /sys/firmware/memmap/X/{end, start, type} : [PATCH 2/10]
  - mem_section and related sysfs files       : [PATCH 3-4/10]
  - memmap of sparse-vmemmap                  : [PATCH 5-7/10]
  - page table of removed memory              : [RFC PATCH 8/10]
  - node and related sysfs files              : [RFC PATCH 9-10/10]

* [PATCH 2/10] checks whether the memory can be removed or not.

If you find lack of function for physical memory hot-remove, please let me
know.

How to test this patchset?
1. apply this patchset and build the kernel. MEMORY_HOTPLUG, MEMORY_HOTREMOVE,
   ACPI_HOTPLUG_MEMORY must be selected.
2. load the module acpi_memhotplug
3. hotplug the memory device(it depends on your hardware)
   You will see the memory device under the directory /sys/bus/acpi/devices/.
   Its name is PNP0C80:XX.
4. online/offline pages provided by this memory device
   You can write online/offline to /sys/devices/system/memory/memoryX/state to
   online/offline pages provided by this memory device
5. hotremove the memory device
   You can hotremove the memory device by the hardware, or writing 1 to
   /sys/bus/acpi/devices/PNP0C80:XX/eject.

Note: if the memory provided by the memory device is used by the kernel, it
can't be offlined. It is not a bug.

Known problems:
1. hotremoving memory device may cause kernel panicked
   This bug will be fixed by Liu Jiang's patch:
   https://lkml.org/lkml/2012/7/3/1

Changelogs from v3 to v4:
 Patch7: remove unused codes.
 Patch8: fix nr_pages that is passed to free_map_bootmem()

Changelogs from v2 to v3:
 Patch9: call sync_global_pgds() if pgd is changed
 Patch10: fix a problem int the patch

Changelogs from v1 to v2:
 Patch1: new patch, offline memory twice. 1st iterate: offline every non primary
         memory block. 2nd iterate: offline primary (i.e. first added) memory
         block.

 Patch3: new patch, no logical change, just remove reduntant codes.

 Patch9: merge the patch from wujianguo into this patch. flush tlb on all cpu
         after the pagetable is changed.

 Patch12: new patch, free node_data when a node is offlined

Wen Congyang (6):
  memory-hotplug: try to offline the memory twice to avoid dependence
  memory-hotplug: remove redundant codes
  memory-hotplug: introduce new function arch_remove_memory() for
    removing page table depends on architecture
  memory-hotplug: remove page table of x86_64 architecture
  memory-hotplug: remove sysfs file of node
  memory-hotplug: free node_data when a node is offlined

Yasuaki Ishimatsu (6):
  memory-hotplug: check whether all memory blocks are offlined or not
    when removing memory
  memory-hotplug: remove /sys/firmware/memmap/X sysfs
  memory-hotplug: unregister memory section on SPARSEMEM_VMEMMAP
  memory-hotplug: implement register_page_bootmem_info_section of
    sparse-vmemmap
  memory-hotplug: remove memmap of sparse-vmemmap
  memory-hotplug: memory_hotplug: clear zone when removing the memory

 arch/ia64/mm/discontig.c             |  14 ++
 arch/ia64/mm/init.c                  |  18 ++
 arch/powerpc/mm/init_64.c            |  14 ++
 arch/powerpc/mm/mem.c                |  12 +
 arch/s390/mm/init.c                  |  12 +
 arch/s390/mm/vmem.c                  |  14 ++
 arch/sh/mm/init.c                    |  17 ++
 arch/sparc/mm/init_64.c              |  14 ++
 arch/tile/mm/init.c                  |   8 +
 arch/x86/include/asm/pgtable_types.h |   1 +
 arch/x86/mm/init_32.c                |  12 +
 arch/x86/mm/init_64.c                | 417 +++++++++++++++++++++++++++++++++++
 arch/x86/mm/pageattr.c               |  47 ++--
 drivers/acpi/acpi_memhotplug.c       |   8 +-
 drivers/base/memory.c                |   6 +
 drivers/firmware/memmap.c            |  98 +++++++-
 include/linux/firmware-map.h         |   6 +
 include/linux/memory_hotplug.h       |  15 +-
 include/linux/mm.h                   |   5 +-
 mm/memory_hotplug.c                  | 405 ++++++++++++++++++++++++++++++++--
 mm/sparse.c                          |  19 +-
 21 files changed, 1098 insertions(+), 64 deletions(-)

-- 
1.8.0


^ permalink raw reply

* [Patch v4 12/12] memory-hotplug: free node_data when a node is offlined
From: Wen Congyang @ 2012-11-27  9:59 UTC (permalink / raw)
  To: x86, linux-mm, linux-kernel, linuxppc-dev, linux-acpi, linux-s390,
	linux-sh, linux-ia64, cmetcalf, sparclinux
  Cc: David Rientjes, Jiang Liu, Len Brown, benh, paulus,
	Christoph Lameter, Minchan Kim, Andrew Morton, KOSAKI Motohiro,
	Yasuaki Ishimatsu, Jianguo Wu, Wen Congyang
In-Reply-To: <1354010422-19648-1-git-send-email-wency@cn.fujitsu.com>

We call hotadd_new_pgdat() to allocate memory to store node_data. So we
should free it when removing a node.

CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <liuj97@gmail.com>
CC: Len Brown <len.brown@intel.com>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <paulus@samba.org>
CC: Christoph Lameter <cl@linux.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
CC: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 mm/memory_hotplug.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 449663e..d1451ab 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1309,9 +1309,12 @@ static int check_cpu_on_node(void *data)
 /* offline the node if all memory sections of this node are removed */
 static void try_offline_node(int nid)
 {
+	pg_data_t *pgdat = NODE_DATA(nid);
 	unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
-	unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
+	unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages;
 	unsigned long pfn;
+	struct page *pgdat_page = virt_to_page(pgdat);
+	int i;
 
 	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
 		unsigned long section_nr = pfn_to_section_nr(pfn);
@@ -1338,6 +1341,21 @@ static void try_offline_node(int nid)
 	 */
 	node_set_offline(nid);
 	unregister_one_node(nid);
+
+	if (!PageSlab(pgdat_page) && !PageCompound(pgdat_page))
+		/* node data is allocated from boot memory */
+		return;
+
+	/* free waittable in each zone */
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		struct zone *zone = pgdat->node_zones + i;
+
+		if (zone->wait_table)
+			vfree(zone->wait_table);
+	}
+
+	arch_refresh_nodedata(nid, NULL);
+	arch_free_nodedata(pgdat);
 }
 
 int __ref remove_memory(int nid, u64 start, u64 size)
-- 
1.8.0


^ permalink raw reply related

* [Patch v4 01/12] memory-hotplug: try to offline the memory twice to avoid dependence
From: Wen Congyang @ 2012-11-27  9:58 UTC (permalink / raw)
  To: x86, linux-mm, linux-kernel, linuxppc-dev, linux-acpi, linux-s390,
	linux-sh, linux-ia64, cmetcalf, sparclinux
  Cc: David Rientjes, Jiang Liu, Len Brown, benh, paulus,
	Christoph Lameter, Minchan Kim, Andrew Morton, KOSAKI Motohiro,
	Yasuaki Ishimatsu, Jianguo Wu, Wen Congyang
In-Reply-To: <1354010422-19648-1-git-send-email-wency@cn.fujitsu.com>

memory can't be offlined when CONFIG_MEMCG is selected.
For example: there is a memory device on node 1. The address range
is [1G, 1.5G). You will find 4 new directories memory8, memory9, memory10,
and memory11 under the directory /sys/devices/system/memory/.

If CONFIG_MEMCG is selected, we will allocate memory to store page cgroup
when we online pages. When we online memory8, the memory stored page cgroup
is not provided by this memory device. But when we online memory9, the memory
stored page cgroup may be provided by memory8. So we can't offline memory8
now. We should offline the memory in the reversed order.

When the memory device is hotremoved, we will auto offline memory provided
by this memory device. But we don't know which memory is onlined first, so
offlining memory may fail. In such case, iterate twice to offline the memory.
1st iterate: offline every non primary memory block.
2nd iterate: offline primary (i.e. first added) memory block.

This idea is suggested by KOSAKI Motohiro.

CC: David Rientjes <rientjes@google.com>
CC: Jiang Liu <liuj97@gmail.com>
CC: Len Brown <len.brown@intel.com>
CC: Christoph Lameter <cl@linux.com>
Cc: Minchan Kim <minchan.kim@gmail.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
CC: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 mm/memory_hotplug.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index e4eeaca..b825dbc 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1012,10 +1012,13 @@ int remove_memory(u64 start, u64 size)
 	unsigned long start_pfn, end_pfn;
 	unsigned long pfn, section_nr;
 	int ret;
+	int return_on_error = 0;
+	int retry = 0;
 
 	start_pfn = PFN_DOWN(start);
 	end_pfn = start_pfn + PFN_DOWN(size);
 
+repeat:
 	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
 		section_nr = pfn_to_section_nr(pfn);
 		if (!present_section_nr(section_nr))
@@ -1034,14 +1037,23 @@ int remove_memory(u64 start, u64 size)
 
 		ret = offline_memory_block(mem);
 		if (ret) {
-			kobject_put(&mem->dev.kobj);
-			return ret;
+			if (return_on_error) {
+				kobject_put(&mem->dev.kobj);
+				return ret;
+			} else {
+				retry = 1;
+			}
 		}
 	}
 
 	if (mem)
 		kobject_put(&mem->dev.kobj);
 
+	if (retry) {
+		return_on_error = 1;
+		goto repeat;
+	}
+
 	return 0;
 }
 #else
-- 
1.8.0


^ permalink raw reply related

* Re: [PATCH v3 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Jianguo Wu @ 2012-11-27  7:14 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: <50B4625F.1050307@cn.fujitsu.com>

On 2012/11/27 14:49, Wen Congyang wrote:

> At 11/27/2012 01:47 PM, Jianguo Wu Wrote:
>> On 2012/11/1 17:44, Wen Congyang wrote:
>>
>>> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>>
>>> All pages of virtual mapping in removed memory cannot be freed, since some pages
>>> used as PGD/PUD includes not only removed memory but also other memory. So the
>>> patch checks whether page can be freed or not.
>>>
>>> How to check whether page can be freed or not?
>>>  1. When removing memory, the page structs of the revmoved memory are filled
>>>     with 0FD.
>>>  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.
>>>
>>> Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
>>> into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
>>>
>>> Note:  vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
>>> ppc, s390, and sparc.
>>>
>>> CC: David Rientjes <rientjes@google.com>
>>> CC: Jiang Liu <liuj97@gmail.com>
>>> CC: Len Brown <len.brown@intel.com>
>>> CC: Christoph Lameter <cl@linux.com>
>>> Cc: Minchan Kim <minchan.kim@gmail.com>
>>> CC: Andrew Morton <akpm@linux-foundation.org>
>>> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>>> CC: Wen Congyang <wency@cn.fujitsu.com>
>>> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>> ---
>>>  arch/ia64/mm/discontig.c  |   8 ++++
>>>  arch/powerpc/mm/init_64.c |   8 ++++
>>>  arch/s390/mm/vmem.c       |   8 ++++
>>>  arch/sparc/mm/init_64.c   |   8 ++++
>>>  arch/x86/mm/init_64.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++
>>>  include/linux/mm.h        |   2 +
>>>  mm/memory_hotplug.c       |  17 +------
>>>  mm/sparse.c               |   5 +-
>>>  8 files changed, 158 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
>>> index 33943db..0d23b69 100644
>>> --- a/arch/ia64/mm/discontig.c
>>> +++ b/arch/ia64/mm/discontig.c
>>> @@ -823,6 +823,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>>  	return vmemmap_populate_basepages(start_page, size, node);
>>>  }
>>>  
>>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>>  				  struct page *start_page, unsigned long size)
>>>  {
>>> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
>>> index 6466440..df7d155 100644
>>> --- a/arch/powerpc/mm/init_64.c
>>> +++ b/arch/powerpc/mm/init_64.c
>>> @@ -298,6 +298,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>>  	return 0;
>>>  }
>>>  
>>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>>  				  struct page *start_page, unsigned long size)
>>>  {
>>> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
>>> index 4f4803a..ab69c34 100644
>>> --- a/arch/s390/mm/vmem.c
>>> +++ b/arch/s390/mm/vmem.c
>>> @@ -236,6 +236,14 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>>  				  struct page *start_page, unsigned long size)
>>>  {
>>> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
>>> index 75a984b..546855d 100644
>>> --- a/arch/sparc/mm/init_64.c
>>> +++ b/arch/sparc/mm/init_64.c
>>> @@ -2232,6 +2232,14 @@ void __meminit vmemmap_populate_print_last(void)
>>>  	}
>>>  }
>>>  
>>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +}
>>> +
>>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>>  				  struct page *start_page, unsigned long size)
>>>  {
>>> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
>>> index 795dae3..e85626d 100644
>>> --- a/arch/x86/mm/init_64.c
>>> +++ b/arch/x86/mm/init_64.c
>>> @@ -998,6 +998,125 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
>>>  	return 0;
>>>  }
>>>  
>>> +#define PAGE_INUSE 0xFD
>>> +
>>> +unsigned long find_and_clear_pte_page(unsigned long addr, unsigned long end,
>>> +			    struct page **pp, int *page_size)
>>> +{
>>> +	pgd_t *pgd;
>>> +	pud_t *pud;
>>> +	pmd_t *pmd;
>>> +	pte_t *pte = NULL;
>>> +	void *page_addr;
>>> +	unsigned long next;
>>> +
>>> +	*pp = NULL;
>>> +
>>> +	pgd = pgd_offset_k(addr);
>>> +	if (pgd_none(*pgd))
>>> +		return pgd_addr_end(addr, end);
>>> +
>>> +	pud = pud_offset(pgd, addr);
>>> +	if (pud_none(*pud))
>>> +		return pud_addr_end(addr, end);
>>> +
>>> +	if (!cpu_has_pse) {
>>> +		next = (addr + PAGE_SIZE) & PAGE_MASK;
>>> +		pmd = pmd_offset(pud, addr);
>>> +		if (pmd_none(*pmd))
>>> +			return next;
>>> +
>>> +		pte = pte_offset_kernel(pmd, addr);
>>> +		if (pte_none(*pte))
>>> +			return next;
>>> +
>>> +		*page_size = PAGE_SIZE;
>>> +		*pp = pte_page(*pte);
>>> +	} else {
>>> +		next = pmd_addr_end(addr, end);
>>> +
>>> +		pmd = pmd_offset(pud, addr);
>>> +		if (pmd_none(*pmd))
>>> +			return next;
>>> +
>>> +		*page_size = PMD_SIZE;
>>> +		*pp = pmd_page(*pmd);
>>> +	}
>>> +
>>> +	/*
>>> +	 * Removed page structs are filled with 0xFD.
>>> +	 */
>>> +	memset((void *)addr, PAGE_INUSE, next - addr);
>>> +
>>> +	page_addr = page_address(*pp);
>>> +
>>> +	/*
>>> +	 * Check the page is filled with 0xFD or not.
>>> +	 * memchr_inv() returns the address. In this case, we cannot
>>> +	 * clear PTE/PUD entry, since the page is used by other.
>>> +	 * So we cannot also free the page.
>>> +	 *
>>> +	 * memchr_inv() returns NULL. In this case, we can clear
>>> +	 * PTE/PUD entry, since the page is not used by other.
>>> +	 * So we can also free the page.
>>> +	 */
>>> +	if (memchr_inv(page_addr, PAGE_INUSE, *page_size)) {
>>> +		*pp = NULL;
>>> +		return next;
>>> +	}
>>> +
>>> +	if (!cpu_has_pse)
>>> +		pte_clear(&init_mm, addr, pte);
>>> +	else
>>> +		pmd_clear(pmd);
>>> +
>>> +	return next;
>>> +}
>>> +
>>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +	unsigned long addr = (unsigned long)memmap;
>>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>>> +	unsigned long next;
>>> +	struct page *page;
>>> +	int page_size;
>>> +
>>> +	for (; addr < end; addr = next) {
>>> +		page = NULL;
>>> +		page_size = 0;
>>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>>> +		if (!page)
>>> +			continue;
>>> +
>>> +		free_pages((unsigned long)page_address(page),
>>> +			    get_order(page_size));
>>> +		__flush_tlb_one(addr);
>>> +	}
>>> +}
>>> +
>>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>>> +{
>>> +	unsigned long addr = (unsigned long)memmap;
>>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>>> +	unsigned long next;
>>> +	struct page *page;
>>> +	int page_size;
>>> +	unsigned long magic;
>>> +
>>> +	for (; addr < end; addr = next) {
>>> +		page = NULL;
>>> +		page_size = 0;
>>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>>> +		if (!page)
>>> +			continue;
>>> +
>>> +		magic = (unsigned long) page->lru.next;
>>> +		if (magic = SECTION_INFO)
>>> +			put_page_bootmem(page);
>>> +		flush_tlb_kernel_range(addr, end);
>>> +	}
>>> +}
>>> +
>>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>>  				  struct page *start_page, unsigned long size)
>>>  {
>>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>>> index 8e5a56f..42b8723 100644
>>> --- a/include/linux/mm.h
>>> +++ b/include/linux/mm.h
>>> @@ -1642,6 +1642,8 @@ 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_kfree(struct page *memmpa, unsigned long nr_pages);
>>> +void vmemmap_free_bootmem(struct page *memmpa, unsigned long nr_pages);
>>>  
>>>  enum mf_flags {
>>>  	MF_COUNT_INCREASED = 1 << 0,
>>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>>> index db9806c..03153cf 100644
>>> --- a/mm/memory_hotplug.c
>>> +++ b/mm/memory_hotplug.c
>>> @@ -312,19 +312,6 @@ static int __meminit __add_section(int nid, struct zone *zone,
>>>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>>>  }
>>>  
>>> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
>>> -static int __remove_section(struct zone *zone, struct mem_section *ms)
>>> -{
>>> -	int ret = -EINVAL;
>>> -
>>> -	if (!valid_section(ms))
>>> -		return ret;
>>> -
>>> -	ret = unregister_memory_section(ms);
>>> -
>>> -	return ret;
>>> -}
>>> -#else
>>>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>>>  {
>>>  	unsigned long flags;
>>> @@ -341,9 +328,9 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>>>  	pgdat_resize_lock(pgdat, &flags);
>>>  	sparse_remove_one_section(zone, ms);
>>>  	pgdat_resize_unlock(pgdat, &flags);
>>> -	return 0;
>>> +
>>> +	return ret;
>>>  }
>>> -#endif
>>>  
>>>  /*
>>>   * Reasonably generic function for adding memory.  It is
>>> diff --git a/mm/sparse.c b/mm/sparse.c
>>> index fac95f2..ab9d755 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)
>>>  {
>>> -	return; /* XXX: Not implemented yet */
>>> +	vmemmap_kfree(page, nr_pages);
>>>  }
>>>  static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>>>  {
>>> +	vmemmap_free_bootmem(page, nr_pages);
>>>  }
>>
>> Hi Congyang,
>> 	For vmemmap, nr_pages should be PAGES_PER_SECTION for free_map_bootmem(),
>> which is passed by free_section_usemap(), right? 
>> But now, nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT.
>>
>> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
>> ---
>>  mm/sparse.c |    4 ++++
>>  1 files changed, 4 insertions(+), 0 deletions(-)
>>
>> diff --git a/mm/sparse.c b/mm/sparse.c
>> index fac95f2..31e5282 100644
>> --- a/mm/sparse.c
>> +++ b/mm/sparse.c
>> @@ -713,8 +713,12 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
>>  		struct page *memmap_page;
>>  		memmap_page = virt_to_page(memmap);
>>  
>> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
>> +		nr_pages = PAGES_PER_SECTION;
>> +#else
>>  		nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
>>  			>> PAGE_SHIFT;
>> +#endif
> 
> Hmm, to avoid using ifdef, I think we can pass PAGE_PER_SECTION to free_map_bootmem(),
> and calculate how many pages is used to store struct page.
> 

yes, it is ugly to use ifdef. Or we can remove parameter--nr_pages of free_map_bootmem(),
and calculate nr_pages in free_map_bootmem() directly.

> Thanks
> Wen Congyang
> 
>>  
>>  		free_map_bootmem(memmap_page, nr_pages);
>>  	}
> 
> 
> .
> 




^ permalink raw reply

* Re: [PATCH v3 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Wen Congyang @ 2012-11-27  6:49 UTC (permalink / raw)
  To: Jianguo Wu
  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: <50B45400.20800@huawei.com>

At 11/27/2012 01:47 PM, Jianguo Wu Wrote:
> On 2012/11/1 17:44, Wen Congyang wrote:
> 
>> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>
>> All pages of virtual mapping in removed memory cannot be freed, since some pages
>> used as PGD/PUD includes not only removed memory but also other memory. So the
>> patch checks whether page can be freed or not.
>>
>> How to check whether page can be freed or not?
>>  1. When removing memory, the page structs of the revmoved memory are filled
>>     with 0FD.
>>  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.
>>
>> Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
>> into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
>>
>> Note:  vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
>> ppc, s390, and sparc.
>>
>> CC: David Rientjes <rientjes@google.com>
>> CC: Jiang Liu <liuj97@gmail.com>
>> CC: Len Brown <len.brown@intel.com>
>> CC: Christoph Lameter <cl@linux.com>
>> Cc: Minchan Kim <minchan.kim@gmail.com>
>> CC: Andrew Morton <akpm@linux-foundation.org>
>> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>> CC: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>> ---
>>  arch/ia64/mm/discontig.c  |   8 ++++
>>  arch/powerpc/mm/init_64.c |   8 ++++
>>  arch/s390/mm/vmem.c       |   8 ++++
>>  arch/sparc/mm/init_64.c   |   8 ++++
>>  arch/x86/mm/init_64.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/mm.h        |   2 +
>>  mm/memory_hotplug.c       |  17 +------
>>  mm/sparse.c               |   5 +-
>>  8 files changed, 158 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
>> index 33943db..0d23b69 100644
>> --- a/arch/ia64/mm/discontig.c
>> +++ b/arch/ia64/mm/discontig.c
>> @@ -823,6 +823,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>  	return vmemmap_populate_basepages(start_page, size, node);
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
>> index 6466440..df7d155 100644
>> --- a/arch/powerpc/mm/init_64.c
>> +++ b/arch/powerpc/mm/init_64.c
>> @@ -298,6 +298,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>  	return 0;
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
>> index 4f4803a..ab69c34 100644
>> --- a/arch/s390/mm/vmem.c
>> +++ b/arch/s390/mm/vmem.c
>> @@ -236,6 +236,14 @@ out:
>>  	return ret;
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
>> index 75a984b..546855d 100644
>> --- a/arch/sparc/mm/init_64.c
>> +++ b/arch/sparc/mm/init_64.c
>> @@ -2232,6 +2232,14 @@ void __meminit vmemmap_populate_print_last(void)
>>  	}
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
>> index 795dae3..e85626d 100644
>> --- a/arch/x86/mm/init_64.c
>> +++ b/arch/x86/mm/init_64.c
>> @@ -998,6 +998,125 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
>>  	return 0;
>>  }
>>  
>> +#define PAGE_INUSE 0xFD
>> +
>> +unsigned long find_and_clear_pte_page(unsigned long addr, unsigned long end,
>> +			    struct page **pp, int *page_size)
>> +{
>> +	pgd_t *pgd;
>> +	pud_t *pud;
>> +	pmd_t *pmd;
>> +	pte_t *pte = NULL;
>> +	void *page_addr;
>> +	unsigned long next;
>> +
>> +	*pp = NULL;
>> +
>> +	pgd = pgd_offset_k(addr);
>> +	if (pgd_none(*pgd))
>> +		return pgd_addr_end(addr, end);
>> +
>> +	pud = pud_offset(pgd, addr);
>> +	if (pud_none(*pud))
>> +		return pud_addr_end(addr, end);
>> +
>> +	if (!cpu_has_pse) {
>> +		next = (addr + PAGE_SIZE) & PAGE_MASK;
>> +		pmd = pmd_offset(pud, addr);
>> +		if (pmd_none(*pmd))
>> +			return next;
>> +
>> +		pte = pte_offset_kernel(pmd, addr);
>> +		if (pte_none(*pte))
>> +			return next;
>> +
>> +		*page_size = PAGE_SIZE;
>> +		*pp = pte_page(*pte);
>> +	} else {
>> +		next = pmd_addr_end(addr, end);
>> +
>> +		pmd = pmd_offset(pud, addr);
>> +		if (pmd_none(*pmd))
>> +			return next;
>> +
>> +		*page_size = PMD_SIZE;
>> +		*pp = pmd_page(*pmd);
>> +	}
>> +
>> +	/*
>> +	 * Removed page structs are filled with 0xFD.
>> +	 */
>> +	memset((void *)addr, PAGE_INUSE, next - addr);
>> +
>> +	page_addr = page_address(*pp);
>> +
>> +	/*
>> +	 * Check the page is filled with 0xFD or not.
>> +	 * memchr_inv() returns the address. In this case, we cannot
>> +	 * clear PTE/PUD entry, since the page is used by other.
>> +	 * So we cannot also free the page.
>> +	 *
>> +	 * memchr_inv() returns NULL. In this case, we can clear
>> +	 * PTE/PUD entry, since the page is not used by other.
>> +	 * So we can also free the page.
>> +	 */
>> +	if (memchr_inv(page_addr, PAGE_INUSE, *page_size)) {
>> +		*pp = NULL;
>> +		return next;
>> +	}
>> +
>> +	if (!cpu_has_pse)
>> +		pte_clear(&init_mm, addr, pte);
>> +	else
>> +		pmd_clear(pmd);
>> +
>> +	return next;
>> +}
>> +
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +	unsigned long addr = (unsigned long)memmap;
>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>> +	unsigned long next;
>> +	struct page *page;
>> +	int page_size;
>> +
>> +	for (; addr < end; addr = next) {
>> +		page = NULL;
>> +		page_size = 0;
>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>> +		if (!page)
>> +			continue;
>> +
>> +		free_pages((unsigned long)page_address(page),
>> +			    get_order(page_size));
>> +		__flush_tlb_one(addr);
>> +	}
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +	unsigned long addr = (unsigned long)memmap;
>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>> +	unsigned long next;
>> +	struct page *page;
>> +	int page_size;
>> +	unsigned long magic;
>> +
>> +	for (; addr < end; addr = next) {
>> +		page = NULL;
>> +		page_size = 0;
>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>> +		if (!page)
>> +			continue;
>> +
>> +		magic = (unsigned long) page->lru.next;
>> +		if (magic = SECTION_INFO)
>> +			put_page_bootmem(page);
>> +		flush_tlb_kernel_range(addr, end);
>> +	}
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 8e5a56f..42b8723 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1642,6 +1642,8 @@ 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_kfree(struct page *memmpa, unsigned long nr_pages);
>> +void vmemmap_free_bootmem(struct page *memmpa, unsigned long nr_pages);
>>  
>>  enum mf_flags {
>>  	MF_COUNT_INCREASED = 1 << 0,
>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>> index db9806c..03153cf 100644
>> --- a/mm/memory_hotplug.c
>> +++ b/mm/memory_hotplug.c
>> @@ -312,19 +312,6 @@ static int __meminit __add_section(int nid, struct zone *zone,
>>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>>  }
>>  
>> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
>> -static int __remove_section(struct zone *zone, struct mem_section *ms)
>> -{
>> -	int ret = -EINVAL;
>> -
>> -	if (!valid_section(ms))
>> -		return ret;
>> -
>> -	ret = unregister_memory_section(ms);
>> -
>> -	return ret;
>> -}
>> -#else
>>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  {
>>  	unsigned long flags;
>> @@ -341,9 +328,9 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  	pgdat_resize_lock(pgdat, &flags);
>>  	sparse_remove_one_section(zone, ms);
>>  	pgdat_resize_unlock(pgdat, &flags);
>> -	return 0;
>> +
>> +	return ret;
>>  }
>> -#endif
>>  
>>  /*
>>   * Reasonably generic function for adding memory.  It is
>> diff --git a/mm/sparse.c b/mm/sparse.c
>> index fac95f2..ab9d755 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)
>>  {
>> -	return; /* XXX: Not implemented yet */
>> +	vmemmap_kfree(page, nr_pages);
>>  }
>>  static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>>  {
>> +	vmemmap_free_bootmem(page, nr_pages);
>>  }
> 
> Hi Congyang,
> 	For vmemmap, nr_pages should be PAGES_PER_SECTION for free_map_bootmem(),
> which is passed by free_section_usemap(), right? 
> But now, nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT.
> 
> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
> ---
>  mm/sparse.c |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/mm/sparse.c b/mm/sparse.c
> index fac95f2..31e5282 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -713,8 +713,12 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
>  		struct page *memmap_page;
>  		memmap_page = virt_to_page(memmap);
>  
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +		nr_pages = PAGES_PER_SECTION;
> +#else
>  		nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
>  			>> PAGE_SHIFT;
> +#endif

Hmm, to avoid using ifdef, I think we can pass PAGE_PER_SECTION to free_map_bootmem(),
and calculate how many pages is used to store struct page.

Thanks
Wen Congyang

>  
>  		free_map_bootmem(memmap_page, nr_pages);
>  	}


^ permalink raw reply

* Re: [PATCH v3 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Wen Congyang @ 2012-11-27  6:39 UTC (permalink / raw)
  To: Jianguo Wu
  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: <50B45400.20800@huawei.com>

At 11/27/2012 01:47 PM, Jianguo Wu Wrote:
> On 2012/11/1 17:44, Wen Congyang wrote:
> 
>> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>
>> All pages of virtual mapping in removed memory cannot be freed, since some pages
>> used as PGD/PUD includes not only removed memory but also other memory. So the
>> patch checks whether page can be freed or not.
>>
>> How to check whether page can be freed or not?
>>  1. When removing memory, the page structs of the revmoved memory are filled
>>     with 0FD.
>>  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.
>>
>> Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
>> into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
>>
>> Note:  vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
>> ppc, s390, and sparc.
>>
>> CC: David Rientjes <rientjes@google.com>
>> CC: Jiang Liu <liuj97@gmail.com>
>> CC: Len Brown <len.brown@intel.com>
>> CC: Christoph Lameter <cl@linux.com>
>> Cc: Minchan Kim <minchan.kim@gmail.com>
>> CC: Andrew Morton <akpm@linux-foundation.org>
>> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>> CC: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>> ---
>>  arch/ia64/mm/discontig.c  |   8 ++++
>>  arch/powerpc/mm/init_64.c |   8 ++++
>>  arch/s390/mm/vmem.c       |   8 ++++
>>  arch/sparc/mm/init_64.c   |   8 ++++
>>  arch/x86/mm/init_64.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/mm.h        |   2 +
>>  mm/memory_hotplug.c       |  17 +------
>>  mm/sparse.c               |   5 +-
>>  8 files changed, 158 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
>> index 33943db..0d23b69 100644
>> --- a/arch/ia64/mm/discontig.c
>> +++ b/arch/ia64/mm/discontig.c
>> @@ -823,6 +823,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>  	return vmemmap_populate_basepages(start_page, size, node);
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
>> index 6466440..df7d155 100644
>> --- a/arch/powerpc/mm/init_64.c
>> +++ b/arch/powerpc/mm/init_64.c
>> @@ -298,6 +298,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>>  	return 0;
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
>> index 4f4803a..ab69c34 100644
>> --- a/arch/s390/mm/vmem.c
>> +++ b/arch/s390/mm/vmem.c
>> @@ -236,6 +236,14 @@ out:
>>  	return ret;
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
>> index 75a984b..546855d 100644
>> --- a/arch/sparc/mm/init_64.c
>> +++ b/arch/sparc/mm/init_64.c
>> @@ -2232,6 +2232,14 @@ void __meminit vmemmap_populate_print_last(void)
>>  	}
>>  }
>>  
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
>> index 795dae3..e85626d 100644
>> --- a/arch/x86/mm/init_64.c
>> +++ b/arch/x86/mm/init_64.c
>> @@ -998,6 +998,125 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
>>  	return 0;
>>  }
>>  
>> +#define PAGE_INUSE 0xFD
>> +
>> +unsigned long find_and_clear_pte_page(unsigned long addr, unsigned long end,
>> +			    struct page **pp, int *page_size)
>> +{
>> +	pgd_t *pgd;
>> +	pud_t *pud;
>> +	pmd_t *pmd;
>> +	pte_t *pte = NULL;
>> +	void *page_addr;
>> +	unsigned long next;
>> +
>> +	*pp = NULL;
>> +
>> +	pgd = pgd_offset_k(addr);
>> +	if (pgd_none(*pgd))
>> +		return pgd_addr_end(addr, end);
>> +
>> +	pud = pud_offset(pgd, addr);
>> +	if (pud_none(*pud))
>> +		return pud_addr_end(addr, end);
>> +
>> +	if (!cpu_has_pse) {
>> +		next = (addr + PAGE_SIZE) & PAGE_MASK;
>> +		pmd = pmd_offset(pud, addr);
>> +		if (pmd_none(*pmd))
>> +			return next;
>> +
>> +		pte = pte_offset_kernel(pmd, addr);
>> +		if (pte_none(*pte))
>> +			return next;
>> +
>> +		*page_size = PAGE_SIZE;
>> +		*pp = pte_page(*pte);
>> +	} else {
>> +		next = pmd_addr_end(addr, end);
>> +
>> +		pmd = pmd_offset(pud, addr);
>> +		if (pmd_none(*pmd))
>> +			return next;
>> +
>> +		*page_size = PMD_SIZE;
>> +		*pp = pmd_page(*pmd);
>> +	}
>> +
>> +	/*
>> +	 * Removed page structs are filled with 0xFD.
>> +	 */
>> +	memset((void *)addr, PAGE_INUSE, next - addr);
>> +
>> +	page_addr = page_address(*pp);
>> +
>> +	/*
>> +	 * Check the page is filled with 0xFD or not.
>> +	 * memchr_inv() returns the address. In this case, we cannot
>> +	 * clear PTE/PUD entry, since the page is used by other.
>> +	 * So we cannot also free the page.
>> +	 *
>> +	 * memchr_inv() returns NULL. In this case, we can clear
>> +	 * PTE/PUD entry, since the page is not used by other.
>> +	 * So we can also free the page.
>> +	 */
>> +	if (memchr_inv(page_addr, PAGE_INUSE, *page_size)) {
>> +		*pp = NULL;
>> +		return next;
>> +	}
>> +
>> +	if (!cpu_has_pse)
>> +		pte_clear(&init_mm, addr, pte);
>> +	else
>> +		pmd_clear(pmd);
>> +
>> +	return next;
>> +}
>> +
>> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
>> +{
>> +	unsigned long addr = (unsigned long)memmap;
>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>> +	unsigned long next;
>> +	struct page *page;
>> +	int page_size;
>> +
>> +	for (; addr < end; addr = next) {
>> +		page = NULL;
>> +		page_size = 0;
>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>> +		if (!page)
>> +			continue;
>> +
>> +		free_pages((unsigned long)page_address(page),
>> +			    get_order(page_size));
>> +		__flush_tlb_one(addr);
>> +	}
>> +}
>> +
>> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
>> +{
>> +	unsigned long addr = (unsigned long)memmap;
>> +	unsigned long end = (unsigned long)(memmap + nr_pages);
>> +	unsigned long next;
>> +	struct page *page;
>> +	int page_size;
>> +	unsigned long magic;
>> +
>> +	for (; addr < end; addr = next) {
>> +		page = NULL;
>> +		page_size = 0;
>> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
>> +		if (!page)
>> +			continue;
>> +
>> +		magic = (unsigned long) page->lru.next;
>> +		if (magic = SECTION_INFO)
>> +			put_page_bootmem(page);
>> +		flush_tlb_kernel_range(addr, end);
>> +	}
>> +}
>> +
>>  void register_page_bootmem_memmap(unsigned long section_nr,
>>  				  struct page *start_page, unsigned long size)
>>  {
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 8e5a56f..42b8723 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -1642,6 +1642,8 @@ 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_kfree(struct page *memmpa, unsigned long nr_pages);
>> +void vmemmap_free_bootmem(struct page *memmpa, unsigned long nr_pages);
>>  
>>  enum mf_flags {
>>  	MF_COUNT_INCREASED = 1 << 0,
>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>> index db9806c..03153cf 100644
>> --- a/mm/memory_hotplug.c
>> +++ b/mm/memory_hotplug.c
>> @@ -312,19 +312,6 @@ static int __meminit __add_section(int nid, struct zone *zone,
>>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>>  }
>>  
>> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
>> -static int __remove_section(struct zone *zone, struct mem_section *ms)
>> -{
>> -	int ret = -EINVAL;
>> -
>> -	if (!valid_section(ms))
>> -		return ret;
>> -
>> -	ret = unregister_memory_section(ms);
>> -
>> -	return ret;
>> -}
>> -#else
>>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  {
>>  	unsigned long flags;
>> @@ -341,9 +328,9 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  	pgdat_resize_lock(pgdat, &flags);
>>  	sparse_remove_one_section(zone, ms);
>>  	pgdat_resize_unlock(pgdat, &flags);
>> -	return 0;
>> +
>> +	return ret;
>>  }
>> -#endif
>>  
>>  /*
>>   * Reasonably generic function for adding memory.  It is
>> diff --git a/mm/sparse.c b/mm/sparse.c
>> index fac95f2..ab9d755 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)
>>  {
>> -	return; /* XXX: Not implemented yet */
>> +	vmemmap_kfree(page, nr_pages);
>>  }
>>  static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>>  {
>> +	vmemmap_free_bootmem(page, nr_pages);
>>  }
> 
> Hi Congyang,
> 	For vmemmap, nr_pages should be PAGES_PER_SECTION for free_map_bootmem(),
> which is passed by free_section_usemap(), right? 

Yes, you are right. I will merge it into my patchset.

I will sent the new patchset later today.

Thanks
Wen Congyang

> But now, nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT.
> 
> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
> ---
>  mm/sparse.c |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/mm/sparse.c b/mm/sparse.c
> index fac95f2..31e5282 100644
> --- a/mm/sparse.c
> +++ b/mm/sparse.c
> @@ -713,8 +713,12 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
>  		struct page *memmap_page;
>  		memmap_page = virt_to_page(memmap);
>  
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +		nr_pages = PAGES_PER_SECTION;
> +#else
>  		nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
>  			>> PAGE_SHIFT;
> +#endif
>  
>  		free_map_bootmem(memmap_page, nr_pages);
>  	}


^ permalink raw reply

* Re: [PATCH v3 08/12] memory-hotplug: remove memmap of sparse-vmemmap
From: Jianguo Wu @ 2012-11-27  5: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: <1351763083-7905-9-git-send-email-wency@cn.fujitsu.com>

On 2012/11/1 17:44, Wen Congyang wrote:

> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> 
> All pages of virtual mapping in removed memory cannot be freed, since some pages
> used as PGD/PUD includes not only removed memory but also other memory. So the
> patch checks whether page can be freed or not.
> 
> How to check whether page can be freed or not?
>  1. When removing memory, the page structs of the revmoved memory are filled
>     with 0FD.
>  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.
> 
> Applying patch, __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is integrated
> into one. So __remove_section() of CONFIG_SPARSEMEM_VMEMMAP is deleted.
> 
> Note:  vmemmap_kfree() and vmemmap_free_bootmem() are not implemented for ia64,
> ppc, s390, and sparc.
> 
> CC: David Rientjes <rientjes@google.com>
> CC: Jiang Liu <liuj97@gmail.com>
> CC: Len Brown <len.brown@intel.com>
> CC: Christoph Lameter <cl@linux.com>
> Cc: Minchan Kim <minchan.kim@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> CC: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> ---
>  arch/ia64/mm/discontig.c  |   8 ++++
>  arch/powerpc/mm/init_64.c |   8 ++++
>  arch/s390/mm/vmem.c       |   8 ++++
>  arch/sparc/mm/init_64.c   |   8 ++++
>  arch/x86/mm/init_64.c     | 119 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mm.h        |   2 +
>  mm/memory_hotplug.c       |  17 +------
>  mm/sparse.c               |   5 +-
>  8 files changed, 158 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
> index 33943db..0d23b69 100644
> --- a/arch/ia64/mm/discontig.c
> +++ b/arch/ia64/mm/discontig.c
> @@ -823,6 +823,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>  	return vmemmap_populate_basepages(start_page, size, node);
>  }
>  
> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
>  void register_page_bootmem_memmap(unsigned long section_nr,
>  				  struct page *start_page, unsigned long size)
>  {
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 6466440..df7d155 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -298,6 +298,14 @@ int __meminit vmemmap_populate(struct page *start_page,
>  	return 0;
>  }
>  
> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
>  void register_page_bootmem_memmap(unsigned long section_nr,
>  				  struct page *start_page, unsigned long size)
>  {
> diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
> index 4f4803a..ab69c34 100644
> --- a/arch/s390/mm/vmem.c
> +++ b/arch/s390/mm/vmem.c
> @@ -236,6 +236,14 @@ out:
>  	return ret;
>  }
>  
> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
>  void register_page_bootmem_memmap(unsigned long section_nr,
>  				  struct page *start_page, unsigned long size)
>  {
> diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
> index 75a984b..546855d 100644
> --- a/arch/sparc/mm/init_64.c
> +++ b/arch/sparc/mm/init_64.c
> @@ -2232,6 +2232,14 @@ void __meminit vmemmap_populate_print_last(void)
>  	}
>  }
>  
> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
> +{
> +}
> +
>  void register_page_bootmem_memmap(unsigned long section_nr,
>  				  struct page *start_page, unsigned long size)
>  {
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index 795dae3..e85626d 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -998,6 +998,125 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node)
>  	return 0;
>  }
>  
> +#define PAGE_INUSE 0xFD
> +
> +unsigned long find_and_clear_pte_page(unsigned long addr, unsigned long end,
> +			    struct page **pp, int *page_size)
> +{
> +	pgd_t *pgd;
> +	pud_t *pud;
> +	pmd_t *pmd;
> +	pte_t *pte = NULL;
> +	void *page_addr;
> +	unsigned long next;
> +
> +	*pp = NULL;
> +
> +	pgd = pgd_offset_k(addr);
> +	if (pgd_none(*pgd))
> +		return pgd_addr_end(addr, end);
> +
> +	pud = pud_offset(pgd, addr);
> +	if (pud_none(*pud))
> +		return pud_addr_end(addr, end);
> +
> +	if (!cpu_has_pse) {
> +		next = (addr + PAGE_SIZE) & PAGE_MASK;
> +		pmd = pmd_offset(pud, addr);
> +		if (pmd_none(*pmd))
> +			return next;
> +
> +		pte = pte_offset_kernel(pmd, addr);
> +		if (pte_none(*pte))
> +			return next;
> +
> +		*page_size = PAGE_SIZE;
> +		*pp = pte_page(*pte);
> +	} else {
> +		next = pmd_addr_end(addr, end);
> +
> +		pmd = pmd_offset(pud, addr);
> +		if (pmd_none(*pmd))
> +			return next;
> +
> +		*page_size = PMD_SIZE;
> +		*pp = pmd_page(*pmd);
> +	}
> +
> +	/*
> +	 * Removed page structs are filled with 0xFD.
> +	 */
> +	memset((void *)addr, PAGE_INUSE, next - addr);
> +
> +	page_addr = page_address(*pp);
> +
> +	/*
> +	 * Check the page is filled with 0xFD or not.
> +	 * memchr_inv() returns the address. In this case, we cannot
> +	 * clear PTE/PUD entry, since the page is used by other.
> +	 * So we cannot also free the page.
> +	 *
> +	 * memchr_inv() returns NULL. In this case, we can clear
> +	 * PTE/PUD entry, since the page is not used by other.
> +	 * So we can also free the page.
> +	 */
> +	if (memchr_inv(page_addr, PAGE_INUSE, *page_size)) {
> +		*pp = NULL;
> +		return next;
> +	}
> +
> +	if (!cpu_has_pse)
> +		pte_clear(&init_mm, addr, pte);
> +	else
> +		pmd_clear(pmd);
> +
> +	return next;
> +}
> +
> +void vmemmap_kfree(struct page *memmap, unsigned long nr_pages)
> +{
> +	unsigned long addr = (unsigned long)memmap;
> +	unsigned long end = (unsigned long)(memmap + nr_pages);
> +	unsigned long next;
> +	struct page *page;
> +	int page_size;
> +
> +	for (; addr < end; addr = next) {
> +		page = NULL;
> +		page_size = 0;
> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
> +		if (!page)
> +			continue;
> +
> +		free_pages((unsigned long)page_address(page),
> +			    get_order(page_size));
> +		__flush_tlb_one(addr);
> +	}
> +}
> +
> +void vmemmap_free_bootmem(struct page *memmap, unsigned long nr_pages)
> +{
> +	unsigned long addr = (unsigned long)memmap;
> +	unsigned long end = (unsigned long)(memmap + nr_pages);
> +	unsigned long next;
> +	struct page *page;
> +	int page_size;
> +	unsigned long magic;
> +
> +	for (; addr < end; addr = next) {
> +		page = NULL;
> +		page_size = 0;
> +		next = find_and_clear_pte_page(addr, end, &page, &page_size);
> +		if (!page)
> +			continue;
> +
> +		magic = (unsigned long) page->lru.next;
> +		if (magic = SECTION_INFO)
> +			put_page_bootmem(page);
> +		flush_tlb_kernel_range(addr, end);
> +	}
> +}
> +
>  void register_page_bootmem_memmap(unsigned long section_nr,
>  				  struct page *start_page, unsigned long size)
>  {
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 8e5a56f..42b8723 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -1642,6 +1642,8 @@ 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_kfree(struct page *memmpa, unsigned long nr_pages);
> +void vmemmap_free_bootmem(struct page *memmpa, unsigned long nr_pages);
>  
>  enum mf_flags {
>  	MF_COUNT_INCREASED = 1 << 0,
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index db9806c..03153cf 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -312,19 +312,6 @@ static int __meminit __add_section(int nid, struct zone *zone,
>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>  }
>  
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -static int __remove_section(struct zone *zone, struct mem_section *ms)
> -{
> -	int ret = -EINVAL;
> -
> -	if (!valid_section(ms))
> -		return ret;
> -
> -	ret = unregister_memory_section(ms);
> -
> -	return ret;
> -}
> -#else
>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>  {
>  	unsigned long flags;
> @@ -341,9 +328,9 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>  	pgdat_resize_lock(pgdat, &flags);
>  	sparse_remove_one_section(zone, ms);
>  	pgdat_resize_unlock(pgdat, &flags);
> -	return 0;
> +
> +	return ret;
>  }
> -#endif
>  
>  /*
>   * Reasonably generic function for adding memory.  It is
> diff --git a/mm/sparse.c b/mm/sparse.c
> index fac95f2..ab9d755 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)
>  {
> -	return; /* XXX: Not implemented yet */
> +	vmemmap_kfree(page, nr_pages);
>  }
>  static void free_map_bootmem(struct page *page, unsigned long nr_pages)
>  {
> +	vmemmap_free_bootmem(page, nr_pages);
>  }

Hi Congyang,
	For vmemmap, nr_pages should be PAGES_PER_SECTION for free_map_bootmem(),
which is passed by free_section_usemap(), right? 
But now, nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT.

Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
---
 mm/sparse.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/mm/sparse.c b/mm/sparse.c
index fac95f2..31e5282 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -713,8 +713,12 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
 		struct page *memmap_page;
 		memmap_page = virt_to_page(memmap);
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+		nr_pages = PAGES_PER_SECTION;
+#else
 		nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page))
 			>> PAGE_SHIFT;
+#endif
 
 		free_map_bootmem(memmap_page, nr_pages);
 	}
-- 
1.7.6.1

>  #else
>  static struct page *__kmalloc_section_memmap(unsigned long nr_pages)




^ permalink raw reply related

* Re: [PATCH] Update ARM/SHMOBILE section of MAINTAINERS
From: Paul Mundt @ 2012-11-27  4:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1353984346-25463-1-git-send-email-horms@verge.net.au>

On Tue, Nov 27, 2012 at 11:45:46AM +0900, Simon Horman wrote:
> From: Simon Horman <horms+renesas@verge.net.au>
> 
> I have been handling maintenance of shmobile
> for a little over a release-cycle now and it seems
> to appropriate to update the MAINTAINERS file accordingly.
> 
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>

Acked-by: Paul Mundt <lethal@linux-sh.org>

^ permalink raw reply

* Re: [PATCH 1/1] ARM: shmobile: Remove duplicate inclusion of dma-mapping.h in setup-r8a7740.c
From: Sachin Kamat @ 2012-11-27  3:47 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <1353393549-1532-1-git-send-email-sachin.kamat@linaro.org>

ping

On 20 November 2012 12:09, Sachin Kamat <sachin.kamat@linaro.org> wrote:
> linux/dma-mapping.h was included twice.
>
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>  arch/arm/mach-shmobile/setup-r8a7740.c |    1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
> index 0952224..878a07a 100644
> --- a/arch/arm/mach-shmobile/setup-r8a7740.c
> +++ b/arch/arm/mach-shmobile/setup-r8a7740.c
> @@ -27,7 +27,6 @@
>  #include <linux/serial_sci.h>
>  #include <linux/sh_dma.h>
>  #include <linux/sh_timer.h>
> -#include <linux/dma-mapping.h>
>  #include <mach/dma-register.h>
>  #include <mach/r8a7740.h>
>  #include <mach/pm-rmobile.h>
> --
> 1.7.4.1
>



-- 
With warm regards,
Sachin

^ permalink raw reply

* Re: [PATCH 4/7] ARM: shmobile: pfc-sh73a0: Register device tree
From: Simon Horman @ 2012-11-27  3:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7701261.79JI41uS12@avalon>

On Mon, Nov 26, 2012 at 03:06:37PM +0100, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday 26 November 2012 09:16:51 Simon Horman wrote:
> > Register the pfc with sh73a0_init_gpio_dt() to allow
> > gpios provided by pfc to be accessed by devices which
> > are registered using device tree.
> > 
> > The motivation of this is to allow the gpio used for carrier detect
> > but the Micro SD SDHI port of the KZM-9A-GT board to be accessed
> > using device tree. Thus, allowing the SDHI device of the KZM-9A-GT
> > board to be registered using device tree.
> > 
> > Signed-off-by: Simon Horman <horms@verge.net.au>
> > ---
> >  arch/arm/mach-shmobile/pfc-sh73a0.c |   45 ++++++++++++++++++++++++++++++++
> >  1 file changed, 45 insertions(+)
> > 
> > diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c
> > b/arch/arm/mach-shmobile/pfc-sh73a0.c index b442f9d..d1a04c0b 100644
> > --- a/arch/arm/mach-shmobile/pfc-sh73a0.c
> > +++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
> > @@ -2797,7 +2797,52 @@ static struct pinmux_info sh73a0_pinmux_info = {
> >  	.gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
> >  };
> > 
> > +#ifdef CONFIG_OF_GPIO
> > +static int sh73a0_gpio_xlate(struct gpio_chip *gc,
> > +			     const struct of_phandle_args *gpiospec,
> > +			     u32 *flags)
> > +{
> > +	if (WARN_ON(gc->of_gpio_n_cells < 2))
> > +		return -EINVAL;
> > +
> > +	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
> > +		return -EINVAL;
> > +
> > +	if (gpiospec->args[0] > gc->ngpio)
> > +		return -EINVAL;
> > +
> > +	if (flags)
> > +		*flags = gpiospec->args[1];
> > +
> > +	return gpiospec->args[0];
> > +}
> 
> Is there any reason not to use of_gpio_simple_xlate here ? If there isn't, 
> of_xlate and of_gpio_n_cells default to of_gpio_simple_xlate and 2 
> respectively when of_xlate isn't specified, so you could omit both.

No reason other than that I wasn't aware of of_gpio_simple_xlate.

^ permalink raw reply

* [PATCH] Update ARM/SHMOBILE section of MAINTAINERS
From: Simon Horman @ 2012-11-27  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

From: Simon Horman <horms+renesas@verge.net.au>

I have been handling maintenance of shmobile
for a little over a release-cycle now and it seems
to appropriate to update the MAINTAINERS file accordingly.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 MAINTAINERS |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index e73060f..056200c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1114,12 +1114,12 @@ S:	Maintained
 F:	drivers/media/platform/s5p-tv/
 
 ARM/SHMOBILE ARM ARCHITECTURE
-M:	Paul Mundt <lethal@linux-sh.org>
+M:	Simon Horman <horms@verge.net.au>
 M:	Magnus Damm <magnus.damm@gmail.com>
 L:	linux-sh@vger.kernel.org
 W:	http://oss.renesas.com
 Q:	http://patchwork.kernel.org/project/linux-sh/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git rmobile-latest
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next
 S:	Supported
 F:	arch/arm/mach-shmobile/
 F:	drivers/sh/
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH v3 11/12] memory-hotplug: remove sysfs file of node
From: Wen Congyang @ 2012-11-27  2:24 UTC (permalink / raw)
  To: Jianguo Wu
  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,
	Jianguo Wu
In-Reply-To: <50B37C52.2060301@gmail.com>

At 11/26/2012 10:27 PM, Jianguo Wu Wrote:
> On 2012/11/1 17:44, Wen Congyang wrote:
>> This patch introduces a new function try_offline_node() to
>> remove sysfs file of node when all memory sections of this
>> node are removed. If some memory sections of this node are
>> not removed, this function does nothing.
>>
>> CC: David Rientjes <rientjes@google.com>
>> CC: Jiang Liu <liuj97@gmail.com>
>> CC: Len Brown <len.brown@intel.com>
>> CC: Christoph Lameter <cl@linux.com>
>> Cc: Minchan Kim <minchan.kim@gmail.com>
>> CC: Andrew Morton <akpm@linux-foundation.org>
>> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>> CC: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>>  drivers/acpi/acpi_memhotplug.c |  8 +++++-
>>  include/linux/memory_hotplug.h |  2 +-
>>  mm/memory_hotplug.c            | 58 ++++++++++++++++++++++++++++++++++++++++--
>>  3 files changed, 64 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
>> index 24c807f..0780f99 100644
>> --- a/drivers/acpi/acpi_memhotplug.c
>> +++ b/drivers/acpi/acpi_memhotplug.c
>> @@ -310,7 +310,9 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
>>  {
>>  	int result;
>>  	struct acpi_memory_info *info, *n;
>> +	int node;
>>  
>> +	node = acpi_get_node(mem_device->device->handle);
>>  
>>  	/*
>>  	 * Ask the VM to offline this memory range.
>> @@ -318,7 +320,11 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device)
>>  	 */
>>  	list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
>>  		if (info->enabled) {
>> -			result = remove_memory(info->start_addr, info->length);
>> +			if (node < 0)
>> +				node = memory_add_physaddr_to_nid(
>> +					info->start_addr);
>> +			result = remove_memory(node, info->start_addr,
>> +				info->length);
>>  			if (result)
>>  				return result;
>>  		}
>> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
>> index d4c4402..7b4cfe6 100644
>> --- a/include/linux/memory_hotplug.h
>> +++ b/include/linux/memory_hotplug.h
>> @@ -231,7 +231,7 @@ extern int arch_add_memory(int nid, u64 start, u64 size);
>>  extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
>>  extern int offline_memory_block(struct memory_block *mem);
>>  extern bool is_memblock_offlined(struct memory_block *mem);
>> -extern int remove_memory(u64 start, u64 size);
>> +extern int remove_memory(int node, u64 start, u64 size);
>>  extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
>>  								int nr_pages);
>>  extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms);
>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>> index 7bcced0..d965da3 100644
>> --- a/mm/memory_hotplug.c
>> +++ b/mm/memory_hotplug.c
>> @@ -29,6 +29,7 @@
>>  #include <linux/suspend.h>
>>  #include <linux/mm_inline.h>
>>  #include <linux/firmware-map.h>
>> +#include <linux/stop_machine.h>
>>  
>>  #include <asm/tlbflush.h>
>>  
>> @@ -1299,7 +1300,58 @@ static int is_memblock_offlined_cb(struct memory_block *mem, void *arg)
>>  	return ret;
>>  }
>>  
>> -int __ref remove_memory(u64 start, u64 size)
>> +static int check_cpu_on_node(void *data)
>> +{
>> +	struct pglist_data *pgdat = data;
>> +	int cpu;
>> +
>> +	for_each_present_cpu(cpu) {
>> +		if (cpu_to_node(cpu) = pgdat->node_id)
>> +			/*
>> +			 * the cpu on this node isn't removed, and we can't
>> +			 * offline this node.
>> +			 */
>> +			return -EBUSY;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/* offline the node if all memory sections of this node are removed */
>> +static void try_offline_node(int nid)
>> +{
>> +	unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn;
>> +	unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages;
>> +	unsigned long pfn;
>> +
>> +	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
>> +		unsigned long section_nr = pfn_to_section_nr(pfn);
>> +
>> +		if (!present_section_nr(section_nr))
>> +			continue;
>> +
>> +		if (pfn_to_nid(pfn) != nid)
>> +			continue;
>> +
>> +		/*
>> +		 * some memory sections of this node are not removed, and we
>> +		 * can't offline node now.
>> +		 */
>> +		return;
>> +	}
>> +
>> +	if (stop_machine(check_cpu_on_node, NODE_DATA(nid), NULL))
>> +		return;
> 
> how about:
> 	if (nr_cpus_node(nid))

If all cpus on the node is offlined, but not removed, nr_cpus_node(nid) will
return 0. In this case, we still can't offline the node.

Another purpose to use stop_machine() is to prevent cpu hotplug. We can't lock
cpuhotplug here.

Thanks
Wen Congyang

> 		return;
>> +
>> +	/*
>> +	 * all memory/cpu of this node are removed, we can offline this
>> +	 * node now.
>> +	 */
>> +	node_set_offline(nid);
>> +	unregister_one_node(nid);
>> +}
>> +
>> +int __ref remove_memory(int nid, u64 start, u64 size)
>>  {
>>  	unsigned long start_pfn, end_pfn;
>>  	int ret = 0;
>> @@ -1346,6 +1398,8 @@ repeat:
>>  
>>  	arch_remove_memory(start, size);
>>  
>> +	try_offline_node(nid);
>> +
>>  	unlock_memory_hotplug();
>>  
>>  	return 0;
>> @@ -1355,7 +1409,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
>>  {
>>  	return -EINVAL;
>>  }
>> -int remove_memory(u64 start, u64 size)
>> +int remove_memory(int nid, u64 start, u64 size)
>>  {
>>  	return -EINVAL;
>>  }
>>
> 
> 


^ permalink raw reply

* Re: [PATCH v2] sh: clkfwk: bugfix: sh_clk_div_enable() care sh_clk_div_set_rate() if div6
From: Paul Mundt @ 2012-11-27  1:33 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <87a9u4x5q1.wl%kuninori.morimoto.gx@renesas.com>

On Mon, Nov 26, 2012 at 04:45:45PM -0800, Kuninori Morimoto wrote:
> 
> Hi Paul
> 
> > > 764f4e4e33d18cde4dcaf8a0d860b749c6d6d08b
> > > (sh: clkfwk: Use shared sh_clk_div_enable/disable())
> > > shared enable/disable funcions for div4/div6.
> > > But new sh_clk_div_enable() didn't care sh_clk_div_set_rate()
> > > which is required on div6 clock.
> > > This patch fixes it.
> > > 
> > > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> > 
> > Looks better, I'll queue it up, thanks.
> 
> Thanks.
> Is it possible to go to v3.7-rcX ?
> 
Yes, should be fine.

^ permalink raw reply

* Re: [PATCH 1/5] backlight: Add GPIO-based backlight driver
From: Jingoo Han @ 2012-11-27  1:24 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Jingoo Han, Laurent Pinchart, akpm@linux-foundation.org,
	linux-kernel@vger.kernel.org, linux-sh@vger.kernel.org,
	linux-fbdev@vger.kernel.org, Paul Mundt, Magnus Damm,
	Richard Purdie, Kuninori Morimoto
In-Reply-To: <1353688515-30458-2-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

T24gTW9uZGF5LCBOb3ZlbWJlciAyNiwgMjAxMiA3OjI1IFBNLCBMYXVyZW50IFBpbmNoYXJ0IHdy
b3RlDQo+IA0KPiBIaSBKaW5nb28sDQo+IA0KPiBPbiBNb25kYXkgMjYgTm92ZW1iZXIgMjAxMiAw
OTo0OTozNiBKaW5nb28gSGFuIHdyb3RlOg0KPiA+IE9uIFNhdHVyZGF5LCBOb3ZlbWJlciAyNCwg
MjAxMiAxOjM1IEFNLCBMYXVyZW50IFBpbmNoYXJ0IHdyb3RlDQo+ID4gPg0KPiA+ID4gU2lnbmVk
LW9mZi1ieTogTGF1cmVudCBQaW5jaGFydCA8bGF1cmVudC5waW5jaGFydEBpZGVhc29uYm9hcmQu
Y29tPg0KPiA+DQo+ID4gQ0MnZWQgQW5kcmV3IE1vcnRvbg0KPiA+DQo+ID4gSXQgbG9va3MgZ29v
ZC4gQWxzbywgSSB0ZXN0ZWQgdGhpcyBwYXRjaCB3aXRoIFNNREs0MjEwIGJvYXJkLg0KPiA+IEFj
a2VkLWJ5OiBKaW5nb28gSGFuIDxqZzEuaGFuQHNhbXN1bmcuY29tPg0KPiANCj4gVGhhbmsgeW91
Lg0KPiANCj4gVW5sZXNzIFJpY2hhcmQgd2FudHMgdG8gdGFrZSAxLzUgYW5kIDIvNSwgSSBwbGFu
IHRvIHB1c2ggdGhlbSB0aHJvdWdoIGVpdGhlcg0KPiB0aGUgUmVuZXNhcyBBUk0gb3IgUmVuZXNh
cyBTSCB0cmVlIHdpdGggdGhlIGJvYXJkIGNvZGUgcGF0Y2hlcy4NCg0KSGkgTGF1cmVudCwNCg0K
T0ssIEkgc2VlLg0KTWF5YmUgUmljaGFyZCB3b24ndCB0YWtlIDEvNSBhbmQgMi81LiBBcyB5b3Ug
bWVudGlvbmVkLCBpdCB3b3VsZCBiZSBnb29kDQp0byBwdXNoIHRoZW0gdGhyb3VnaG91dCB0aGUg
UmVuZXNhcyB0cmVlIHRvIGF2b2lkIGJpc2VjdGlvbiBicmVha2FnZXMuDQoNCkJlc3QgcmVnYXJk
cywNCkppbmdvbyBIYW4NCg0KDQo


^ permalink raw reply

* Re: [PATCH 1/5] backlight: Add GPIO-based backlight driver
From: Jingoo Han @ 2012-11-27  1:10 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: akpm, linux-kernel, linux-sh@vger.kernel.org,
	linux-fbdev@vger.kernel.org, Paul Mundt, Magnus Damm,
	Richard Purdie, Kuninori Morimoto, Jingoo Han
In-Reply-To: <1353688515-30458-2-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

T24gU2F0dXJkYXksIE5vdmVtYmVyIDI0LCAyMDEyIDE6MzUgQU0sIExhdXJlbnQgUGluY2hhcnQg
d3JvdGUNCj4gDQo+IFNpZ25lZC1vZmYtYnk6IExhdXJlbnQgUGluY2hhcnQgPGxhdXJlbnQucGlu
Y2hhcnRAaWRlYXNvbmJvYXJkLmNvbT4NCj4gLS0tDQo+ICBkcml2ZXJzL3ZpZGVvL2JhY2tsaWdo
dC9LY29uZmlnICAgICAgICAgIHwgICAgNyArKw0KPiAgZHJpdmVycy92aWRlby9iYWNrbGlnaHQv
TWFrZWZpbGUgICAgICAgICB8ICAgIDEgKw0KPiAgZHJpdmVycy92aWRlby9iYWNrbGlnaHQvZ3Bp
b19iYWNrbGlnaHQuYyB8ICAxNTggKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrDQo+ICBp
bmNsdWRlL3ZpZGVvL2dwaW9fYmFja2xpZ2h0LmggICAgICAgICAgIHwgICAyMSArKysrDQo+ICA0
IGZpbGVzIGNoYW5nZWQsIDE4NyBpbnNlcnRpb25zKCspLCAwIGRlbGV0aW9ucygtKQ0KPiAgY3Jl
YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdmlkZW8vYmFja2xpZ2h0L2dwaW9fYmFja2xpZ2h0LmMN
Cj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL3ZpZGVvL2dwaW9fYmFja2xpZ2h0LmgNCg0K
Wy4uLl0NCg0KPiArc3RhdGljIGludCBfX2RldmluaXQgZ3Bpb19iYWNrbGlnaHRfcHJvYmUoc3Ry
dWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4gKwlzdHJ1Y3QgZ3Bpb19iYWNrbGln
aHRfcGxhdGZvcm1fZGF0YSAqcGRhdGEgPSBwZGV2LT5kZXYucGxhdGZvcm1fZGF0YTsNCj4gKwlz
dHJ1Y3QgYmFja2xpZ2h0X3Byb3BlcnRpZXMgcHJvcHM7DQo+ICsJc3RydWN0IGJhY2tsaWdodF9k
ZXZpY2UgKmJsOw0KPiArCXN0cnVjdCBncGlvX2JhY2tsaWdodCAqZ2JsOw0KPiArCWludCByZXQ7
DQo+ICsNCj4gKwlnYmwgPSBkZXZtX2t6YWxsb2MoJnBkZXYtPmRldiwgc2l6ZW9mKCpnYmwpLCBH
RlBfS0VSTkVMKTsNCj4gKwlpZiAoZ2JsID09IE5VTEwpDQo+ICsJCXJldHVybiAtRU5PTUVNOw0K
PiArDQo+ICsJZ2JsLT5kZXYgPSAmcGRldi0+ZGV2Ow0KPiArDQo+ICsJaWYgKCFwZGF0YSkgew0K
PiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWlsZWQgdG8gZmluZCBwbGF0Zm9ybSBkYXRhXG4i
KTsNCj4gKwkJcmV0dXJuIC1FTk9ERVY7DQo+ICsJfQ0KPiArDQo+ICsJZ2JsLT5mYmRldiA9IHBk
YXRhLT5mYmRldjsNCj4gKwlnYmwtPmdwaW8gPSBwZGF0YS0+Z3BpbzsNCj4gKwlnYmwtPmFjdGl2
ZSA9IHBkYXRhLT5hY3RpdmVfbG93ID8gMCA6IDE7DQo+ICsNCj4gKwlyZXQgPSBkZXZtX2dwaW9f
cmVxdWVzdF9vbmUoZ2JsLT5kZXYsIGdibC0+Z3BpbywgR1BJT0ZfRElSX09VVCwNCj4gKwkJCQkg
ICAgcGRhdGEtPm5hbWUpOw0KDQpQbGVhc2UgdXNlIEdQSU9GX0lOSVQgZmxhZ3MgaWYgeW91IHdh
bnQgdG8gdHVybiBvZmYgR1BJTyBiYWNrbGlnaHQuDQpJZiBnYmwtPmFjdGl2ZSBpcyBpbnZlcnRl
ZCwgR1BJT0ZfSU5JVF9ISUdIIGNhbiBiZSB1c2VkIGFzIGJlbG93Og0KDQoJcmV0ID0gZGV2bV9n
cGlvX3JlcXVlc3Rfb25lKGdibC0+ZGV2LCBnYmwtPmdwaW8sDQoJCQkJICAgIEdQSU9GX0RJUl9P
VVQgfCAoZ2JsLT5hY3RpdmUgPw0KCQkJCSAgICBHUElPRl9JTklUX0xPVyA6IEdQSU9GX0lOSVRf
SElHSCksDQoJCQkJICAgIHBkYXRhLT5uYW1lKTsNCg0KQmVzdCByZWdhcmRzLA0KSmluZ29vIEhh
bg0KDQo+ICsJaWYgKHJldCA8IDApIHsNCj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAidW5hYmxl
IHRvIHJlcXVlc3QgR1BJT1xuIik7DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJ
bWVtc2V0KCZwcm9wcywgMCwgc2l6ZW9mKHByb3BzKSk7DQo+ICsJcHJvcHMudHlwZSA9IEJBQ0tM
SUdIVF9SQVc7DQo+ICsJcHJvcHMubWF4X2JyaWdodG5lc3MgPSAxOw0KPiArCWJsID0gYmFja2xp
Z2h0X2RldmljZV9yZWdpc3RlcihkZXZfbmFtZSgmcGRldi0+ZGV2KSwgJnBkZXYtPmRldiwgZ2Js
LA0KPiArCQkJCSAgICAgICAmZ3Bpb19iYWNrbGlnaHRfb3BzLCAmcHJvcHMpOw0KPiArCWlmIChJ
U19FUlIoYmwpKSB7DQo+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgImZhaWxlZCB0byByZWdpc3Rl
ciBiYWNrbGlnaHRcbiIpOw0KPiArCQlyZXR1cm4gUFRSX0VSUihibCk7DQo+ICsJfQ0KPiArDQo+
ICsJYmwtPnByb3BzLmJyaWdodG5lc3MgPSBwZGF0YS0+ZGVmX3ZhbHVlOw0KPiArCWJhY2tsaWdo
dF91cGRhdGVfc3RhdHVzKGJsKTsNCj4gKw0KPiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYs
IGJsKTsNCj4gKwlyZXR1cm4gMDsNCj4gK30NCg0KDQo


^ permalink raw reply

* Re: [PATCH v2] sh: clkfwk: bugfix: sh_clk_div_enable() care sh_clk_div_set_rate() if div6
From: Kuninori Morimoto @ 2012-11-27  0:45 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <87a9u4x5q1.wl%kuninori.morimoto.gx@renesas.com>


Hi Paul

> > 764f4e4e33d18cde4dcaf8a0d860b749c6d6d08b
> > (sh: clkfwk: Use shared sh_clk_div_enable/disable())
> > shared enable/disable funcions for div4/div6.
> > But new sh_clk_div_enable() didn't care sh_clk_div_set_rate()
> > which is required on div6 clock.
> > This patch fixes it.
> > 
> > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> 
> Looks better, I'll queue it up, thanks.

Thanks.
Is it possible to go to v3.7-rcX ?

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* Re: [PATCH 3/7] sh: pfc: Allow device tree registration
From: Simon Horman @ 2012-11-27  0:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528017.UPeIBOTTC7@avalon>

On Tue, Nov 27, 2012 at 01:07:28AM +0100, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday 26 November 2012 09:16:50 Simon Horman wrote:
> > This is a crude mechanism to allow the pfc driver to
> > be registered through device tree. The mofication of this
> > is to provide a way for pfc gpios to be looked up by
> > device tree for devices which use pfc gpios.
> > 
> > More specifically, the motivation is to allow the registration
> > of the card-detect gpio for the Micro-SD SDHI slot of the KZM9G board.
> 
> I've just posted v2 of my PCF patches ("SH pin control and GPIO rework with OF 
> support") that include OF support for GPIOs. This patch as well as patch 4/7 
> and the gpio node in patch 7/7 and shouldn't be required anymore.

Thanks.

^ permalink raw reply

* Re: [PATCH 7/7] ARM: mach-shmobile: kzm9g: Reference DT implementation
From: Simon Horman @ 2012-11-27  0:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50B329B3.8000209@kmckk.co.jp>

On Mon, Nov 26, 2012 at 05:34:59PM +0900, Tetsuyuki Kobayashi wrote:
> Hello Simon-san,
> 
> (2012/11/26 9:16), Simon Horman wrote:
> > 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 devices using device tree
> >    - ST1232 (Touchscreen)
> >    - MMCIF (MMC)
> >    - SDHI (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@verge.net.au>
> > ---
> >   arch/arm/boot/dts/Makefile                     |    3 +-
> >   arch/arm/boot/dts/sh73a0-kzm9g-reference.dts   |  153 ++++++++++++++++++++++++
> >   arch/arm/mach-shmobile/Kconfig                 |   10 ++
> >   arch/arm/mach-shmobile/Makefile                |    8 +-
> >   arch/arm/mach-shmobile/board-kzm9g-reference.c |  142 ++++++++++++++++++++++
> >   5 files changed, 314 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 c1ce813..b6c4fa2 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -75,7 +75,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..978892a
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
> > @@ -0,0 +1,153 @@
> > +/*
> > + * 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/ "skeleton.dtsi"
> > +
> > +/ {
> > +	model = "KZM-A9-GT";
> > +	compatible = "renesas,kzm9g-reference", "renesas,sh73a0";
> > +
> > +	memory {
> > +		device_type = "memory";
> > +		reg = <0x41000000 0x1e800000>;
> > +	};
> > +
> > +	gic: interrupt-controller@f0001000 {
> > +		compatible = "arm,cortex-a9-gic";
> > +		#interrupt-cells = <3>;
> > +		#address-cells = <1>;
> > +		interrupt-controller;
> > +		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 170 0x4>;
> > +	};
> 
> I reported /dev/i2c-0 seems not working. I found the reason.
> About i2c0 interrupt, it should be:
> 
>  		interrupts = <0 167 0x4
> 			      0 168 0x4
> 			      0 169 0x4
>  			      0 170 0x4>;
> 
> The same as i2c1 - ic24. There are 4 interrupts each.

Thanks, sorry for missing that the first time around.

^ permalink raw reply

* Re: [PATCH 0/7] ARM: mach-shmobile: kzm9g: Reference DT implementation
From: Simon Horman @ 2012-11-27  0:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50B307D0.3030800@kmckk.co.jp>

On Mon, Nov 26, 2012 at 03:10:24PM +0900, Tetsuyuki Kobayashi wrote:
> Hello Simon-san,
> 
> (2012/11/26 9:16), Simon Horman wrote:
> 
> > this series is a first pass at providing a refernce DT implementation
> > for the kzm9g baord which is intended to act as a guide for mach-shmobile
> > developers.
> > 
> 
> I tried this patch series on v3.7-rc7 with CONFIG_MACH_KZM9G_REFERENCE=y.
> It boot up correctly with rootfs on SD card. It works good for following devices
>  - serial port on /dev/ttySC4
>  - SD card on /dev/mmcblk0
>  - micro SD card on /dev/mmcblk1
>  - eMMC on /dev/mmcblk2
> 
> I found /dev/i2c-0 seems not to work correctly. "i2cdump" command fails like this.
> 
> # i2cdump 0 0x40
> No size specified (using byte-data access)
> WARNING! This program can confuse your I2C bus, cause data loss and worse!
> I will probe file /dev/i2c-0, address 0x40, mode byte
> Continue? [Y/n]
>      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
> 00: [  180.171875] i2c-sh_mobile i2c-sh_mobile.0: Transfer request timed out
> [  180.187500] i2c-sh_mobile i2c-sh_mobile.0: Polling timed out
> XX [  185.187500] i2c-sh_mobile i2c-sh_mobile.0: Transfer request timed out
> [  185.203125] i2c-sh_mobile i2c-sh_mobile.0: Polling timed out
> XX ^C[  190.203125] i2c-sh_mobile i2c-sh_mobile.0: Transfer request timed out
> [  190.218750] i2c-sh_mobile i2c-sh_mobile.0: Polling timed out
> 
> I quited the command by ^C.
> When I try the same on v3.7-rc7 without CONFIG_MACH_KZM9G_REFERENCE=y
> "i2cdump" command does not time out and shows some data.

Thanks. I found that I had missed two interrupts for
each i2c controller. I will fix this in the next revision.

^ permalink raw reply

* Re: [PATCH 6/7] ARM: mach-shmobile: sh73a0: Minimal setup using DT
From: Simon Horman @ 2012-11-27  0:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <67705146.EhpdzQI6yT@avalon>

On Mon, Nov 26, 2012 at 01:53:06PM +0100, Laurent Pinchart wrote:
> Hi Simon,
> 
> On Monday 26 November 2012 13:58:06 Simon Horman wrote:
> > On Mon, Nov 26, 2012 at 01:23:12PM +0900, Magnus Damm wrote:
> > > On Mon, Nov 26, 2012 at 9:16 AM, Simon Horman <horms@verge.net.au> wrote:
> > > > Allow a minimal setup of the sh73a0 SoC using a flattened device tree.
> > > > 
> > > > * Allow configuration of 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.
> > > > 
> > > > An example dts snuppet follows:
> > > >         i2c0: i2c@0xe6820000 {
> > > >         
> > > >                 #address-cells = <1>;
> > > >                 #size-cells = <0>;
> > > >                 compatible = "renesas,rmobile-iic";
> > > >                 reg = <0xe6820000 0x425>;
> > > >                 interrupt-parent = <&gic>;
> > > >                 interrupts = <0 167 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 44 0x4>;
> > > >                 
> > > >                 touchscreen@55 {
> > > >                 
> > > >                         compatible = "sitronix,st1232";
> > > >                         reg = <0x55>;
> > > >                         interrupt-parent = <&gic>;
> > > >                         interrupts = <0 9 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 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 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 190 0x4>;
> > > >         
> > > >         };
> > > 
> > > Uhm, doesn't the above want to go into sh73a0.dtsi?
> > 
> > There are two things that I am unsure of:
> > 
> > * What should go into sh73a0.dtsi and what should go into
> >   sh73a0-kzm9g-refere3nce.dts.
> > 
> >   The i2c seems like it should go into sh73a0.dtsi as it is part of the
> >   soc. Likewise the interrupt controllers.
> > 
> >   But when it comes to mmcif and sdhi I am less sure. Both of these make use
> >   of regulators. Are the regulators part of the board or the SoC?
> 
> It depends on the regulators. In theory you could have on-SoC regulators that 
> would thus be part of the SoC. In practice I'm not sure how often that 
> happens.
> 
> Most of the regulators are provided by the PMIC, so we can create PMIC-
> specific .dtsi files that would be included by boards. See twl4030.dtsi for an 
> example. Other board-specific regulators, including fixed regulators, should 
> be provided by the board.
> 
> >   If the are part of the board then it makes it more difficult to put mmcif
> >   and sdhi into sh73a0.dtsi as they need to reference the regulators
> >   somehow.
> 
> I think you can split a node across several files. You could have
> 
>         mmcif: mmcif@0x10010000 {
>                 compatible = "renesas,sh-mmcif";
>                 reg = <0xe6bd0000 0x100>;
>                 interrupt-parent = <&gic>;
>                 interrupts = <0 140 0x4
>                               0 141 0x4>;
>                 reg-io-width = <4>;
>         };
> 
> in the SoC .dtsi, and
> 
>         &mmcif {
>                 vmmc-supply = <&fixedregulator1v8>;
>                 vqmmc-supply = <&fixedregulator1v8>;
>         };
> 
> in the board .dts.

Thanks, I discovered that after writing my previous email.
I think it is an approach well suited to the needs of kzm9g
and I intend to use it.

> > * What to do the of_dev_auxdata.
> > 
> >   Currently I add this in patch 4 to the board-kzm9g.c. It is used to force
> >   the name of the i2c, mmcif and sdhi devices in order to allow their clock
> >   lookup to work (though come to think of it it may not be necessary for
> >   mmcif and sdhi).
> 
> Shouldn't clocks be specified as an attribute in DT nodes that reference the 
> clock node ?

Oh, I will look into that.

Magnus's suggestion was to register the names that DT will use
in the clock .c file.

In either case I think we can get rid of auxdata.

> >   In any case, the location of the of_dev_auxdata might be come a bit
> >   tricky if it covers devices in both the board and SoC dts files.

^ permalink raw reply

* Re: [PATCH 3/7] sh: pfc: Allow device tree registration
From: Laurent Pinchart @ 2012-11-27  0:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1353889014-17142-4-git-send-email-horms@verge.net.au>

Hi Simon,

On Monday 26 November 2012 09:16:50 Simon Horman wrote:
> This is a crude mechanism to allow the pfc driver to
> be registered through device tree. The mofication of this
> is to provide a way for pfc gpios to be looked up by
> device tree for devices which use pfc gpios.
> 
> More specifically, the motivation is to allow the registration
> of the card-detect gpio for the Micro-SD SDHI slot of the KZM9G board.

I've just posted v2 of my PCF patches ("SH pin control and GPIO rework with OF 
support") that include OF support for GPIOs. This patch as well as patch 4/7 
and the gpio node in patch 7/7 and shouldn't be required anymore.

> Cc: Paul Mundt <lethal@linux-sh.org>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Simon Horman <horms@verge.net.au>
> ---
>  drivers/sh/pfc/gpio.c  |   15 +++++++++++++++
>  include/linux/sh_pfc.h |    7 +++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/sh/pfc/gpio.c b/drivers/sh/pfc/gpio.c
> index 038fa07..322b927 100644
> --- a/drivers/sh/pfc/gpio.c
> +++ b/drivers/sh/pfc/gpio.c
> @@ -136,6 +136,19 @@ static void sh_pfc_gpio_setup(struct sh_pfc_chip *chip)
> gc->ngpio = (pfc->last_gpio - pfc->first_gpio) + 1;
>  }
> 
> +#ifdef CONFIG_OF_GPIO
> +static void
> +sh_pfc_register_gpiochip_dt(struct sh_pfc *pfc, struct gpio_chip *chip)
> +{
> +	chip->of_node = pfc->of_node;
> +	chip->of_gpio_n_cells = pfc->of_gpio_n_cells;
> +	chip->of_xlate = pfc->of_xlate;
> +}
> +#else
> +static void sh_pfc_register_gpiochip_dt(struct sh_pfc *pfc,
> +					struct gpio_chip *chip) {}
> +#endif
> +
>  int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
>  {
>  	struct sh_pfc_chip *chip;
> @@ -153,6 +166,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
>  	if (unlikely(ret < 0))
>  		kfree(chip);
> 
> +	sh_pfc_register_gpiochip_dt(pfc, &chip->gpio_chip);
> +
>  	pr_info("%s handling gpio %d -> %d\n",
>  		pfc->name, pfc->first_gpio, pfc->last_gpio);
> 
> diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h
> index c19a092..9963370 100644
> --- a/include/linux/sh_pfc.h
> +++ b/include/linux/sh_pfc.h
> @@ -124,6 +124,13 @@ struct sh_pfc {
>  	struct pfc_window *window;
> 
>  	unsigned long unlock_reg;
> +
> +#ifdef CONFIG_OF_GPIO
> +	struct device_node *of_node;
> +	int of_gpio_n_cells;
> +	int (*of_xlate)(struct gpio_chip *gc,
> +		        const struct of_phandle_args *gpiospec, u32 *flags);
> +#endif
>  };
> 
>  /* XXX compat for now */
-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* [PATCH v2 77/77] ARM: shmobile: kzm9g: Add LED1-LED4 to the device tree
From: Laurent Pinchart @ 2012-11-27  0:03 UTC (permalink / raw)
  To: linux-sh

LED1 to LED4 are GPIO LEDs. Add corresponding DT nodes.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/sh73a0-kzm9g.dts |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts
index 7b37901..203efb8 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts
@@ -19,4 +19,20 @@
 		device_type = "memory";
 		reg = <0x41000000 0x1e800000>;
 	};
+
+	leds {
+		compatible = "gpio-leds";
+		led1 {
+			gpios = <&gpio 20 1>; /* Active low */
+		};
+		led2 {
+			gpios = <&gpio 21 1>; /* Active low */
+		};
+		led3 {
+			gpios = <&gpio 22 1>; /* Active low */
+		};
+		led4 {
+			gpios = <&gpio 23 1>; /* Active low */
+		};
+	};
 };
-- 
1.7.8.6


^ permalink raw reply related

* [PATCH v2 76/77] ARM: shmobile: kzm9g: Populate platform devices from device tree
From: Laurent Pinchart @ 2012-11-27  0:03 UTC (permalink / raw)
  To: linux-sh

Call of_platform_populate() at machine initialization time to populate
platform devices. Remove the explicit pinmux initialization as the PFC
device will be instantiated from the device tree.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-kzm9g.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 0a43f31..d23b234 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -29,6 +29,7 @@
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/mfd/tmio.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
@@ -648,7 +649,7 @@ static void __init kzm_init(void)
 				     ARRAY_SIZE(fixed2v8_power_consumers), 2800000);
 	regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
 
-	sh73a0_pinmux_init();
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
 	/* enable SCIFA4 */
 	gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
-- 
1.7.8.6


^ permalink raw reply related

* [PATCH v2 75/77] ARM: shmobile: kzm9g: Add pin control device in device tree
From: Laurent Pinchart @ 2012-11-27  0:03 UTC (permalink / raw)
  To: linux-sh

Add a pfc node in the sh73a0 device tree and include it in kzm9g.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/boot/dts/sh73a0-kzm9g.dts |    2 +-
 arch/arm/boot/dts/sh73a0.dtsi      |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boot/dts/sh73a0.dtsi

diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts
index bcb9119..7b37901 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts
@@ -9,7 +9,7 @@
  */
 
 /dts-v1/;
-/include/ "skeleton.dtsi"
+/include/ "sh73a0.dtsi"
 
 / {
 	model = "KZM-A9-GT";
diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
new file mode 100644
index 0000000..6b374ff
--- /dev/null
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -0,0 +1,32 @@
+/*
+ * 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/ "skeleton.dtsi"
+
+/ {
+	compatible = "renesas,sh73a0";
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,cortex-a9";
+		};
+		cpu@1 {
+			compatible = "arm,cortex-a9";
+		};
+	};
+
+	gpio: pfc@e6050000 {
+		compatible = "renesas,pfc-sh73a0";
+		reg = <0xe6050000 0x8000>,
+		      <0xe605801c 0x1c>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
-- 
1.7.8.6


^ permalink raw reply related

* [PATCH v2 74/77] ARM: shmobile: armadillo: Populate platform devices from device tree
From: Laurent Pinchart @ 2012-11-27  0:03 UTC (permalink / raw)
  To: linux-sh

Call of_platform_populate() at machine initialization time to populate
platform devices. Remove the explicit pinmux initialization as the PFC
device will be instantiated from the device tree.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/board-armadillo800eva.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index 3cc8b1c..ba81519 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/irq.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
@@ -985,7 +986,8 @@ static void __init eva_init(void)
 	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
 				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
 
-	r8a7740_pinmux_init();
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
 	r8a7740_meram_workaround();
 
 	/* SCIFA1 */
-- 
1.7.8.6


^ permalink raw reply related


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