aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/io-mapping.h
diff options
context:
space:
mode:
authorVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>2009-02-24 20:35:12 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-25 07:09:51 -0500
commit4ab0d47d0ab311eb181532c1ecb6d02905685071 (patch)
tree48b1a6cc01b65bab1442e05a971220366f998976 /include/linux/io-mapping.h
parent6644107d57a8fa82b47e4c55da4d9d91a612f29c (diff)
gpu/drm, x86, PAT: io_mapping_create_wc and resource_size_t
io_mapping_create_wc should take a resource_size_t parameter in place of unsigned long. With unsigned long, there will be no way to map greater than 4GB address in i386/32 bit. On x86, greater than 4GB addresses cannot be mapped on i386 without PAE. Return error for such a case. Patch also adds a structure for io_mapping, that saves the base, size and type on HAVE_ATOMIC_IOMAP archs, that can be used to verify the offset on io_mapping_map calls. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Eric Anholt <eric@anholt.net> Cc: Keith Packard <keithp@keithp.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/io-mapping.h')
-rw-r--r--include/linux/io-mapping.h46
1 files changed, 35 insertions, 11 deletions
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index 82df31726a54..cbc2f0cd631b 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -30,11 +30,14 @@
30 * See Documentation/io_mapping.txt 30 * See Documentation/io_mapping.txt
31 */ 31 */
32 32
33/* this struct isn't actually defined anywhere */
34struct io_mapping;
35
36#ifdef CONFIG_HAVE_ATOMIC_IOMAP 33#ifdef CONFIG_HAVE_ATOMIC_IOMAP
37 34
35struct io_mapping {
36 resource_size_t base;
37 unsigned long size;
38 pgprot_t prot;
39};
40
38/* 41/*
39 * For small address space machines, mapping large objects 42 * For small address space machines, mapping large objects
40 * into the kernel virtual space isn't practical. Where 43 * into the kernel virtual space isn't practical. Where
@@ -43,23 +46,40 @@ struct io_mapping;
43 */ 46 */
44 47
45static inline struct io_mapping * 48static inline struct io_mapping *
46io_mapping_create_wc(unsigned long base, unsigned long size) 49io_mapping_create_wc(resource_size_t base, unsigned long size)
47{ 50{
48 return (struct io_mapping *) base; 51 struct io_mapping *iomap;
52
53 if (!is_io_mapping_possible(base, size))
54 return NULL;
55
56 iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
57 if (!iomap)
58 return NULL;
59
60 iomap->base = base;
61 iomap->size = size;
62 iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL));
63 return iomap;
49} 64}
50 65
51static inline void 66static inline void
52io_mapping_free(struct io_mapping *mapping) 67io_mapping_free(struct io_mapping *mapping)
53{ 68{
69 kfree(mapping);
54} 70}
55 71
56/* Atomic map/unmap */ 72/* Atomic map/unmap */
57static inline void * 73static inline void *
58io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) 74io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
59{ 75{
60 offset += (unsigned long) mapping; 76 resource_size_t phys_addr;
61 return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, 77 unsigned long pfn;
62 __pgprot(__PAGE_KERNEL_WC)); 78
79 BUG_ON(offset >= mapping->size);
80 phys_addr = mapping->base + offset;
81 pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
82 return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot);
63} 83}
64 84
65static inline void 85static inline void
@@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr)
71static inline void * 91static inline void *
72io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) 92io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
73{ 93{
74 offset += (unsigned long) mapping; 94 BUG_ON(offset >= mapping->size);
75 return ioremap_wc(offset, PAGE_SIZE); 95 resource_size_t phys_addr = mapping->base + offset;
96 return ioremap_wc(phys_addr, PAGE_SIZE);
76} 97}
77 98
78static inline void 99static inline void
@@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr)
83 104
84#else 105#else
85 106
107/* this struct isn't actually defined anywhere */
108struct io_mapping;
109
86/* Create the io_mapping object*/ 110/* Create the io_mapping object*/
87static inline struct io_mapping * 111static inline struct io_mapping *
88io_mapping_create_wc(unsigned long base, unsigned long size) 112io_mapping_create_wc(resource_size_t base, unsigned long size)
89{ 113{
90 return (struct io_mapping *) ioremap_wc(base, size); 114 return (struct io_mapping *) ioremap_wc(base, size);
91} 115}