diff options
author | Kai Jiang <Kai.Jiang@freescale.com> | 2011-10-17 14:50:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-10-18 14:18:57 -0400 |
commit | 27a90700a4275c5178b883b65927affdafa5185c (patch) | |
tree | d140a0c39bc0bf68531a165e0678be58987d2d78 /drivers/uio | |
parent | c4253cb0748cd50060d04d838c38b07f1ad0e6e5 (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>
Diffstat (limited to 'drivers/uio')
-rw-r--r-- | drivers/uio/uio.c | 7 |
1 files changed, 3 insertions, 4 deletions
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 | ||
70 | static ssize_t map_addr_show(struct uio_mem *mem, char *buf) | 70 | static 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 | ||
75 | static ssize_t map_size_show(struct uio_mem *mem, char *buf) | 75 | static 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 | ||
80 | static ssize_t map_offset_show(struct uio_mem *mem, char *buf) | 80 | static 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 | ||
85 | struct map_sysfs_entry { | 85 | struct 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; |