diff options
-rw-r--r-- | drivers/sn/ioc4.c | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index ea75b3d0612b..67140a5804f5 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/ioc4.h> | 31 | #include <linux/ioc4.h> |
32 | #include <linux/mmtimer.h> | 32 | #include <linux/mmtimer.h> |
33 | #include <linux/rtc.h> | 33 | #include <linux/rtc.h> |
34 | #include <linux/rwsem.h> | 34 | #include <linux/mutex.h> |
35 | #include <asm/sn/addrs.h> | 35 | #include <asm/sn/addrs.h> |
36 | #include <asm/sn/clksupport.h> | 36 | #include <asm/sn/clksupport.h> |
37 | #include <asm/sn/shub_mmr.h> | 37 | #include <asm/sn/shub_mmr.h> |
@@ -54,11 +54,10 @@ | |||
54 | * Submodule management * | 54 | * Submodule management * |
55 | ************************/ | 55 | ************************/ |
56 | 56 | ||
57 | static LIST_HEAD(ioc4_devices); | 57 | static DEFINE_MUTEX(ioc4_mutex); |
58 | static DECLARE_RWSEM(ioc4_devices_rwsem); | ||
59 | 58 | ||
59 | static LIST_HEAD(ioc4_devices); | ||
60 | static LIST_HEAD(ioc4_submodules); | 60 | static LIST_HEAD(ioc4_submodules); |
61 | static DECLARE_RWSEM(ioc4_submodules_rwsem); | ||
62 | 61 | ||
63 | /* Register an IOC4 submodule */ | 62 | /* Register an IOC4 submodule */ |
64 | int | 63 | int |
@@ -66,15 +65,13 @@ ioc4_register_submodule(struct ioc4_submodule *is) | |||
66 | { | 65 | { |
67 | struct ioc4_driver_data *idd; | 66 | struct ioc4_driver_data *idd; |
68 | 67 | ||
69 | down_write(&ioc4_submodules_rwsem); | 68 | mutex_lock(&ioc4_mutex); |
70 | list_add(&is->is_list, &ioc4_submodules); | 69 | list_add(&is->is_list, &ioc4_submodules); |
71 | up_write(&ioc4_submodules_rwsem); | ||
72 | 70 | ||
73 | /* Initialize submodule for each IOC4 */ | 71 | /* Initialize submodule for each IOC4 */ |
74 | if (!is->is_probe) | 72 | if (!is->is_probe) |
75 | return 0; | 73 | goto out; |
76 | 74 | ||
77 | down_read(&ioc4_devices_rwsem); | ||
78 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | 75 | list_for_each_entry(idd, &ioc4_devices, idd_list) { |
79 | if (is->is_probe(idd)) { | 76 | if (is->is_probe(idd)) { |
80 | printk(KERN_WARNING | 77 | printk(KERN_WARNING |
@@ -84,8 +81,8 @@ ioc4_register_submodule(struct ioc4_submodule *is) | |||
84 | pci_name(idd->idd_pdev)); | 81 | pci_name(idd->idd_pdev)); |
85 | } | 82 | } |
86 | } | 83 | } |
87 | up_read(&ioc4_devices_rwsem); | 84 | out: |
88 | 85 | mutex_unlock(&ioc4_mutex); | |
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | 88 | ||
@@ -95,15 +92,13 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) | |||
95 | { | 92 | { |
96 | struct ioc4_driver_data *idd; | 93 | struct ioc4_driver_data *idd; |
97 | 94 | ||
98 | down_write(&ioc4_submodules_rwsem); | 95 | mutex_lock(&ioc4_mutex); |
99 | list_del(&is->is_list); | 96 | list_del(&is->is_list); |
100 | up_write(&ioc4_submodules_rwsem); | ||
101 | 97 | ||
102 | /* Remove submodule for each IOC4 */ | 98 | /* Remove submodule for each IOC4 */ |
103 | if (!is->is_remove) | 99 | if (!is->is_remove) |
104 | return; | 100 | goto out; |
105 | 101 | ||
106 | down_read(&ioc4_devices_rwsem); | ||
107 | list_for_each_entry(idd, &ioc4_devices, idd_list) { | 102 | list_for_each_entry(idd, &ioc4_devices, idd_list) { |
108 | if (is->is_remove(idd)) { | 103 | if (is->is_remove(idd)) { |
109 | printk(KERN_WARNING | 104 | printk(KERN_WARNING |
@@ -113,7 +108,8 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) | |||
113 | pci_name(idd->idd_pdev)); | 108 | pci_name(idd->idd_pdev)); |
114 | } | 109 | } |
115 | } | 110 | } |
116 | up_read(&ioc4_devices_rwsem); | 111 | out: |
112 | mutex_unlock(&ioc4_mutex); | ||
117 | } | 113 | } |
118 | 114 | ||
119 | /********************* | 115 | /********************* |
@@ -312,12 +308,11 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
312 | /* Track PCI-device specific data */ | 308 | /* Track PCI-device specific data */ |
313 | idd->idd_serial_data = NULL; | 309 | idd->idd_serial_data = NULL; |
314 | pci_set_drvdata(idd->idd_pdev, idd); | 310 | pci_set_drvdata(idd->idd_pdev, idd); |
315 | down_write(&ioc4_devices_rwsem); | 311 | |
312 | mutex_lock(&ioc4_mutex); | ||
316 | list_add(&idd->idd_list, &ioc4_devices); | 313 | list_add(&idd->idd_list, &ioc4_devices); |
317 | up_write(&ioc4_devices_rwsem); | ||
318 | 314 | ||
319 | /* Add this IOC4 to all submodules */ | 315 | /* Add this IOC4 to all submodules */ |
320 | down_read(&ioc4_submodules_rwsem); | ||
321 | list_for_each_entry(is, &ioc4_submodules, is_list) { | 316 | list_for_each_entry(is, &ioc4_submodules, is_list) { |
322 | if (is->is_probe && is->is_probe(idd)) { | 317 | if (is->is_probe && is->is_probe(idd)) { |
323 | printk(KERN_WARNING | 318 | printk(KERN_WARNING |
@@ -327,7 +322,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
327 | pci_name(idd->idd_pdev)); | 322 | pci_name(idd->idd_pdev)); |
328 | } | 323 | } |
329 | } | 324 | } |
330 | up_read(&ioc4_submodules_rwsem); | 325 | mutex_unlock(&ioc4_mutex); |
331 | 326 | ||
332 | return 0; | 327 | return 0; |
333 | 328 | ||
@@ -351,7 +346,7 @@ ioc4_remove(struct pci_dev *pdev) | |||
351 | idd = pci_get_drvdata(pdev); | 346 | idd = pci_get_drvdata(pdev); |
352 | 347 | ||
353 | /* Remove this IOC4 from all submodules */ | 348 | /* Remove this IOC4 from all submodules */ |
354 | down_read(&ioc4_submodules_rwsem); | 349 | mutex_lock(&ioc4_mutex); |
355 | list_for_each_entry(is, &ioc4_submodules, is_list) { | 350 | list_for_each_entry(is, &ioc4_submodules, is_list) { |
356 | if (is->is_remove && is->is_remove(idd)) { | 351 | if (is->is_remove && is->is_remove(idd)) { |
357 | printk(KERN_WARNING | 352 | printk(KERN_WARNING |
@@ -361,7 +356,7 @@ ioc4_remove(struct pci_dev *pdev) | |||
361 | pci_name(idd->idd_pdev)); | 356 | pci_name(idd->idd_pdev)); |
362 | } | 357 | } |
363 | } | 358 | } |
364 | up_read(&ioc4_submodules_rwsem); | 359 | mutex_unlock(&ioc4_mutex); |
365 | 360 | ||
366 | /* Release resources */ | 361 | /* Release resources */ |
367 | iounmap(idd->idd_misc_regs); | 362 | iounmap(idd->idd_misc_regs); |
@@ -377,9 +372,9 @@ ioc4_remove(struct pci_dev *pdev) | |||
377 | pci_disable_device(pdev); | 372 | pci_disable_device(pdev); |
378 | 373 | ||
379 | /* Remove and free driver data */ | 374 | /* Remove and free driver data */ |
380 | down_write(&ioc4_devices_rwsem); | 375 | mutex_lock(&ioc4_mutex); |
381 | list_del(&idd->idd_list); | 376 | list_del(&idd->idd_list); |
382 | up_write(&ioc4_devices_rwsem); | 377 | mutex_unlock(&ioc4_mutex); |
383 | kfree(idd); | 378 | kfree(idd); |
384 | } | 379 | } |
385 | 380 | ||