aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Jiang <Kai.Jiang@freescale.com>2011-10-17 14:50:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-18 14:18:57 -0400
commit27a90700a4275c5178b883b65927affdafa5185c (patch)
treed140a0c39bc0bf68531a165e0678be58987d2d78
parentc4253cb0748cd50060d04d838c38b07f1ad0e6e5 (diff)
uio: Support physical addresses >32 bits on 32-bit systems
To support >32-bit physical addresses for UIO_MEM_PHYS type we need to extend the width of 'addr' in struct uio_mem. Numerous platforms like embedded PPC, ARM, and X86 have support for systems with larger physical address than logical. Since 'addr' may contain a physical, logical, or virtual address the easiest solution is to just change the type to 'phys_addr_t' which should always be greater than or equal to the sizeof(void *) such that it can properly hold any of the address types. For physical address we can support up to a 44-bit physical address on a typical 32-bit system as we utilize remap_pfn_range() for the mapping of the memory region and pfn's are represnted by shifting the address by the page size (typically 4k). Signed-off-by: Kai Jiang <Kai.Jiang@freescale.com> Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Hans J. Koch <hjk@hansjkoch.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/DocBook/uio-howto.tmpl2
-rw-r--r--drivers/uio/uio.c7
-rw-r--r--include/linux/uio_driver.h7
3 files changed, 9 insertions, 7 deletions
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 7c4b514d62b1..54883de5d5f9 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -529,7 +529,7 @@ memory (e.g. allocated with <function>kmalloc()</function>). There's also
529</para></listitem> 529</para></listitem>
530 530
531<listitem><para> 531<listitem><para>
532<varname>unsigned long addr</varname>: Required if the mapping is used. 532<varname>phys_addr_t addr</varname>: Required if the mapping is used.
533Fill in the address of your memory block. This address is the one that 533Fill in the address of your memory block. This address is the one that
534appears in sysfs. 534appears in sysfs.
535</para></listitem> 535</para></listitem>
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index c89f12a8b116..a783d533a1a6 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -69,7 +69,7 @@ static ssize_t map_name_show(struct uio_mem *mem, char *buf)
69 69
70static ssize_t map_addr_show(struct uio_mem *mem, char *buf) 70static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
71{ 71{
72 return sprintf(buf, "0x%lx\n", mem->addr); 72 return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr);
73} 73}
74 74
75static ssize_t map_size_show(struct uio_mem *mem, char *buf) 75static ssize_t map_size_show(struct uio_mem *mem, char *buf)
@@ -79,7 +79,7 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf)
79 79
80static ssize_t map_offset_show(struct uio_mem *mem, char *buf) 80static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
81{ 81{
82 return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK); 82 return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr & ~PAGE_MASK);
83} 83}
84 84
85struct map_sysfs_entry { 85struct map_sysfs_entry {
@@ -634,8 +634,7 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
634 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) 634 if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
635 page = virt_to_page(idev->info->mem[mi].addr + offset); 635 page = virt_to_page(idev->info->mem[mi].addr + offset);
636 else 636 else
637 page = vmalloc_to_page((void *)idev->info->mem[mi].addr 637 page = vmalloc_to_page((void *)(unsigned long)idev->info->mem[mi].addr + offset);
638 + offset);
639 get_page(page); 638 get_page(page);
640 vmf->page = page; 639 vmf->page = page;
641 return 0; 640 return 0;
diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
index 665517c05eaf..fd99ff9298c6 100644
--- a/include/linux/uio_driver.h
+++ b/include/linux/uio_driver.h
@@ -23,7 +23,10 @@ struct uio_map;
23/** 23/**
24 * struct uio_mem - description of a UIO memory region 24 * struct uio_mem - description of a UIO memory region
25 * @name: name of the memory region for identification 25 * @name: name of the memory region for identification
26 * @addr: address of the device's memory 26 * @addr: address of the device's memory (phys_addr is used since
27 * addr can be logical, virtual, or physical & phys_addr_t
28 * should always be large enough to handle any of the
29 * address types)
27 * @size: size of IO 30 * @size: size of IO
28 * @memtype: type of memory addr points to 31 * @memtype: type of memory addr points to
29 * @internal_addr: ioremap-ped version of addr, for driver internal use 32 * @internal_addr: ioremap-ped version of addr, for driver internal use
@@ -31,7 +34,7 @@ struct uio_map;
31 */ 34 */
32struct uio_mem { 35struct uio_mem {
33 const char *name; 36 const char *name;
34 unsigned long addr; 37 phys_addr_t addr;
35 unsigned long size; 38 unsigned long size;
36 int memtype; 39 int memtype;
37 void __iomem *internal_addr; 40 void __iomem *internal_addr;