firewire: clean up fw_card reference counting

This is a functionally equivalent replacement of the current reference
counting of struct fw_card instances. It only converts it to common
idioms as suggested by Kristian Høgsberg:
- struct kref replaces atomic_t as the counter.
- wait_for_completion is used to wait for all card users to complete.

BTW, it may make sense to count card->flush_timer and card->work as
card users too.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

+40 -15
+20 -10
drivers/firewire/fw-card.c
··· 16 16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 17 */ 18 18 19 - #include <linux/module.h> 20 - #include <linux/errno.h> 19 + #include <linux/completion.h> 20 + #include <linux/crc-itu-t.h> 21 21 #include <linux/delay.h> 22 22 #include <linux/device.h> 23 + #include <linux/errno.h> 24 + #include <linux/kref.h> 25 + #include <linux/module.h> 23 26 #include <linux/mutex.h> 24 - #include <linux/crc-itu-t.h> 27 + 25 28 #include "fw-transaction.h" 26 29 #include "fw-topology.h" 27 30 #include "fw-device.h" ··· 399 396 { 400 397 static atomic_t index = ATOMIC_INIT(-1); 401 398 402 - atomic_set(&card->device_count, 0); 403 399 card->index = atomic_inc_return(&index); 404 400 card->driver = driver; 405 401 card->device = device; ··· 407 405 card->color = 0; 408 406 card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; 409 407 408 + kref_init(&card->kref); 409 + init_completion(&card->done); 410 410 INIT_LIST_HEAD(&card->transaction_list); 411 411 spin_lock_init(&card->lock); 412 412 setup_timer(&card->flush_timer, ··· 511 507 }; 512 508 513 509 void 510 + fw_card_release(struct kref *kref) 511 + { 512 + struct fw_card *card = container_of(kref, struct fw_card, kref); 513 + 514 + complete(&card->done); 515 + } 516 + 517 + void 514 518 fw_core_remove_card(struct fw_card *card) 515 519 { 516 520 card->driver->update_phy_reg(card, 4, ··· 533 521 card->driver = &dummy_driver; 534 522 535 523 fw_destroy_nodes(card); 536 - /* 537 - * Wait for all device workqueue jobs to finish. Otherwise the 538 - * firewire-core module could be unloaded before the jobs ran. 539 - */ 540 - while (atomic_read(&card->device_count) > 0) 541 - msleep(100); 524 + 525 + /* Wait for all users, especially device workqueue jobs, to finish. */ 526 + fw_card_put(card); 527 + wait_for_completion(&card->done); 542 528 543 529 cancel_delayed_work_sync(&card->work); 544 530 fw_flush_transactions(card);
+2 -3
drivers/firewire/fw-device.c
··· 168 168 fw_node_put(device->node); 169 169 kfree(device->config_rom); 170 170 kfree(device); 171 - atomic_dec(&card->device_count); 171 + fw_card_put(card); 172 172 } 173 173 174 174 int fw_device_enable_phys_dma(struct fw_device *device) ··· 946 946 */ 947 947 device_initialize(&device->device); 948 948 atomic_set(&device->state, FW_DEVICE_INITIALIZING); 949 - atomic_inc(&card->device_count); 950 - device->card = card; 949 + device->card = fw_card_get(card); 951 950 device->node = fw_node_get(node); 952 951 device->node_id = node->node_id; 953 952 device->generation = card->generation;
+18 -2
drivers/firewire/fw-transaction.h
··· 19 19 #ifndef __fw_transaction_h 20 20 #define __fw_transaction_h 21 21 22 + #include <linux/completion.h> 22 23 #include <linux/device.h> 23 24 #include <linux/dma-mapping.h> 24 25 #include <linux/firewire-constants.h> 26 + #include <linux/kref.h> 25 27 #include <linux/list.h> 26 28 #include <linux/spinlock_types.h> 27 29 #include <linux/timer.h> 28 30 #include <linux/workqueue.h> 29 - #include <asm/atomic.h> 30 31 31 32 #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) 32 33 #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) ··· 220 219 struct fw_card { 221 220 const struct fw_card_driver *driver; 222 221 struct device *device; 223 - atomic_t device_count; 222 + struct kref kref; 223 + struct completion done; 224 224 225 225 int node_id; 226 226 int generation; ··· 261 259 int bm_retries; 262 260 int bm_generation; 263 261 }; 262 + 263 + static inline struct fw_card *fw_card_get(struct fw_card *card) 264 + { 265 + kref_get(&card->kref); 266 + 267 + return card; 268 + } 269 + 270 + void fw_card_release(struct kref *kref); 271 + 272 + static inline void fw_card_put(struct fw_card *card) 273 + { 274 + kref_put(&card->kref, fw_card_release); 275 + } 264 276 265 277 /* 266 278 * The iso packet format allows for an immediate header/payload part