diff options
author | Ming Lei <ming.lei@canonical.com> | 2012-10-09 00:01:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-22 11:37:18 -0400 |
commit | d28d3882bd1fdb88ae4e02f11b091a92b0e5068b (patch) | |
tree | 01c2208e2b5226cf84dc9de4e97456f874fdfa6b /drivers/base | |
parent | 746058f4304343507e48d39f80d7a3b0d8550e3a (diff) |
firmware loader: sync firmware cache by async_synchronize_full_domain
async.c has provided synchronization mechanism on async_schedule_*,
so use async_synchronize_full_domain to sync caching firmware instead
of reinventing the wheel.
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/firmware_class.c | 34 |
1 files changed, 6 insertions, 28 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index a095d84ddfd9..8945f4e489ed 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -116,8 +116,6 @@ struct firmware_cache { | |||
116 | spinlock_t name_lock; | 116 | spinlock_t name_lock; |
117 | struct list_head fw_names; | 117 | struct list_head fw_names; |
118 | 118 | ||
119 | wait_queue_head_t wait_queue; | ||
120 | int cnt; | ||
121 | struct delayed_work work; | 119 | struct delayed_work work; |
122 | 120 | ||
123 | struct notifier_block pm_notify; | 121 | struct notifier_block pm_notify; |
@@ -1166,6 +1164,8 @@ int uncache_firmware(const char *fw_name) | |||
1166 | } | 1164 | } |
1167 | 1165 | ||
1168 | #ifdef CONFIG_PM_SLEEP | 1166 | #ifdef CONFIG_PM_SLEEP |
1167 | static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain); | ||
1168 | |||
1169 | static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) | 1169 | static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) |
1170 | { | 1170 | { |
1171 | struct fw_cache_entry *fce; | 1171 | struct fw_cache_entry *fce; |
@@ -1232,12 +1232,6 @@ static void __async_dev_cache_fw_image(void *fw_entry, | |||
1232 | 1232 | ||
1233 | free_fw_cache_entry(fce); | 1233 | free_fw_cache_entry(fce); |
1234 | } | 1234 | } |
1235 | |||
1236 | spin_lock(&fwc->name_lock); | ||
1237 | fwc->cnt--; | ||
1238 | spin_unlock(&fwc->name_lock); | ||
1239 | |||
1240 | wake_up(&fwc->wait_queue); | ||
1241 | } | 1235 | } |
1242 | 1236 | ||
1243 | /* called with dev->devres_lock held */ | 1237 | /* called with dev->devres_lock held */ |
@@ -1278,7 +1272,6 @@ static void dev_cache_fw_image(struct device *dev, void *data) | |||
1278 | spin_lock(&fwc->name_lock); | 1272 | spin_lock(&fwc->name_lock); |
1279 | /* only one cache entry for one firmware */ | 1273 | /* only one cache entry for one firmware */ |
1280 | if (!__fw_entry_found(fce->name)) { | 1274 | if (!__fw_entry_found(fce->name)) { |
1281 | fwc->cnt++; | ||
1282 | list_add(&fce->list, &fwc->fw_names); | 1275 | list_add(&fce->list, &fwc->fw_names); |
1283 | } else { | 1276 | } else { |
1284 | free_fw_cache_entry(fce); | 1277 | free_fw_cache_entry(fce); |
@@ -1287,8 +1280,9 @@ static void dev_cache_fw_image(struct device *dev, void *data) | |||
1287 | spin_unlock(&fwc->name_lock); | 1280 | spin_unlock(&fwc->name_lock); |
1288 | 1281 | ||
1289 | if (fce) | 1282 | if (fce) |
1290 | async_schedule(__async_dev_cache_fw_image, | 1283 | async_schedule_domain(__async_dev_cache_fw_image, |
1291 | (void *)fce); | 1284 | (void *)fce, |
1285 | &fw_cache_domain); | ||
1292 | } | 1286 | } |
1293 | } | 1287 | } |
1294 | 1288 | ||
@@ -1350,21 +1344,7 @@ static void device_cache_fw_images(void) | |||
1350 | mutex_unlock(&fw_lock); | 1344 | mutex_unlock(&fw_lock); |
1351 | 1345 | ||
1352 | /* wait for completion of caching firmware for all devices */ | 1346 | /* wait for completion of caching firmware for all devices */ |
1353 | spin_lock(&fwc->name_lock); | 1347 | async_synchronize_full_domain(&fw_cache_domain); |
1354 | for (;;) { | ||
1355 | prepare_to_wait(&fwc->wait_queue, &wait, | ||
1356 | TASK_UNINTERRUPTIBLE); | ||
1357 | if (!fwc->cnt) | ||
1358 | break; | ||
1359 | |||
1360 | spin_unlock(&fwc->name_lock); | ||
1361 | |||
1362 | schedule(); | ||
1363 | |||
1364 | spin_lock(&fwc->name_lock); | ||
1365 | } | ||
1366 | spin_unlock(&fwc->name_lock); | ||
1367 | finish_wait(&fwc->wait_queue, &wait); | ||
1368 | 1348 | ||
1369 | loading_timeout = old_timeout; | 1349 | loading_timeout = old_timeout; |
1370 | } | 1350 | } |
@@ -1452,9 +1432,7 @@ static void __init fw_cache_init(void) | |||
1452 | #ifdef CONFIG_PM_SLEEP | 1432 | #ifdef CONFIG_PM_SLEEP |
1453 | spin_lock_init(&fw_cache.name_lock); | 1433 | spin_lock_init(&fw_cache.name_lock); |
1454 | INIT_LIST_HEAD(&fw_cache.fw_names); | 1434 | INIT_LIST_HEAD(&fw_cache.fw_names); |
1455 | fw_cache.cnt = 0; | ||
1456 | 1435 | ||
1457 | init_waitqueue_head(&fw_cache.wait_queue); | ||
1458 | INIT_DELAYED_WORK(&fw_cache.work, | 1436 | INIT_DELAYED_WORK(&fw_cache.work, |
1459 | device_uncache_fw_images_work); | 1437 | device_uncache_fw_images_work); |
1460 | 1438 | ||