diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 23 |
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. */ |
248 | static void __iomem * | 248 | static void __iomem * |
249 | acpi_map_vaddr_lookup(acpi_physical_address phys, acpi_size size) | 249 | acpi_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. */ |
262 | static struct acpi_ioremap * | 262 | static struct acpi_ioremap * |
263 | acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | 263 | acpi_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; |