diff options
Diffstat (limited to 'drivers/acpi/osl.c')
| -rw-r--r-- | drivers/acpi/osl.c | 28 | 
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a2e844a8e9ed..41168c027a5a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -374,19 +374,21 @@ void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)  }  EXPORT_SYMBOL_GPL(acpi_os_map_memory); -static void acpi_os_drop_map_ref(struct acpi_ioremap *map) +/* Must be called with mutex_lock(&acpi_ioremap_lock) */ +static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map)  { -	if (!--map->refcount) +	unsigned long refcount = --map->refcount; + +	if (!refcount)  		list_del_rcu(&map->list); +	return refcount;  }  static void acpi_os_map_cleanup(struct acpi_ioremap *map)  { -	if (!map->refcount) { -		synchronize_rcu_expedited(); -		acpi_unmap(map->phys, map->virt); -		kfree(map); -	} +	synchronize_rcu_expedited(); +	acpi_unmap(map->phys, map->virt); +	kfree(map);  }  /** @@ -406,6 +408,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)  void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)  {  	struct acpi_ioremap *map; +	unsigned long refcount;  	if (!acpi_permanent_mmap) {  		__acpi_unmap_table(virt, size); @@ -419,10 +422,11 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)  		WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);  		return;  	} -	acpi_os_drop_map_ref(map); +	refcount = acpi_os_drop_map_ref(map);  	mutex_unlock(&acpi_ioremap_lock); -	acpi_os_map_cleanup(map); +	if (!refcount) +		acpi_os_map_cleanup(map);  }  EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); @@ -457,6 +461,7 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)  {  	u64 addr;  	struct acpi_ioremap *map; +	unsigned long refcount;  	if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)  		return; @@ -472,10 +477,11 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *gas)  		mutex_unlock(&acpi_ioremap_lock);  		return;  	} -	acpi_os_drop_map_ref(map); +	refcount = acpi_os_drop_map_ref(map);  	mutex_unlock(&acpi_ioremap_lock); -	acpi_os_map_cleanup(map); +	if (!refcount) +		acpi_os_map_cleanup(map);  }  EXPORT_SYMBOL(acpi_os_unmap_generic_address);  | 
