~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/logic_iomem.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /lib/logic_iomem.c (Version linux-6.12-rc7) and /lib/logic_iomem.c (Version linux-4.11.12)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * Copyright (C) 2021 Intel Corporation           
  4  * Author: Johannes Berg <johannes@sipsolution    
  5  */                                               
  6 #include <linux/types.h>                          
  7 #include <linux/slab.h>                           
  8 #include <linux/logic_iomem.h>                    
  9 #include <asm/io.h>                               
 10                                                   
 11 struct logic_iomem_region {                       
 12         const struct resource *res;               
 13         const struct logic_iomem_region_ops *o    
 14         struct list_head list;                    
 15 };                                                
 16                                                   
 17 struct logic_iomem_area {                         
 18         const struct logic_iomem_ops *ops;        
 19         void *priv;                               
 20 };                                                
 21                                                   
 22 #define AREA_SHIFT      24                        
 23 #define MAX_AREA_SIZE   (1 << AREA_SHIFT)         
 24 #define MAX_AREAS       ((1U << 31) / MAX_AREA    
 25 #define AREA_BITS       ((MAX_AREAS - 1) << AR    
 26 #define AREA_MASK       (MAX_AREA_SIZE - 1)       
 27 #ifdef CONFIG_64BIT                               
 28 #define IOREMAP_BIAS    0xDEAD000000000000UL      
 29 #define IOREMAP_MASK    0xFFFFFFFF00000000UL      
 30 #else                                             
 31 #define IOREMAP_BIAS    0x80000000UL              
 32 #define IOREMAP_MASK    0x80000000UL              
 33 #endif                                            
 34                                                   
 35 static DEFINE_MUTEX(regions_mtx);                 
 36 static LIST_HEAD(regions_list);                   
 37 static struct logic_iomem_area mapped_areas[MA    
 38                                                   
 39 int logic_iomem_add_region(struct resource *re    
 40                            const struct logic_    
 41 {                                                 
 42         struct logic_iomem_region *rreg;          
 43         int err;                                  
 44                                                   
 45         if (WARN_ON(!resource || !ops))           
 46                 return -EINVAL;                   
 47                                                   
 48         if (WARN_ON((resource->flags & IORESOU    
 49                 return -EINVAL;                   
 50                                                   
 51         rreg = kzalloc(sizeof(*rreg), GFP_KERN    
 52         if (!rreg)                                
 53                 return -ENOMEM;                   
 54                                                   
 55         err = request_resource(&iomem_resource    
 56         if (err) {                                
 57                 kfree(rreg);                      
 58                 return -ENOMEM;                   
 59         }                                         
 60                                                   
 61         mutex_lock(&regions_mtx);                 
 62         rreg->res = resource;                     
 63         rreg->ops = ops;                          
 64         list_add_tail(&rreg->list, &regions_li    
 65         mutex_unlock(&regions_mtx);               
 66                                                   
 67         return 0;                                 
 68 }                                                 
 69 EXPORT_SYMBOL(logic_iomem_add_region);            
 70                                                   
 71 #ifndef CONFIG_INDIRECT_IOMEM_FALLBACK            
 72 static void __iomem *real_ioremap(phys_addr_t     
 73 {                                                 
 74         WARN(1, "invalid ioremap(0x%llx, 0x%zx    
 75              (unsigned long long)offset, size)    
 76         return NULL;                              
 77 }                                                 
 78                                                   
 79 static void real_iounmap(volatile void __iomem    
 80 {                                                 
 81         WARN(1, "invalid iounmap for addr 0x%l    
 82              (unsigned long long)(uintptr_t __    
 83 }                                                 
 84 #endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */       
 85                                                   
 86 void __iomem *ioremap(phys_addr_t offset, size    
 87 {                                                 
 88         void __iomem *ret = NULL;                 
 89         struct logic_iomem_region *rreg, *foun    
 90         int i;                                    
 91                                                   
 92         mutex_lock(&regions_mtx);                 
 93         list_for_each_entry(rreg, &regions_lis    
 94                 if (rreg->res->start > offset)    
 95                         continue;                 
 96                 if (rreg->res->end < offset +     
 97                         continue;                 
 98                 found = rreg;                     
 99                 break;                            
100         }                                         
101                                                   
102         if (!found)                               
103                 goto out;                         
104                                                   
105         for (i = 0; i < MAX_AREAS; i++) {         
106                 long offs;                        
107                                                   
108                 if (mapped_areas[i].ops)          
109                         continue;                 
110                                                   
111                 offs = rreg->ops->map(offset -    
112                                       size, &m    
113                                       &mapped_    
114                 if (offs < 0) {                   
115                         mapped_areas[i].ops =     
116                         break;                    
117                 }                                 
118                                                   
119                 if (WARN_ON(!mapped_areas[i].o    
120                         mapped_areas[i].ops =     
121                         break;                    
122                 }                                 
123                                                   
124                 ret = (void __iomem *)(IOREMAP    
125                 break;                            
126         }                                         
127 out:                                              
128         mutex_unlock(&regions_mtx);               
129         if (ret)                                  
130                 return ret;                       
131         return real_ioremap(offset, size);        
132 }                                                 
133 EXPORT_SYMBOL(ioremap);                           
134                                                   
135 static inline struct logic_iomem_area *           
136 get_area(const volatile void __iomem *addr)       
137 {                                                 
138         unsigned long a = (unsigned long)addr;    
139         unsigned int idx;                         
140                                                   
141         if (WARN_ON((a & IOREMAP_MASK) != IORE    
142                 return NULL;                      
143                                                   
144         idx = (a & AREA_BITS) >> AREA_SHIFT;      
145                                                   
146         if (mapped_areas[idx].ops)                
147                 return &mapped_areas[idx];        
148                                                   
149         return NULL;                              
150 }                                                 
151                                                   
152 void iounmap(volatile void __iomem *addr)         
153 {                                                 
154         struct logic_iomem_area *area = get_ar    
155                                                   
156         if (!area) {                              
157                 real_iounmap(addr);               
158                 return;                           
159         }                                         
160                                                   
161         if (area->ops->unmap)                     
162                 area->ops->unmap(area->priv);     
163                                                   
164         mutex_lock(&regions_mtx);                 
165         area->ops = NULL;                         
166         area->priv = NULL;                        
167         mutex_unlock(&regions_mtx);               
168 }                                                 
169 EXPORT_SYMBOL(iounmap);                           
170                                                   
171 #ifndef CONFIG_INDIRECT_IOMEM_FALLBACK            
172 #define MAKE_FALLBACK(op, sz)                     
173 static u##sz real_raw_read ## op(const volatil    
174 {                                                 
175         WARN(1, "Invalid read" #op " at addres    
176              (unsigned long long)(uintptr_t __    
177         return (u ## sz)~0ULL;                    
178 }                                                 
179                                                   
180 static void real_raw_write ## op(u ## sz val,     
181                                  volatile void    
182 {                                                 
183         WARN(1, "Invalid writeq" #op " of 0x%l    
184              (unsigned long long)val,             
185              (unsigned long long)(uintptr_t __    
186 }                                                 
187                                                   
188 MAKE_FALLBACK(b, 8);                              
189 MAKE_FALLBACK(w, 16);                             
190 MAKE_FALLBACK(l, 32);                             
191 #ifdef CONFIG_64BIT                               
192 MAKE_FALLBACK(q, 64);                             
193 #endif                                            
194                                                   
195 static void real_memset_io(volatile void __iom    
196 {                                                 
197         WARN(1, "Invalid memset_io at address     
198              (unsigned long long)(uintptr_t __    
199 }                                                 
200                                                   
201 static void real_memcpy_fromio(void *buffer, c    
202                                size_t size)       
203 {                                                 
204         WARN(1, "Invalid memcpy_fromio at addr    
205              (unsigned long long)(uintptr_t __    
206                                                   
207         memset(buffer, 0xff, size);               
208 }                                                 
209                                                   
210 static void real_memcpy_toio(volatile void __i    
211                              size_t size)         
212 {                                                 
213         WARN(1, "Invalid memcpy_toio at addres    
214              (unsigned long long)(uintptr_t __    
215 }                                                 
216 #endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */       
217                                                   
218 #define MAKE_OP(op, sz)                           
219 u##sz __raw_read ## op(const volatile void __i    
220 {                                                 
221         struct logic_iomem_area *area = get_ar    
222                                                   
223         if (!area)                                
224                 return real_raw_read ## op(add    
225                                                   
226         return (u ## sz) area->ops->read(area-    
227                                          (unsi    
228                                          sz /     
229 }                                                 
230 EXPORT_SYMBOL(__raw_read ## op);                  
231                                                   
232 void __raw_write ## op(u ## sz val, volatile v    
233 {                                                 
234         struct logic_iomem_area *area = get_ar    
235                                                   
236         if (!area) {                              
237                 real_raw_write ## op(val, addr    
238                 return;                           
239         }                                         
240                                                   
241         area->ops->write(area->priv,              
242                          (unsigned long)addr &    
243                          sz / 8, val);            
244 }                                                 
245 EXPORT_SYMBOL(__raw_write ## op)                  
246                                                   
247 MAKE_OP(b, 8);                                    
248 MAKE_OP(w, 16);                                   
249 MAKE_OP(l, 32);                                   
250 #ifdef CONFIG_64BIT                               
251 MAKE_OP(q, 64);                                   
252 #endif                                            
253                                                   
254 void memset_io(volatile void __iomem *addr, in    
255 {                                                 
256         struct logic_iomem_area *area = get_ar    
257         unsigned long offs, start;                
258                                                   
259         if (!area) {                              
260                 real_memset_io(addr, value, si    
261                 return;                           
262         }                                         
263                                                   
264         start = (unsigned long)addr & AREA_MAS    
265                                                   
266         if (area->ops->set) {                     
267                 area->ops->set(area->priv, sta    
268                 return;                           
269         }                                         
270                                                   
271         for (offs = 0; offs < size; offs++)       
272                 area->ops->write(area->priv, s    
273 }                                                 
274 EXPORT_SYMBOL(memset_io);                         
275                                                   
276 void memcpy_fromio(void *buffer, const volatil    
277                    size_t size)                   
278 {                                                 
279         struct logic_iomem_area *area = get_ar    
280         u8 *buf = buffer;                         
281         unsigned long offs, start;                
282                                                   
283         if (!area) {                              
284                 real_memcpy_fromio(buffer, add    
285                 return;                           
286         }                                         
287                                                   
288         start = (unsigned long)addr & AREA_MAS    
289                                                   
290         if (area->ops->copy_from) {               
291                 area->ops->copy_from(area->pri    
292                 return;                           
293         }                                         
294                                                   
295         for (offs = 0; offs < size; offs++)       
296                 buf[offs] = area->ops->read(ar    
297 }                                                 
298 EXPORT_SYMBOL(memcpy_fromio);                     
299                                                   
300 void memcpy_toio(volatile void __iomem *addr,     
301 {                                                 
302         struct logic_iomem_area *area = get_ar    
303         const u8 *buf = buffer;                   
304         unsigned long offs, start;                
305                                                   
306         if (!area) {                              
307                 real_memcpy_toio(addr, buffer,    
308                 return;                           
309         }                                         
310                                                   
311         start = (unsigned long)addr & AREA_MAS    
312                                                   
313         if (area->ops->copy_to) {                 
314                 area->ops->copy_to(area->priv,    
315                 return;                           
316         }                                         
317                                                   
318         for (offs = 0; offs < size; offs++)       
319                 area->ops->write(area->priv, s    
320 }                                                 
321 EXPORT_SYMBOL(memcpy_toio);                       
322                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php