aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sn/ioc4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sn/ioc4.c')
-rw-r--r--drivers/sn/ioc4.c41
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
57static LIST_HEAD(ioc4_devices); 57static DEFINE_MUTEX(ioc4_mutex);
58static DECLARE_RWSEM(ioc4_devices_rwsem);
59 58
59static LIST_HEAD(ioc4_devices);
60static LIST_HEAD(ioc4_submodules); 60static LIST_HEAD(ioc4_submodules);
61static DECLARE_RWSEM(ioc4_submodules_rwsem);
62 61
63/* Register an IOC4 submodule */ 62/* Register an IOC4 submodule */
64int 63int
@@ -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