diff options
Diffstat (limited to 'drivers/acpi/acpi_ipmi.c')
-rw-r--r-- | drivers/acpi/acpi_ipmi.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index f40acef80269..a6977e12d574 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/ipmi.h> | 39 | #include <linux/ipmi.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/pnp.h> | 41 | #include <linux/pnp.h> |
42 | #include <linux/spinlock.h> | ||
42 | 43 | ||
43 | MODULE_AUTHOR("Zhao Yakui"); | 44 | MODULE_AUTHOR("Zhao Yakui"); |
44 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); | 45 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); |
@@ -57,7 +58,7 @@ struct acpi_ipmi_device { | |||
57 | struct list_head head; | 58 | struct list_head head; |
58 | /* the IPMI request message list */ | 59 | /* the IPMI request message list */ |
59 | struct list_head tx_msg_list; | 60 | struct list_head tx_msg_list; |
60 | struct mutex tx_msg_lock; | 61 | spinlock_t tx_msg_lock; |
61 | acpi_handle handle; | 62 | acpi_handle handle; |
62 | struct pnp_dev *pnp_dev; | 63 | struct pnp_dev *pnp_dev; |
63 | ipmi_user_t user_interface; | 64 | ipmi_user_t user_interface; |
@@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
147 | struct kernel_ipmi_msg *msg; | 148 | struct kernel_ipmi_msg *msg; |
148 | struct acpi_ipmi_buffer *buffer; | 149 | struct acpi_ipmi_buffer *buffer; |
149 | struct acpi_ipmi_device *device; | 150 | struct acpi_ipmi_device *device; |
151 | unsigned long flags; | ||
150 | 152 | ||
151 | msg = &tx_msg->tx_message; | 153 | msg = &tx_msg->tx_message; |
152 | /* | 154 | /* |
@@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
177 | 179 | ||
178 | /* Get the msgid */ | 180 | /* Get the msgid */ |
179 | device = tx_msg->device; | 181 | device = tx_msg->device; |
180 | mutex_lock(&device->tx_msg_lock); | 182 | spin_lock_irqsave(&device->tx_msg_lock, flags); |
181 | device->curr_msgid++; | 183 | device->curr_msgid++; |
182 | tx_msg->tx_msgid = device->curr_msgid; | 184 | tx_msg->tx_msgid = device->curr_msgid; |
183 | mutex_unlock(&device->tx_msg_lock); | 185 | spin_unlock_irqrestore(&device->tx_msg_lock, flags); |
184 | } | 186 | } |
185 | 187 | ||
186 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, | 188 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, |
@@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
242 | int msg_found = 0; | 244 | int msg_found = 0; |
243 | struct acpi_ipmi_msg *tx_msg; | 245 | struct acpi_ipmi_msg *tx_msg; |
244 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; | 246 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; |
247 | unsigned long flags; | ||
245 | 248 | ||
246 | if (msg->user != ipmi_device->user_interface) { | 249 | if (msg->user != ipmi_device->user_interface) { |
247 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " | 250 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " |
@@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
250 | ipmi_free_recv_msg(msg); | 253 | ipmi_free_recv_msg(msg); |
251 | return; | 254 | return; |
252 | } | 255 | } |
253 | mutex_lock(&ipmi_device->tx_msg_lock); | 256 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
254 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { | 257 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { |
255 | if (msg->msgid == tx_msg->tx_msgid) { | 258 | if (msg->msgid == tx_msg->tx_msgid) { |
256 | msg_found = 1; | 259 | msg_found = 1; |
@@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
258 | } | 261 | } |
259 | } | 262 | } |
260 | 263 | ||
261 | mutex_unlock(&ipmi_device->tx_msg_lock); | 264 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
262 | if (!msg_found) { | 265 | if (!msg_found) { |
263 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " | 266 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " |
264 | "returned.\n", msg->msgid); | 267 | "returned.\n", msg->msgid); |
@@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
378 | struct acpi_ipmi_device *ipmi_device = handler_context; | 381 | struct acpi_ipmi_device *ipmi_device = handler_context; |
379 | int err, rem_time; | 382 | int err, rem_time; |
380 | acpi_status status; | 383 | acpi_status status; |
384 | unsigned long flags; | ||
381 | /* | 385 | /* |
382 | * IPMI opregion message. | 386 | * IPMI opregion message. |
383 | * IPMI message is firstly written to the BMC and system software | 387 | * IPMI message is firstly written to the BMC and system software |
@@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
395 | return AE_NO_MEMORY; | 399 | return AE_NO_MEMORY; |
396 | 400 | ||
397 | acpi_format_ipmi_msg(tx_msg, address, value); | 401 | acpi_format_ipmi_msg(tx_msg, address, value); |
398 | mutex_lock(&ipmi_device->tx_msg_lock); | 402 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
399 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); | 403 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); |
400 | mutex_unlock(&ipmi_device->tx_msg_lock); | 404 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
401 | err = ipmi_request_settime(ipmi_device->user_interface, | 405 | err = ipmi_request_settime(ipmi_device->user_interface, |
402 | &tx_msg->addr, | 406 | &tx_msg->addr, |
403 | tx_msg->tx_msgid, | 407 | tx_msg->tx_msgid, |
@@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
413 | status = AE_OK; | 417 | status = AE_OK; |
414 | 418 | ||
415 | end_label: | 419 | end_label: |
416 | mutex_lock(&ipmi_device->tx_msg_lock); | 420 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
417 | list_del(&tx_msg->head); | 421 | list_del(&tx_msg->head); |
418 | mutex_unlock(&ipmi_device->tx_msg_lock); | 422 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
419 | kfree(tx_msg); | 423 | kfree(tx_msg); |
420 | return status; | 424 | return status; |
421 | } | 425 | } |
@@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) | |||
457 | 461 | ||
458 | INIT_LIST_HEAD(&ipmi_device->head); | 462 | INIT_LIST_HEAD(&ipmi_device->head); |
459 | 463 | ||
460 | mutex_init(&ipmi_device->tx_msg_lock); | 464 | spin_lock_init(&ipmi_device->tx_msg_lock); |
461 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); | 465 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); |
462 | ipmi_install_space_handler(ipmi_device); | 466 | ipmi_install_space_handler(ipmi_device); |
463 | 467 | ||