aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r--drivers/acpi/osl.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index c63d4cb37dab..32826893c2e6 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -244,13 +244,13 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
244 } 244 }
245} 245}
246 246
247/* Must be called with 'acpi_ioremap_lock' lock held. */ 247/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
248static void __iomem * 248static void __iomem *
249acpi_map_vaddr_lookup(acpi_physical_address phys, acpi_size size) 249acpi_map_vaddr_lookup(acpi_physical_address phys, acpi_size size)
250{ 250{
251 struct acpi_ioremap *map; 251 struct acpi_ioremap *map;
252 252
253 list_for_each_entry(map, &acpi_ioremaps, list) 253 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
254 if (map->phys <= phys && 254 if (map->phys <= phys &&
255 phys + size <= map->phys + map->size) 255 phys + size <= map->phys + map->size)
256 return map->virt + (phys - map->phys); 256 return map->virt + (phys - map->phys);
@@ -258,13 +258,13 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, acpi_size size)
258 return NULL; 258 return NULL;
259} 259}
260 260
261/* Must be called with 'acpi_ioremap_lock' lock held. */ 261/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
262static struct acpi_ioremap * 262static struct acpi_ioremap *
263acpi_map_lookup_virt(void __iomem *virt, acpi_size size) 263acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
264{ 264{
265 struct acpi_ioremap *map; 265 struct acpi_ioremap *map;
266 266
267 list_for_each_entry(map, &acpi_ioremaps, list) 267 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
268 if (map->virt == virt && map->size == size) 268 if (map->virt == virt && map->size == size)
269 return map; 269 return map;
270 270
@@ -302,7 +302,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
302 map->size = size; 302 map->size = size;
303 303
304 spin_lock_irqsave(&acpi_ioremap_lock, flags); 304 spin_lock_irqsave(&acpi_ioremap_lock, flags);
305 list_add_tail(&map->list, &acpi_ioremaps); 305 list_add_tail_rcu(&map->list, &acpi_ioremaps);
306 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 306 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
307 307
308 return virt; 308 return virt;
@@ -328,9 +328,10 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
328 return; 328 return;
329 } 329 }
330 330
331 list_del(&map->list); 331 list_del_rcu(&map->list);
332 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 332 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
333 333
334 synchronize_rcu();
334 iounmap(map->virt); 335 iounmap(map->virt);
335 kfree(map); 336 kfree(map);
336} 337}
@@ -584,11 +585,10 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
584 u32 dummy; 585 u32 dummy;
585 void __iomem *virt_addr; 586 void __iomem *virt_addr;
586 int size = width / 8, unmap = 0; 587 int size = width / 8, unmap = 0;
587 unsigned long flags;
588 588
589 spin_lock_irqsave(&acpi_ioremap_lock, flags); 589 rcu_read_lock();
590 virt_addr = acpi_map_vaddr_lookup(phys_addr, size); 590 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
591 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 591 rcu_read_unlock();
592 if (!virt_addr) { 592 if (!virt_addr) {
593 virt_addr = ioremap(phys_addr, size); 593 virt_addr = ioremap(phys_addr, size);
594 unmap = 1; 594 unmap = 1;
@@ -621,11 +621,10 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
621{ 621{
622 void __iomem *virt_addr; 622 void __iomem *virt_addr;
623 int size = width / 8, unmap = 0; 623 int size = width / 8, unmap = 0;
624 unsigned long flags;
625 624
626 spin_lock_irqsave(&acpi_ioremap_lock, flags); 625 rcu_read_lock();
627 virt_addr = acpi_map_vaddr_lookup(phys_addr, size); 626 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
628 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 627 rcu_read_unlock();
629 if (!virt_addr) { 628 if (!virt_addr) {
630 virt_addr = ioremap(phys_addr, size); 629 virt_addr = ioremap(phys_addr, size);
631 unmap = 1; 630 unmap = 1;