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 | ||
