diff options
-rw-r--r-- | Documentation/devicetree/bindings/ipmi.txt | 25 | ||||
-rw-r--r-- | drivers/acpi/acpi_pnp.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_bt_sm.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_kcs_sm.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 46 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_powernv.c | 10 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 597 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_sm.h | 10 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_smic_sm.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_ssif.c | 14 | ||||
-rw-r--r-- | include/linux/ipmi_smi.h | 7 |
11 files changed, 437 insertions, 280 deletions
diff --git a/Documentation/devicetree/bindings/ipmi.txt b/Documentation/devicetree/bindings/ipmi.txt new file mode 100644 index 000000000000..d5f1a877ed3e --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | IPMI device | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be one of ipmi-kcs, ipmi-smic, or ipmi-bt | ||
5 | - device_type: should be ipmi | ||
6 | - reg: Address and length of the register set for the device | ||
7 | |||
8 | Optional properties: | ||
9 | - interrupts: The interrupt for the device. Without this the interface | ||
10 | is polled. | ||
11 | - reg-size - The size of the register. Defaults to 1 | ||
12 | - reg-spacing - The number of bytes between register starts. Defaults to 1 | ||
13 | - reg-shift - The amount to shift the registers to the right to get the data | ||
14 | into bit zero. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | smic@fff3a000 { | ||
19 | compatible = "ipmi-smic"; | ||
20 | device_type = "ipmi"; | ||
21 | reg = <0xfff3a000 0x1000>; | ||
22 | interrupts = <0 24 4>; | ||
23 | reg-size = <4>; | ||
24 | reg-spacing = <4>; | ||
25 | }; | ||
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index fb765524cc3d..c58940b231d6 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c | |||
@@ -19,8 +19,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { | |||
19 | {"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */ | 19 | {"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */ |
20 | /* floppy */ | 20 | /* floppy */ |
21 | {"PNP0700"}, | 21 | {"PNP0700"}, |
22 | /* ipmi_si */ | ||
23 | {"IPI0001"}, | ||
24 | /* tpm_inf_pnp */ | 22 | /* tpm_inf_pnp */ |
25 | {"IFX0101"}, /* Infineon TPMs */ | 23 | {"IFX0101"}, /* Infineon TPMs */ |
26 | {"IFX0102"}, /* Infineon TPMs */ | 24 | {"IFX0102"}, /* Infineon TPMs */ |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 61e71616689b..feafdab734ae 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -694,7 +694,7 @@ static int bt_size(void) | |||
694 | return sizeof(struct si_sm_data); | 694 | return sizeof(struct si_sm_data); |
695 | } | 695 | } |
696 | 696 | ||
697 | struct si_sm_handlers bt_smi_handlers = { | 697 | const struct si_sm_handlers bt_smi_handlers = { |
698 | .init_data = bt_init_data, | 698 | .init_data = bt_init_data, |
699 | .start_transaction = bt_start_transaction, | 699 | .start_transaction = bt_start_transaction, |
700 | .get_result = bt_get_result, | 700 | .get_result = bt_get_result, |
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index 8c25f596808a..1da61af7f576 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c | |||
@@ -540,7 +540,7 @@ static void kcs_cleanup(struct si_sm_data *kcs) | |||
540 | { | 540 | { |
541 | } | 541 | } |
542 | 542 | ||
543 | struct si_sm_handlers kcs_smi_handlers = { | 543 | const struct si_sm_handlers kcs_smi_handlers = { |
544 | .init_data = init_kcs_data, | 544 | .init_data = init_kcs_data, |
545 | .start_transaction = start_kcs_transaction, | 545 | .start_transaction = start_kcs_transaction, |
546 | .get_result = get_kcs_result, | 546 | .get_result = get_kcs_result, |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index bf75f6361773..e3536da05c88 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -342,7 +342,7 @@ struct ipmi_smi { | |||
342 | * an umpreemptible region to use this. You must fetch the | 342 | * an umpreemptible region to use this. You must fetch the |
343 | * value into a local variable and make sure it is not NULL. | 343 | * value into a local variable and make sure it is not NULL. |
344 | */ | 344 | */ |
345 | struct ipmi_smi_handlers *handlers; | 345 | const struct ipmi_smi_handlers *handlers; |
346 | void *send_info; | 346 | void *send_info; |
347 | 347 | ||
348 | #ifdef CONFIG_PROC_FS | 348 | #ifdef CONFIG_PROC_FS |
@@ -744,7 +744,13 @@ static void deliver_response(struct ipmi_recv_msg *msg) | |||
744 | ipmi_inc_stat(intf, unhandled_local_responses); | 744 | ipmi_inc_stat(intf, unhandled_local_responses); |
745 | } | 745 | } |
746 | ipmi_free_recv_msg(msg); | 746 | ipmi_free_recv_msg(msg); |
747 | } else { | 747 | } else if (!oops_in_progress) { |
748 | /* | ||
749 | * If we are running in the panic context, calling the | ||
750 | * receive handler doesn't much meaning and has a deadlock | ||
751 | * risk. At this moment, simply skip it in that case. | ||
752 | */ | ||
753 | |||
748 | ipmi_user_t user = msg->user; | 754 | ipmi_user_t user = msg->user; |
749 | user->handler->ipmi_recv_hndl(msg, user->handler_data); | 755 | user->handler->ipmi_recv_hndl(msg, user->handler_data); |
750 | } | 756 | } |
@@ -1015,7 +1021,7 @@ int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data) | |||
1015 | { | 1021 | { |
1016 | int rv = 0; | 1022 | int rv = 0; |
1017 | ipmi_smi_t intf; | 1023 | ipmi_smi_t intf; |
1018 | struct ipmi_smi_handlers *handlers; | 1024 | const struct ipmi_smi_handlers *handlers; |
1019 | 1025 | ||
1020 | mutex_lock(&ipmi_interfaces_mutex); | 1026 | mutex_lock(&ipmi_interfaces_mutex); |
1021 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { | 1027 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
@@ -1501,7 +1507,7 @@ static struct ipmi_smi_msg *smi_add_send_msg(ipmi_smi_t intf, | |||
1501 | } | 1507 | } |
1502 | 1508 | ||
1503 | 1509 | ||
1504 | static void smi_send(ipmi_smi_t intf, struct ipmi_smi_handlers *handlers, | 1510 | static void smi_send(ipmi_smi_t intf, const struct ipmi_smi_handlers *handlers, |
1505 | struct ipmi_smi_msg *smi_msg, int priority) | 1511 | struct ipmi_smi_msg *smi_msg, int priority) |
1506 | { | 1512 | { |
1507 | int run_to_completion = intf->run_to_completion; | 1513 | int run_to_completion = intf->run_to_completion; |
@@ -2747,7 +2753,7 @@ void ipmi_poll_interface(ipmi_user_t user) | |||
2747 | } | 2753 | } |
2748 | EXPORT_SYMBOL(ipmi_poll_interface); | 2754 | EXPORT_SYMBOL(ipmi_poll_interface); |
2749 | 2755 | ||
2750 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | 2756 | int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, |
2751 | void *send_info, | 2757 | void *send_info, |
2752 | struct ipmi_device_id *device_id, | 2758 | struct ipmi_device_id *device_id, |
2753 | struct device *si_dev, | 2759 | struct device *si_dev, |
@@ -3959,6 +3965,10 @@ free_msg: | |||
3959 | 3965 | ||
3960 | if (!run_to_completion) | 3966 | if (!run_to_completion) |
3961 | spin_lock_irqsave(&intf->xmit_msgs_lock, flags); | 3967 | spin_lock_irqsave(&intf->xmit_msgs_lock, flags); |
3968 | /* | ||
3969 | * We can get an asynchronous event or receive message in addition | ||
3970 | * to commands we send. | ||
3971 | */ | ||
3962 | if (msg == intf->curr_msg) | 3972 | if (msg == intf->curr_msg) |
3963 | intf->curr_msg = NULL; | 3973 | intf->curr_msg = NULL; |
3964 | if (!run_to_completion) | 3974 | if (!run_to_completion) |
@@ -4015,7 +4025,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
4015 | unsigned int *waiting_msgs) | 4025 | unsigned int *waiting_msgs) |
4016 | { | 4026 | { |
4017 | struct ipmi_recv_msg *msg; | 4027 | struct ipmi_recv_msg *msg; |
4018 | struct ipmi_smi_handlers *handlers; | 4028 | const struct ipmi_smi_handlers *handlers; |
4019 | 4029 | ||
4020 | if (intf->in_shutdown) | 4030 | if (intf->in_shutdown) |
4021 | return; | 4031 | return; |
@@ -4082,7 +4092,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
4082 | ipmi_inc_stat(intf, | 4092 | ipmi_inc_stat(intf, |
4083 | retransmitted_ipmb_commands); | 4093 | retransmitted_ipmb_commands); |
4084 | 4094 | ||
4085 | smi_send(intf, intf->handlers, smi_msg, 0); | 4095 | smi_send(intf, handlers, smi_msg, 0); |
4086 | } else | 4096 | } else |
4087 | ipmi_free_smi_msg(smi_msg); | 4097 | ipmi_free_smi_msg(smi_msg); |
4088 | 4098 | ||
@@ -4291,6 +4301,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf, | |||
4291 | 0, 1); /* Don't retry, and don't wait. */ | 4301 | 0, 1); /* Don't retry, and don't wait. */ |
4292 | if (rv) | 4302 | if (rv) |
4293 | atomic_sub(2, &panic_done_count); | 4303 | atomic_sub(2, &panic_done_count); |
4304 | else if (intf->handlers->flush_messages) | ||
4305 | intf->handlers->flush_messages(intf->send_info); | ||
4306 | |||
4294 | while (atomic_read(&panic_done_count) != 0) | 4307 | while (atomic_read(&panic_done_count) != 0) |
4295 | ipmi_poll(intf); | 4308 | ipmi_poll(intf); |
4296 | } | 4309 | } |
@@ -4364,9 +4377,7 @@ static void send_panic_events(char *str) | |||
4364 | /* Interface is not ready. */ | 4377 | /* Interface is not ready. */ |
4365 | continue; | 4378 | continue; |
4366 | 4379 | ||
4367 | intf->run_to_completion = 1; | ||
4368 | /* Send the event announcing the panic. */ | 4380 | /* Send the event announcing the panic. */ |
4369 | intf->handlers->set_run_to_completion(intf->send_info, 1); | ||
4370 | ipmi_panic_request_and_wait(intf, &addr, &msg); | 4381 | ipmi_panic_request_and_wait(intf, &addr, &msg); |
4371 | } | 4382 | } |
4372 | 4383 | ||
@@ -4506,6 +4517,23 @@ static int panic_event(struct notifier_block *this, | |||
4506 | /* Interface is not ready. */ | 4517 | /* Interface is not ready. */ |
4507 | continue; | 4518 | continue; |
4508 | 4519 | ||
4520 | /* | ||
4521 | * If we were interrupted while locking xmit_msgs_lock or | ||
4522 | * waiting_rcv_msgs_lock, the corresponding list may be | ||
4523 | * corrupted. In this case, drop items on the list for | ||
4524 | * the safety. | ||
4525 | */ | ||
4526 | if (!spin_trylock(&intf->xmit_msgs_lock)) { | ||
4527 | INIT_LIST_HEAD(&intf->xmit_msgs); | ||
4528 | INIT_LIST_HEAD(&intf->hp_xmit_msgs); | ||
4529 | } else | ||
4530 | spin_unlock(&intf->xmit_msgs_lock); | ||
4531 | |||
4532 | if (!spin_trylock(&intf->waiting_rcv_msgs_lock)) | ||
4533 | INIT_LIST_HEAD(&intf->waiting_rcv_msgs); | ||
4534 | else | ||
4535 | spin_unlock(&intf->waiting_rcv_msgs_lock); | ||
4536 | |||
4509 | intf->run_to_completion = 1; | 4537 | intf->run_to_completion = 1; |
4510 | intf->handlers->set_run_to_completion(intf->send_info, 1); | 4538 | intf->handlers->set_run_to_completion(intf->send_info, 1); |
4511 | } | 4539 | } |
diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c index 9b409c0f14f7..6e658aa114f1 100644 --- a/drivers/char/ipmi/ipmi_powernv.c +++ b/drivers/char/ipmi/ipmi_powernv.c | |||
@@ -143,8 +143,15 @@ static int ipmi_powernv_recv(struct ipmi_smi_powernv *smi) | |||
143 | pr_devel("%s: -> %d (size %lld)\n", __func__, | 143 | pr_devel("%s: -> %d (size %lld)\n", __func__, |
144 | rc, rc == 0 ? size : 0); | 144 | rc, rc == 0 ? size : 0); |
145 | if (rc) { | 145 | if (rc) { |
146 | /* If came via the poll, and response was not yet ready */ | ||
147 | if (rc == OPAL_EMPTY) { | ||
148 | spin_unlock_irqrestore(&smi->msg_lock, flags); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | smi->cur_msg = NULL; | ||
146 | spin_unlock_irqrestore(&smi->msg_lock, flags); | 153 | spin_unlock_irqrestore(&smi->msg_lock, flags); |
147 | ipmi_free_smi_msg(msg); | 154 | send_error_reply(smi, msg, IPMI_ERR_UNSPECIFIED); |
148 | return 0; | 155 | return 0; |
149 | } | 156 | } |
150 | 157 | ||
@@ -300,7 +307,6 @@ static const struct of_device_id ipmi_powernv_match[] = { | |||
300 | static struct platform_driver powernv_ipmi_driver = { | 307 | static struct platform_driver powernv_ipmi_driver = { |
301 | .driver = { | 308 | .driver = { |
302 | .name = "ipmi-powernv", | 309 | .name = "ipmi-powernv", |
303 | .owner = THIS_MODULE, | ||
304 | .of_match_table = ipmi_powernv_match, | 310 | .of_match_table = ipmi_powernv_match, |
305 | }, | 311 | }, |
306 | .probe = ipmi_powernv_probe, | 312 | .probe = ipmi_powernv_probe, |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 8a45e92ff60c..654f6f36a071 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -64,7 +64,6 @@ | |||
64 | #include <linux/dmi.h> | 64 | #include <linux/dmi.h> |
65 | #include <linux/string.h> | 65 | #include <linux/string.h> |
66 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
67 | #include <linux/pnp.h> | ||
68 | #include <linux/of_device.h> | 67 | #include <linux/of_device.h> |
69 | #include <linux/of_platform.h> | 68 | #include <linux/of_platform.h> |
70 | #include <linux/of_address.h> | 69 | #include <linux/of_address.h> |
@@ -164,7 +163,7 @@ struct smi_info { | |||
164 | int intf_num; | 163 | int intf_num; |
165 | ipmi_smi_t intf; | 164 | ipmi_smi_t intf; |
166 | struct si_sm_data *si_sm; | 165 | struct si_sm_data *si_sm; |
167 | struct si_sm_handlers *handlers; | 166 | const struct si_sm_handlers *handlers; |
168 | enum si_type si_type; | 167 | enum si_type si_type; |
169 | spinlock_t si_lock; | 168 | spinlock_t si_lock; |
170 | struct ipmi_smi_msg *waiting_msg; | 169 | struct ipmi_smi_msg *waiting_msg; |
@@ -263,9 +262,21 @@ struct smi_info { | |||
263 | bool supports_event_msg_buff; | 262 | bool supports_event_msg_buff; |
264 | 263 | ||
265 | /* | 264 | /* |
266 | * Can we clear the global enables receive irq bit? | 265 | * Can we disable interrupts the global enables receive irq |
266 | * bit? There are currently two forms of brokenness, some | ||
267 | * systems cannot disable the bit (which is technically within | ||
268 | * the spec but a bad idea) and some systems have the bit | ||
269 | * forced to zero even though interrupts work (which is | ||
270 | * clearly outside the spec). The next bool tells which form | ||
271 | * of brokenness is present. | ||
267 | */ | 272 | */ |
268 | bool cannot_clear_recv_irq_bit; | 273 | bool cannot_disable_irq; |
274 | |||
275 | /* | ||
276 | * Some systems are broken and cannot set the irq enable | ||
277 | * bit, even if they support interrupts. | ||
278 | */ | ||
279 | bool irq_enable_broken; | ||
269 | 280 | ||
270 | /* | 281 | /* |
271 | * Did we get an attention that we did not handle? | 282 | * Did we get an attention that we did not handle? |
@@ -309,9 +320,6 @@ static int num_force_kipmid; | |||
309 | #ifdef CONFIG_PCI | 320 | #ifdef CONFIG_PCI |
310 | static bool pci_registered; | 321 | static bool pci_registered; |
311 | #endif | 322 | #endif |
312 | #ifdef CONFIG_ACPI | ||
313 | static bool pnp_registered; | ||
314 | #endif | ||
315 | #ifdef CONFIG_PARISC | 323 | #ifdef CONFIG_PARISC |
316 | static bool parisc_registered; | 324 | static bool parisc_registered; |
317 | #endif | 325 | #endif |
@@ -558,13 +566,14 @@ static u8 current_global_enables(struct smi_info *smi_info, u8 base, | |||
558 | if (smi_info->supports_event_msg_buff) | 566 | if (smi_info->supports_event_msg_buff) |
559 | enables |= IPMI_BMC_EVT_MSG_BUFF; | 567 | enables |= IPMI_BMC_EVT_MSG_BUFF; |
560 | 568 | ||
561 | if ((smi_info->irq && !smi_info->interrupt_disabled) || | 569 | if (((smi_info->irq && !smi_info->interrupt_disabled) || |
562 | smi_info->cannot_clear_recv_irq_bit) | 570 | smi_info->cannot_disable_irq) && |
571 | !smi_info->irq_enable_broken) | ||
563 | enables |= IPMI_BMC_RCV_MSG_INTR; | 572 | enables |= IPMI_BMC_RCV_MSG_INTR; |
564 | 573 | ||
565 | if (smi_info->supports_event_msg_buff && | 574 | if (smi_info->supports_event_msg_buff && |
566 | smi_info->irq && !smi_info->interrupt_disabled) | 575 | smi_info->irq && !smi_info->interrupt_disabled && |
567 | 576 | !smi_info->irq_enable_broken) | |
568 | enables |= IPMI_BMC_EVT_MSG_INTR; | 577 | enables |= IPMI_BMC_EVT_MSG_INTR; |
569 | 578 | ||
570 | *irq_on = enables & (IPMI_BMC_EVT_MSG_INTR | IPMI_BMC_RCV_MSG_INTR); | 579 | *irq_on = enables & (IPMI_BMC_EVT_MSG_INTR | IPMI_BMC_RCV_MSG_INTR); |
@@ -928,33 +937,36 @@ static void check_start_timer_thread(struct smi_info *smi_info) | |||
928 | } | 937 | } |
929 | } | 938 | } |
930 | 939 | ||
940 | static void flush_messages(void *send_info) | ||
941 | { | ||
942 | struct smi_info *smi_info = send_info; | ||
943 | enum si_sm_result result; | ||
944 | |||
945 | /* | ||
946 | * Currently, this function is called only in run-to-completion | ||
947 | * mode. This means we are single-threaded, no need for locks. | ||
948 | */ | ||
949 | result = smi_event_handler(smi_info, 0); | ||
950 | while (result != SI_SM_IDLE) { | ||
951 | udelay(SI_SHORT_TIMEOUT_USEC); | ||
952 | result = smi_event_handler(smi_info, SI_SHORT_TIMEOUT_USEC); | ||
953 | } | ||
954 | } | ||
955 | |||
931 | static void sender(void *send_info, | 956 | static void sender(void *send_info, |
932 | struct ipmi_smi_msg *msg) | 957 | struct ipmi_smi_msg *msg) |
933 | { | 958 | { |
934 | struct smi_info *smi_info = send_info; | 959 | struct smi_info *smi_info = send_info; |
935 | enum si_sm_result result; | ||
936 | unsigned long flags; | 960 | unsigned long flags; |
937 | 961 | ||
938 | debug_timestamp("Enqueue"); | 962 | debug_timestamp("Enqueue"); |
939 | 963 | ||
940 | if (smi_info->run_to_completion) { | 964 | if (smi_info->run_to_completion) { |
941 | /* | 965 | /* |
942 | * If we are running to completion, start it and run | 966 | * If we are running to completion, start it. Upper |
943 | * transactions until everything is clear. | 967 | * layer will call flush_messages to clear it out. |
944 | */ | 968 | */ |
945 | smi_info->waiting_msg = msg; | 969 | smi_info->waiting_msg = msg; |
946 | |||
947 | /* | ||
948 | * Run to completion means we are single-threaded, no | ||
949 | * need for locks. | ||
950 | */ | ||
951 | |||
952 | result = smi_event_handler(smi_info, 0); | ||
953 | while (result != SI_SM_IDLE) { | ||
954 | udelay(SI_SHORT_TIMEOUT_USEC); | ||
955 | result = smi_event_handler(smi_info, | ||
956 | SI_SHORT_TIMEOUT_USEC); | ||
957 | } | ||
958 | return; | 970 | return; |
959 | } | 971 | } |
960 | 972 | ||
@@ -975,17 +987,10 @@ static void sender(void *send_info, | |||
975 | static void set_run_to_completion(void *send_info, bool i_run_to_completion) | 987 | static void set_run_to_completion(void *send_info, bool i_run_to_completion) |
976 | { | 988 | { |
977 | struct smi_info *smi_info = send_info; | 989 | struct smi_info *smi_info = send_info; |
978 | enum si_sm_result result; | ||
979 | 990 | ||
980 | smi_info->run_to_completion = i_run_to_completion; | 991 | smi_info->run_to_completion = i_run_to_completion; |
981 | if (i_run_to_completion) { | 992 | if (i_run_to_completion) |
982 | result = smi_event_handler(smi_info, 0); | 993 | flush_messages(smi_info); |
983 | while (result != SI_SM_IDLE) { | ||
984 | udelay(SI_SHORT_TIMEOUT_USEC); | ||
985 | result = smi_event_handler(smi_info, | ||
986 | SI_SHORT_TIMEOUT_USEC); | ||
987 | } | ||
988 | } | ||
989 | } | 994 | } |
990 | 995 | ||
991 | /* | 996 | /* |
@@ -1258,7 +1263,7 @@ static void set_maintenance_mode(void *send_info, bool enable) | |||
1258 | atomic_set(&smi_info->req_events, 0); | 1263 | atomic_set(&smi_info->req_events, 0); |
1259 | } | 1264 | } |
1260 | 1265 | ||
1261 | static struct ipmi_smi_handlers handlers = { | 1266 | static const struct ipmi_smi_handlers handlers = { |
1262 | .owner = THIS_MODULE, | 1267 | .owner = THIS_MODULE, |
1263 | .start_processing = smi_start_processing, | 1268 | .start_processing = smi_start_processing, |
1264 | .get_smi_info = get_smi_info, | 1269 | .get_smi_info = get_smi_info, |
@@ -1267,6 +1272,7 @@ static struct ipmi_smi_handlers handlers = { | |||
1267 | .set_need_watch = set_need_watch, | 1272 | .set_need_watch = set_need_watch, |
1268 | .set_maintenance_mode = set_maintenance_mode, | 1273 | .set_maintenance_mode = set_maintenance_mode, |
1269 | .set_run_to_completion = set_run_to_completion, | 1274 | .set_run_to_completion = set_run_to_completion, |
1275 | .flush_messages = flush_messages, | ||
1270 | .poll = poll, | 1276 | .poll = poll, |
1271 | }; | 1277 | }; |
1272 | 1278 | ||
@@ -1283,14 +1289,14 @@ static int smi_num; /* Used to sequence the SMIs */ | |||
1283 | #define DEFAULT_REGSIZE 1 | 1289 | #define DEFAULT_REGSIZE 1 |
1284 | 1290 | ||
1285 | #ifdef CONFIG_ACPI | 1291 | #ifdef CONFIG_ACPI |
1286 | static bool si_tryacpi = 1; | 1292 | static bool si_tryacpi = true; |
1287 | #endif | 1293 | #endif |
1288 | #ifdef CONFIG_DMI | 1294 | #ifdef CONFIG_DMI |
1289 | static bool si_trydmi = 1; | 1295 | static bool si_trydmi = true; |
1290 | #endif | 1296 | #endif |
1291 | static bool si_tryplatform = 1; | 1297 | static bool si_tryplatform = true; |
1292 | #ifdef CONFIG_PCI | 1298 | #ifdef CONFIG_PCI |
1293 | static bool si_trypci = 1; | 1299 | static bool si_trypci = true; |
1294 | #endif | 1300 | #endif |
1295 | static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS); | 1301 | static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS); |
1296 | static char *si_type[SI_MAX_PARMS]; | 1302 | static char *si_type[SI_MAX_PARMS]; |
@@ -1446,14 +1452,14 @@ static int std_irq_setup(struct smi_info *info) | |||
1446 | return rv; | 1452 | return rv; |
1447 | } | 1453 | } |
1448 | 1454 | ||
1449 | static unsigned char port_inb(struct si_sm_io *io, unsigned int offset) | 1455 | static unsigned char port_inb(const struct si_sm_io *io, unsigned int offset) |
1450 | { | 1456 | { |
1451 | unsigned int addr = io->addr_data; | 1457 | unsigned int addr = io->addr_data; |
1452 | 1458 | ||
1453 | return inb(addr + (offset * io->regspacing)); | 1459 | return inb(addr + (offset * io->regspacing)); |
1454 | } | 1460 | } |
1455 | 1461 | ||
1456 | static void port_outb(struct si_sm_io *io, unsigned int offset, | 1462 | static void port_outb(const struct si_sm_io *io, unsigned int offset, |
1457 | unsigned char b) | 1463 | unsigned char b) |
1458 | { | 1464 | { |
1459 | unsigned int addr = io->addr_data; | 1465 | unsigned int addr = io->addr_data; |
@@ -1461,14 +1467,14 @@ static void port_outb(struct si_sm_io *io, unsigned int offset, | |||
1461 | outb(b, addr + (offset * io->regspacing)); | 1467 | outb(b, addr + (offset * io->regspacing)); |
1462 | } | 1468 | } |
1463 | 1469 | ||
1464 | static unsigned char port_inw(struct si_sm_io *io, unsigned int offset) | 1470 | static unsigned char port_inw(const struct si_sm_io *io, unsigned int offset) |
1465 | { | 1471 | { |
1466 | unsigned int addr = io->addr_data; | 1472 | unsigned int addr = io->addr_data; |
1467 | 1473 | ||
1468 | return (inw(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; | 1474 | return (inw(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; |
1469 | } | 1475 | } |
1470 | 1476 | ||
1471 | static void port_outw(struct si_sm_io *io, unsigned int offset, | 1477 | static void port_outw(const struct si_sm_io *io, unsigned int offset, |
1472 | unsigned char b) | 1478 | unsigned char b) |
1473 | { | 1479 | { |
1474 | unsigned int addr = io->addr_data; | 1480 | unsigned int addr = io->addr_data; |
@@ -1476,14 +1482,14 @@ static void port_outw(struct si_sm_io *io, unsigned int offset, | |||
1476 | outw(b << io->regshift, addr + (offset * io->regspacing)); | 1482 | outw(b << io->regshift, addr + (offset * io->regspacing)); |
1477 | } | 1483 | } |
1478 | 1484 | ||
1479 | static unsigned char port_inl(struct si_sm_io *io, unsigned int offset) | 1485 | static unsigned char port_inl(const struct si_sm_io *io, unsigned int offset) |
1480 | { | 1486 | { |
1481 | unsigned int addr = io->addr_data; | 1487 | unsigned int addr = io->addr_data; |
1482 | 1488 | ||
1483 | return (inl(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; | 1489 | return (inl(addr + (offset * io->regspacing)) >> io->regshift) & 0xff; |
1484 | } | 1490 | } |
1485 | 1491 | ||
1486 | static void port_outl(struct si_sm_io *io, unsigned int offset, | 1492 | static void port_outl(const struct si_sm_io *io, unsigned int offset, |
1487 | unsigned char b) | 1493 | unsigned char b) |
1488 | { | 1494 | { |
1489 | unsigned int addr = io->addr_data; | 1495 | unsigned int addr = io->addr_data; |
@@ -1556,49 +1562,52 @@ static int port_setup(struct smi_info *info) | |||
1556 | return 0; | 1562 | return 0; |
1557 | } | 1563 | } |
1558 | 1564 | ||
1559 | static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset) | 1565 | static unsigned char intf_mem_inb(const struct si_sm_io *io, |
1566 | unsigned int offset) | ||
1560 | { | 1567 | { |
1561 | return readb((io->addr)+(offset * io->regspacing)); | 1568 | return readb((io->addr)+(offset * io->regspacing)); |
1562 | } | 1569 | } |
1563 | 1570 | ||
1564 | static void intf_mem_outb(struct si_sm_io *io, unsigned int offset, | 1571 | static void intf_mem_outb(const struct si_sm_io *io, unsigned int offset, |
1565 | unsigned char b) | 1572 | unsigned char b) |
1566 | { | 1573 | { |
1567 | writeb(b, (io->addr)+(offset * io->regspacing)); | 1574 | writeb(b, (io->addr)+(offset * io->regspacing)); |
1568 | } | 1575 | } |
1569 | 1576 | ||
1570 | static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) | 1577 | static unsigned char intf_mem_inw(const struct si_sm_io *io, |
1578 | unsigned int offset) | ||
1571 | { | 1579 | { |
1572 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1580 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1573 | & 0xff; | 1581 | & 0xff; |
1574 | } | 1582 | } |
1575 | 1583 | ||
1576 | static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, | 1584 | static void intf_mem_outw(const struct si_sm_io *io, unsigned int offset, |
1577 | unsigned char b) | 1585 | unsigned char b) |
1578 | { | 1586 | { |
1579 | writeb(b << io->regshift, (io->addr)+(offset * io->regspacing)); | 1587 | writeb(b << io->regshift, (io->addr)+(offset * io->regspacing)); |
1580 | } | 1588 | } |
1581 | 1589 | ||
1582 | static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) | 1590 | static unsigned char intf_mem_inl(const struct si_sm_io *io, |
1591 | unsigned int offset) | ||
1583 | { | 1592 | { |
1584 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1593 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1585 | & 0xff; | 1594 | & 0xff; |
1586 | } | 1595 | } |
1587 | 1596 | ||
1588 | static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, | 1597 | static void intf_mem_outl(const struct si_sm_io *io, unsigned int offset, |
1589 | unsigned char b) | 1598 | unsigned char b) |
1590 | { | 1599 | { |
1591 | writel(b << io->regshift, (io->addr)+(offset * io->regspacing)); | 1600 | writel(b << io->regshift, (io->addr)+(offset * io->regspacing)); |
1592 | } | 1601 | } |
1593 | 1602 | ||
1594 | #ifdef readq | 1603 | #ifdef readq |
1595 | static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset) | 1604 | static unsigned char mem_inq(const struct si_sm_io *io, unsigned int offset) |
1596 | { | 1605 | { |
1597 | return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1606 | return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift) |
1598 | & 0xff; | 1607 | & 0xff; |
1599 | } | 1608 | } |
1600 | 1609 | ||
1601 | static void mem_outq(struct si_sm_io *io, unsigned int offset, | 1610 | static void mem_outq(const struct si_sm_io *io, unsigned int offset, |
1602 | unsigned char b) | 1611 | unsigned char b) |
1603 | { | 1612 | { |
1604 | writeq(b << io->regshift, (io->addr)+(offset * io->regspacing)); | 1613 | writeq(b << io->regshift, (io->addr)+(offset * io->regspacing)); |
@@ -2233,134 +2242,6 @@ static void spmi_find_bmc(void) | |||
2233 | try_init_spmi(spmi); | 2242 | try_init_spmi(spmi); |
2234 | } | 2243 | } |
2235 | } | 2244 | } |
2236 | |||
2237 | static int ipmi_pnp_probe(struct pnp_dev *dev, | ||
2238 | const struct pnp_device_id *dev_id) | ||
2239 | { | ||
2240 | struct acpi_device *acpi_dev; | ||
2241 | struct smi_info *info; | ||
2242 | struct resource *res, *res_second; | ||
2243 | acpi_handle handle; | ||
2244 | acpi_status status; | ||
2245 | unsigned long long tmp; | ||
2246 | int rv = -EINVAL; | ||
2247 | |||
2248 | acpi_dev = pnp_acpi_device(dev); | ||
2249 | if (!acpi_dev) | ||
2250 | return -ENODEV; | ||
2251 | |||
2252 | info = smi_info_alloc(); | ||
2253 | if (!info) | ||
2254 | return -ENOMEM; | ||
2255 | |||
2256 | info->addr_source = SI_ACPI; | ||
2257 | printk(KERN_INFO PFX "probing via ACPI\n"); | ||
2258 | |||
2259 | handle = acpi_dev->handle; | ||
2260 | info->addr_info.acpi_info.acpi_handle = handle; | ||
2261 | |||
2262 | /* _IFT tells us the interface type: KCS, BT, etc */ | ||
2263 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); | ||
2264 | if (ACPI_FAILURE(status)) { | ||
2265 | dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n"); | ||
2266 | goto err_free; | ||
2267 | } | ||
2268 | |||
2269 | switch (tmp) { | ||
2270 | case 1: | ||
2271 | info->si_type = SI_KCS; | ||
2272 | break; | ||
2273 | case 2: | ||
2274 | info->si_type = SI_SMIC; | ||
2275 | break; | ||
2276 | case 3: | ||
2277 | info->si_type = SI_BT; | ||
2278 | break; | ||
2279 | case 4: /* SSIF, just ignore */ | ||
2280 | rv = -ENODEV; | ||
2281 | goto err_free; | ||
2282 | default: | ||
2283 | dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); | ||
2284 | goto err_free; | ||
2285 | } | ||
2286 | |||
2287 | res = pnp_get_resource(dev, IORESOURCE_IO, 0); | ||
2288 | if (res) { | ||
2289 | info->io_setup = port_setup; | ||
2290 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | ||
2291 | } else { | ||
2292 | res = pnp_get_resource(dev, IORESOURCE_MEM, 0); | ||
2293 | if (res) { | ||
2294 | info->io_setup = mem_setup; | ||
2295 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2296 | } | ||
2297 | } | ||
2298 | if (!res) { | ||
2299 | dev_err(&dev->dev, "no I/O or memory address\n"); | ||
2300 | goto err_free; | ||
2301 | } | ||
2302 | info->io.addr_data = res->start; | ||
2303 | |||
2304 | info->io.regspacing = DEFAULT_REGSPACING; | ||
2305 | res_second = pnp_get_resource(dev, | ||
2306 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? | ||
2307 | IORESOURCE_IO : IORESOURCE_MEM, | ||
2308 | 1); | ||
2309 | if (res_second) { | ||
2310 | if (res_second->start > info->io.addr_data) | ||
2311 | info->io.regspacing = res_second->start - info->io.addr_data; | ||
2312 | } | ||
2313 | info->io.regsize = DEFAULT_REGSPACING; | ||
2314 | info->io.regshift = 0; | ||
2315 | |||
2316 | /* If _GPE exists, use it; otherwise use standard interrupts */ | ||
2317 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); | ||
2318 | if (ACPI_SUCCESS(status)) { | ||
2319 | info->irq = tmp; | ||
2320 | info->irq_setup = acpi_gpe_irq_setup; | ||
2321 | } else if (pnp_irq_valid(dev, 0)) { | ||
2322 | info->irq = pnp_irq(dev, 0); | ||
2323 | info->irq_setup = std_irq_setup; | ||
2324 | } | ||
2325 | |||
2326 | info->dev = &dev->dev; | ||
2327 | pnp_set_drvdata(dev, info); | ||
2328 | |||
2329 | dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n", | ||
2330 | res, info->io.regsize, info->io.regspacing, | ||
2331 | info->irq); | ||
2332 | |||
2333 | rv = add_smi(info); | ||
2334 | if (rv) | ||
2335 | kfree(info); | ||
2336 | |||
2337 | return rv; | ||
2338 | |||
2339 | err_free: | ||
2340 | kfree(info); | ||
2341 | return rv; | ||
2342 | } | ||
2343 | |||
2344 | static void ipmi_pnp_remove(struct pnp_dev *dev) | ||
2345 | { | ||
2346 | struct smi_info *info = pnp_get_drvdata(dev); | ||
2347 | |||
2348 | cleanup_one_si(info); | ||
2349 | } | ||
2350 | |||
2351 | static const struct pnp_device_id pnp_dev_table[] = { | ||
2352 | {"IPI0001", 0}, | ||
2353 | {"", 0}, | ||
2354 | }; | ||
2355 | |||
2356 | static struct pnp_driver ipmi_pnp_driver = { | ||
2357 | .name = DEVICE_NAME, | ||
2358 | .probe = ipmi_pnp_probe, | ||
2359 | .remove = ipmi_pnp_remove, | ||
2360 | .id_table = pnp_dev_table, | ||
2361 | }; | ||
2362 | |||
2363 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | ||
2364 | #endif | 2245 | #endif |
2365 | 2246 | ||
2366 | #ifdef CONFIG_DMI | 2247 | #ifdef CONFIG_DMI |
@@ -2654,7 +2535,7 @@ static void ipmi_pci_remove(struct pci_dev *pdev) | |||
2654 | pci_disable_device(pdev); | 2535 | pci_disable_device(pdev); |
2655 | } | 2536 | } |
2656 | 2537 | ||
2657 | static struct pci_device_id ipmi_pci_devices[] = { | 2538 | static const struct pci_device_id ipmi_pci_devices[] = { |
2658 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, | 2539 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, |
2659 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, | 2540 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, |
2660 | { 0, } | 2541 | { 0, } |
@@ -2669,10 +2550,19 @@ static struct pci_driver ipmi_pci_driver = { | |||
2669 | }; | 2550 | }; |
2670 | #endif /* CONFIG_PCI */ | 2551 | #endif /* CONFIG_PCI */ |
2671 | 2552 | ||
2672 | static const struct of_device_id ipmi_match[]; | ||
2673 | static int ipmi_probe(struct platform_device *dev) | ||
2674 | { | ||
2675 | #ifdef CONFIG_OF | 2553 | #ifdef CONFIG_OF |
2554 | static const struct of_device_id of_ipmi_match[] = { | ||
2555 | { .type = "ipmi", .compatible = "ipmi-kcs", | ||
2556 | .data = (void *)(unsigned long) SI_KCS }, | ||
2557 | { .type = "ipmi", .compatible = "ipmi-smic", | ||
2558 | .data = (void *)(unsigned long) SI_SMIC }, | ||
2559 | { .type = "ipmi", .compatible = "ipmi-bt", | ||
2560 | .data = (void *)(unsigned long) SI_BT }, | ||
2561 | {}, | ||
2562 | }; | ||
2563 | |||
2564 | static int of_ipmi_probe(struct platform_device *dev) | ||
2565 | { | ||
2676 | const struct of_device_id *match; | 2566 | const struct of_device_id *match; |
2677 | struct smi_info *info; | 2567 | struct smi_info *info; |
2678 | struct resource resource; | 2568 | struct resource resource; |
@@ -2683,9 +2573,9 @@ static int ipmi_probe(struct platform_device *dev) | |||
2683 | 2573 | ||
2684 | dev_info(&dev->dev, "probing via device tree\n"); | 2574 | dev_info(&dev->dev, "probing via device tree\n"); |
2685 | 2575 | ||
2686 | match = of_match_device(ipmi_match, &dev->dev); | 2576 | match = of_match_device(of_ipmi_match, &dev->dev); |
2687 | if (!match) | 2577 | if (!match) |
2688 | return -EINVAL; | 2578 | return -ENODEV; |
2689 | 2579 | ||
2690 | if (!of_device_is_available(np)) | 2580 | if (!of_device_is_available(np)) |
2691 | return -EINVAL; | 2581 | return -EINVAL; |
@@ -2754,33 +2644,160 @@ static int ipmi_probe(struct platform_device *dev) | |||
2754 | kfree(info); | 2644 | kfree(info); |
2755 | return ret; | 2645 | return ret; |
2756 | } | 2646 | } |
2757 | #endif | ||
2758 | return 0; | 2647 | return 0; |
2759 | } | 2648 | } |
2649 | MODULE_DEVICE_TABLE(of, of_ipmi_match); | ||
2650 | #else | ||
2651 | #define of_ipmi_match NULL | ||
2652 | static int of_ipmi_probe(struct platform_device *dev) | ||
2653 | { | ||
2654 | return -ENODEV; | ||
2655 | } | ||
2656 | #endif | ||
2760 | 2657 | ||
2761 | static int ipmi_remove(struct platform_device *dev) | 2658 | #ifdef CONFIG_ACPI |
2659 | static int acpi_ipmi_probe(struct platform_device *dev) | ||
2762 | { | 2660 | { |
2763 | #ifdef CONFIG_OF | 2661 | struct smi_info *info; |
2764 | cleanup_one_si(dev_get_drvdata(&dev->dev)); | 2662 | struct resource *res, *res_second; |
2663 | acpi_handle handle; | ||
2664 | acpi_status status; | ||
2665 | unsigned long long tmp; | ||
2666 | int rv = -EINVAL; | ||
2667 | |||
2668 | handle = ACPI_HANDLE(&dev->dev); | ||
2669 | if (!handle) | ||
2670 | return -ENODEV; | ||
2671 | |||
2672 | info = smi_info_alloc(); | ||
2673 | if (!info) | ||
2674 | return -ENOMEM; | ||
2675 | |||
2676 | info->addr_source = SI_ACPI; | ||
2677 | dev_info(&dev->dev, PFX "probing via ACPI\n"); | ||
2678 | |||
2679 | info->addr_info.acpi_info.acpi_handle = handle; | ||
2680 | |||
2681 | /* _IFT tells us the interface type: KCS, BT, etc */ | ||
2682 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); | ||
2683 | if (ACPI_FAILURE(status)) { | ||
2684 | dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n"); | ||
2685 | goto err_free; | ||
2686 | } | ||
2687 | |||
2688 | switch (tmp) { | ||
2689 | case 1: | ||
2690 | info->si_type = SI_KCS; | ||
2691 | break; | ||
2692 | case 2: | ||
2693 | info->si_type = SI_SMIC; | ||
2694 | break; | ||
2695 | case 3: | ||
2696 | info->si_type = SI_BT; | ||
2697 | break; | ||
2698 | case 4: /* SSIF, just ignore */ | ||
2699 | rv = -ENODEV; | ||
2700 | goto err_free; | ||
2701 | default: | ||
2702 | dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); | ||
2703 | goto err_free; | ||
2704 | } | ||
2705 | |||
2706 | res = platform_get_resource(dev, IORESOURCE_IO, 0); | ||
2707 | if (res) { | ||
2708 | info->io_setup = port_setup; | ||
2709 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | ||
2710 | } else { | ||
2711 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
2712 | if (res) { | ||
2713 | info->io_setup = mem_setup; | ||
2714 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2715 | } | ||
2716 | } | ||
2717 | if (!res) { | ||
2718 | dev_err(&dev->dev, "no I/O or memory address\n"); | ||
2719 | goto err_free; | ||
2720 | } | ||
2721 | info->io.addr_data = res->start; | ||
2722 | |||
2723 | info->io.regspacing = DEFAULT_REGSPACING; | ||
2724 | res_second = platform_get_resource(dev, | ||
2725 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? | ||
2726 | IORESOURCE_IO : IORESOURCE_MEM, | ||
2727 | 1); | ||
2728 | if (res_second) { | ||
2729 | if (res_second->start > info->io.addr_data) | ||
2730 | info->io.regspacing = | ||
2731 | res_second->start - info->io.addr_data; | ||
2732 | } | ||
2733 | info->io.regsize = DEFAULT_REGSPACING; | ||
2734 | info->io.regshift = 0; | ||
2735 | |||
2736 | /* If _GPE exists, use it; otherwise use standard interrupts */ | ||
2737 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); | ||
2738 | if (ACPI_SUCCESS(status)) { | ||
2739 | info->irq = tmp; | ||
2740 | info->irq_setup = acpi_gpe_irq_setup; | ||
2741 | } else { | ||
2742 | int irq = platform_get_irq(dev, 0); | ||
2743 | |||
2744 | if (irq > 0) { | ||
2745 | info->irq = irq; | ||
2746 | info->irq_setup = std_irq_setup; | ||
2747 | } | ||
2748 | } | ||
2749 | |||
2750 | info->dev = &dev->dev; | ||
2751 | platform_set_drvdata(dev, info); | ||
2752 | |||
2753 | dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n", | ||
2754 | res, info->io.regsize, info->io.regspacing, | ||
2755 | info->irq); | ||
2756 | |||
2757 | rv = add_smi(info); | ||
2758 | if (rv) | ||
2759 | kfree(info); | ||
2760 | |||
2761 | return rv; | ||
2762 | |||
2763 | err_free: | ||
2764 | kfree(info); | ||
2765 | return rv; | ||
2766 | } | ||
2767 | |||
2768 | static const struct acpi_device_id acpi_ipmi_match[] = { | ||
2769 | { "IPI0001", 0 }, | ||
2770 | { }, | ||
2771 | }; | ||
2772 | MODULE_DEVICE_TABLE(acpi, acpi_ipmi_match); | ||
2773 | #else | ||
2774 | static int acpi_ipmi_probe(struct platform_device *dev) | ||
2775 | { | ||
2776 | return -ENODEV; | ||
2777 | } | ||
2765 | #endif | 2778 | #endif |
2766 | return 0; | 2779 | |
2780 | static int ipmi_probe(struct platform_device *dev) | ||
2781 | { | ||
2782 | if (of_ipmi_probe(dev) == 0) | ||
2783 | return 0; | ||
2784 | |||
2785 | return acpi_ipmi_probe(dev); | ||
2767 | } | 2786 | } |
2768 | 2787 | ||
2769 | static const struct of_device_id ipmi_match[] = | 2788 | static int ipmi_remove(struct platform_device *dev) |
2770 | { | 2789 | { |
2771 | { .type = "ipmi", .compatible = "ipmi-kcs", | 2790 | struct smi_info *info = dev_get_drvdata(&dev->dev); |
2772 | .data = (void *)(unsigned long) SI_KCS }, | 2791 | |
2773 | { .type = "ipmi", .compatible = "ipmi-smic", | 2792 | cleanup_one_si(info); |
2774 | .data = (void *)(unsigned long) SI_SMIC }, | 2793 | return 0; |
2775 | { .type = "ipmi", .compatible = "ipmi-bt", | 2794 | } |
2776 | .data = (void *)(unsigned long) SI_BT }, | ||
2777 | {}, | ||
2778 | }; | ||
2779 | 2795 | ||
2780 | static struct platform_driver ipmi_driver = { | 2796 | static struct platform_driver ipmi_driver = { |
2781 | .driver = { | 2797 | .driver = { |
2782 | .name = DEVICE_NAME, | 2798 | .name = DEVICE_NAME, |
2783 | .of_match_table = ipmi_match, | 2799 | .of_match_table = of_ipmi_match, |
2800 | .acpi_match_table = ACPI_PTR(acpi_ipmi_match), | ||
2784 | }, | 2801 | }, |
2785 | .probe = ipmi_probe, | 2802 | .probe = ipmi_probe, |
2786 | .remove = ipmi_remove, | 2803 | .remove = ipmi_remove, |
@@ -2905,12 +2922,7 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2905 | return rv; | 2922 | return rv; |
2906 | } | 2923 | } |
2907 | 2924 | ||
2908 | /* | 2925 | static int get_global_enables(struct smi_info *smi_info, u8 *enables) |
2909 | * Some BMCs do not support clearing the receive irq bit in the global | ||
2910 | * enables (even if they don't support interrupts on the BMC). Check | ||
2911 | * for this and handle it properly. | ||
2912 | */ | ||
2913 | static void check_clr_rcv_irq(struct smi_info *smi_info) | ||
2914 | { | 2926 | { |
2915 | unsigned char msg[3]; | 2927 | unsigned char msg[3]; |
2916 | unsigned char *resp; | 2928 | unsigned char *resp; |
@@ -2918,12 +2930,8 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) | |||
2918 | int rv; | 2930 | int rv; |
2919 | 2931 | ||
2920 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | 2932 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); |
2921 | if (!resp) { | 2933 | if (!resp) |
2922 | printk(KERN_WARNING PFX "Out of memory allocating response for" | 2934 | return -ENOMEM; |
2923 | " global enables command, cannot check recv irq bit" | ||
2924 | " handling.\n"); | ||
2925 | return; | ||
2926 | } | ||
2927 | 2935 | ||
2928 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | 2936 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
2929 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | 2937 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; |
@@ -2931,9 +2939,9 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) | |||
2931 | 2939 | ||
2932 | rv = wait_for_msg_done(smi_info); | 2940 | rv = wait_for_msg_done(smi_info); |
2933 | if (rv) { | 2941 | if (rv) { |
2934 | printk(KERN_WARNING PFX "Error getting response from get" | 2942 | dev_warn(smi_info->dev, |
2935 | " global enables command, cannot check recv irq bit" | 2943 | "Error getting response from get global enables command: %d\n", |
2936 | " handling.\n"); | 2944 | rv); |
2937 | goto out; | 2945 | goto out; |
2938 | } | 2946 | } |
2939 | 2947 | ||
@@ -2944,27 +2952,44 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) | |||
2944 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || | 2952 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
2945 | resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || | 2953 | resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || |
2946 | resp[2] != 0) { | 2954 | resp[2] != 0) { |
2947 | printk(KERN_WARNING PFX "Invalid return from get global" | 2955 | dev_warn(smi_info->dev, |
2948 | " enables command, cannot check recv irq bit" | 2956 | "Invalid return from get global enables command: %ld %x %x %x\n", |
2949 | " handling.\n"); | 2957 | resp_len, resp[0], resp[1], resp[2]); |
2950 | rv = -EINVAL; | 2958 | rv = -EINVAL; |
2951 | goto out; | 2959 | goto out; |
2960 | } else { | ||
2961 | *enables = resp[3]; | ||
2952 | } | 2962 | } |
2953 | 2963 | ||
2954 | if ((resp[3] & IPMI_BMC_RCV_MSG_INTR) == 0) | 2964 | out: |
2955 | /* Already clear, should work ok. */ | 2965 | kfree(resp); |
2956 | goto out; | 2966 | return rv; |
2967 | } | ||
2968 | |||
2969 | /* | ||
2970 | * Returns 1 if it gets an error from the command. | ||
2971 | */ | ||
2972 | static int set_global_enables(struct smi_info *smi_info, u8 enables) | ||
2973 | { | ||
2974 | unsigned char msg[3]; | ||
2975 | unsigned char *resp; | ||
2976 | unsigned long resp_len; | ||
2977 | int rv; | ||
2978 | |||
2979 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
2980 | if (!resp) | ||
2981 | return -ENOMEM; | ||
2957 | 2982 | ||
2958 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | 2983 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
2959 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | 2984 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; |
2960 | msg[2] = resp[3] & ~IPMI_BMC_RCV_MSG_INTR; | 2985 | msg[2] = enables; |
2961 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); | 2986 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); |
2962 | 2987 | ||
2963 | rv = wait_for_msg_done(smi_info); | 2988 | rv = wait_for_msg_done(smi_info); |
2964 | if (rv) { | 2989 | if (rv) { |
2965 | printk(KERN_WARNING PFX "Error getting response from set" | 2990 | dev_warn(smi_info->dev, |
2966 | " global enables command, cannot check recv irq bit" | 2991 | "Error getting response from set global enables command: %d\n", |
2967 | " handling.\n"); | 2992 | rv); |
2968 | goto out; | 2993 | goto out; |
2969 | } | 2994 | } |
2970 | 2995 | ||
@@ -2974,25 +2999,93 @@ static void check_clr_rcv_irq(struct smi_info *smi_info) | |||
2974 | if (resp_len < 3 || | 2999 | if (resp_len < 3 || |
2975 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || | 3000 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || |
2976 | resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { | 3001 | resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { |
2977 | printk(KERN_WARNING PFX "Invalid return from get global" | 3002 | dev_warn(smi_info->dev, |
2978 | " enables command, cannot check recv irq bit" | 3003 | "Invalid return from set global enables command: %ld %x %x\n", |
2979 | " handling.\n"); | 3004 | resp_len, resp[0], resp[1]); |
2980 | rv = -EINVAL; | 3005 | rv = -EINVAL; |
2981 | goto out; | 3006 | goto out; |
2982 | } | 3007 | } |
2983 | 3008 | ||
2984 | if (resp[2] != 0) { | 3009 | if (resp[2] != 0) |
3010 | rv = 1; | ||
3011 | |||
3012 | out: | ||
3013 | kfree(resp); | ||
3014 | return rv; | ||
3015 | } | ||
3016 | |||
3017 | /* | ||
3018 | * Some BMCs do not support clearing the receive irq bit in the global | ||
3019 | * enables (even if they don't support interrupts on the BMC). Check | ||
3020 | * for this and handle it properly. | ||
3021 | */ | ||
3022 | static void check_clr_rcv_irq(struct smi_info *smi_info) | ||
3023 | { | ||
3024 | u8 enables = 0; | ||
3025 | int rv; | ||
3026 | |||
3027 | rv = get_global_enables(smi_info, &enables); | ||
3028 | if (!rv) { | ||
3029 | if ((enables & IPMI_BMC_RCV_MSG_INTR) == 0) | ||
3030 | /* Already clear, should work ok. */ | ||
3031 | return; | ||
3032 | |||
3033 | enables &= ~IPMI_BMC_RCV_MSG_INTR; | ||
3034 | rv = set_global_enables(smi_info, enables); | ||
3035 | } | ||
3036 | |||
3037 | if (rv < 0) { | ||
3038 | dev_err(smi_info->dev, | ||
3039 | "Cannot check clearing the rcv irq: %d\n", rv); | ||
3040 | return; | ||
3041 | } | ||
3042 | |||
3043 | if (rv) { | ||
2985 | /* | 3044 | /* |
2986 | * An error when setting the event buffer bit means | 3045 | * An error when setting the event buffer bit means |
2987 | * clearing the bit is not supported. | 3046 | * clearing the bit is not supported. |
2988 | */ | 3047 | */ |
2989 | printk(KERN_WARNING PFX "The BMC does not support clearing" | 3048 | dev_warn(smi_info->dev, |
2990 | " the recv irq bit, compensating, but the BMC needs to" | 3049 | "The BMC does not support clearing the recv irq bit, compensating, but the BMC needs to be fixed.\n"); |
2991 | " be fixed.\n"); | 3050 | smi_info->cannot_disable_irq = true; |
2992 | smi_info->cannot_clear_recv_irq_bit = true; | 3051 | } |
3052 | } | ||
3053 | |||
3054 | /* | ||
3055 | * Some BMCs do not support setting the interrupt bits in the global | ||
3056 | * enables even if they support interrupts. Clearly bad, but we can | ||
3057 | * compensate. | ||
3058 | */ | ||
3059 | static void check_set_rcv_irq(struct smi_info *smi_info) | ||
3060 | { | ||
3061 | u8 enables = 0; | ||
3062 | int rv; | ||
3063 | |||
3064 | if (!smi_info->irq) | ||
3065 | return; | ||
3066 | |||
3067 | rv = get_global_enables(smi_info, &enables); | ||
3068 | if (!rv) { | ||
3069 | enables |= IPMI_BMC_RCV_MSG_INTR; | ||
3070 | rv = set_global_enables(smi_info, enables); | ||
3071 | } | ||
3072 | |||
3073 | if (rv < 0) { | ||
3074 | dev_err(smi_info->dev, | ||
3075 | "Cannot check setting the rcv irq: %d\n", rv); | ||
3076 | return; | ||
3077 | } | ||
3078 | |||
3079 | if (rv) { | ||
3080 | /* | ||
3081 | * An error when setting the event buffer bit means | ||
3082 | * setting the bit is not supported. | ||
3083 | */ | ||
3084 | dev_warn(smi_info->dev, | ||
3085 | "The BMC does not support setting the recv irq bit, compensating, but the BMC needs to be fixed.\n"); | ||
3086 | smi_info->cannot_disable_irq = true; | ||
3087 | smi_info->irq_enable_broken = true; | ||
2993 | } | 3088 | } |
2994 | out: | ||
2995 | kfree(resp); | ||
2996 | } | 3089 | } |
2997 | 3090 | ||
2998 | static int try_enable_event_buffer(struct smi_info *smi_info) | 3091 | static int try_enable_event_buffer(struct smi_info *smi_info) |
@@ -3313,6 +3406,12 @@ static void setup_xaction_handlers(struct smi_info *smi_info) | |||
3313 | setup_dell_poweredge_bt_xaction_handler(smi_info); | 3406 | setup_dell_poweredge_bt_xaction_handler(smi_info); |
3314 | } | 3407 | } |
3315 | 3408 | ||
3409 | static void check_for_broken_irqs(struct smi_info *smi_info) | ||
3410 | { | ||
3411 | check_clr_rcv_irq(smi_info); | ||
3412 | check_set_rcv_irq(smi_info); | ||
3413 | } | ||
3414 | |||
3316 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | 3415 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) |
3317 | { | 3416 | { |
3318 | if (smi_info->thread != NULL) | 3417 | if (smi_info->thread != NULL) |
@@ -3321,7 +3420,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | |||
3321 | del_timer_sync(&smi_info->si_timer); | 3420 | del_timer_sync(&smi_info->si_timer); |
3322 | } | 3421 | } |
3323 | 3422 | ||
3324 | static struct ipmi_default_vals | 3423 | static const struct ipmi_default_vals |
3325 | { | 3424 | { |
3326 | int type; | 3425 | int type; |
3327 | int port; | 3426 | int port; |
@@ -3490,10 +3589,9 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3490 | goto out_err; | 3589 | goto out_err; |
3491 | } | 3590 | } |
3492 | 3591 | ||
3493 | check_clr_rcv_irq(new_smi); | ||
3494 | |||
3495 | setup_oem_data_handler(new_smi); | 3592 | setup_oem_data_handler(new_smi); |
3496 | setup_xaction_handlers(new_smi); | 3593 | setup_xaction_handlers(new_smi); |
3594 | check_for_broken_irqs(new_smi); | ||
3497 | 3595 | ||
3498 | new_smi->waiting_msg = NULL; | 3596 | new_smi->waiting_msg = NULL; |
3499 | new_smi->curr_msg = NULL; | 3597 | new_smi->curr_msg = NULL; |
@@ -3692,13 +3790,6 @@ static int init_ipmi_si(void) | |||
3692 | } | 3790 | } |
3693 | #endif | 3791 | #endif |
3694 | 3792 | ||
3695 | #ifdef CONFIG_ACPI | ||
3696 | if (si_tryacpi) { | ||
3697 | pnp_register_driver(&ipmi_pnp_driver); | ||
3698 | pnp_registered = true; | ||
3699 | } | ||
3700 | #endif | ||
3701 | |||
3702 | #ifdef CONFIG_DMI | 3793 | #ifdef CONFIG_DMI |
3703 | if (si_trydmi) | 3794 | if (si_trydmi) |
3704 | dmi_find_bmc(); | 3795 | dmi_find_bmc(); |
@@ -3850,10 +3941,6 @@ static void cleanup_ipmi_si(void) | |||
3850 | if (pci_registered) | 3941 | if (pci_registered) |
3851 | pci_unregister_driver(&ipmi_pci_driver); | 3942 | pci_unregister_driver(&ipmi_pci_driver); |
3852 | #endif | 3943 | #endif |
3853 | #ifdef CONFIG_ACPI | ||
3854 | if (pnp_registered) | ||
3855 | pnp_unregister_driver(&ipmi_pnp_driver); | ||
3856 | #endif | ||
3857 | #ifdef CONFIG_PARISC | 3944 | #ifdef CONFIG_PARISC |
3858 | if (parisc_registered) | 3945 | if (parisc_registered) |
3859 | unregister_parisc_driver(&ipmi_parisc_driver); | 3946 | unregister_parisc_driver(&ipmi_parisc_driver); |
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h index df89f73475fb..a705027c0493 100644 --- a/drivers/char/ipmi/ipmi_si_sm.h +++ b/drivers/char/ipmi/ipmi_si_sm.h | |||
@@ -46,8 +46,8 @@ struct si_sm_data; | |||
46 | * this interface. | 46 | * this interface. |
47 | */ | 47 | */ |
48 | struct si_sm_io { | 48 | struct si_sm_io { |
49 | unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset); | 49 | unsigned char (*inputb)(const struct si_sm_io *io, unsigned int offset); |
50 | void (*outputb)(struct si_sm_io *io, | 50 | void (*outputb)(const struct si_sm_io *io, |
51 | unsigned int offset, | 51 | unsigned int offset, |
52 | unsigned char b); | 52 | unsigned char b); |
53 | 53 | ||
@@ -135,7 +135,7 @@ struct si_sm_handlers { | |||
135 | }; | 135 | }; |
136 | 136 | ||
137 | /* Current state machines that we can use. */ | 137 | /* Current state machines that we can use. */ |
138 | extern struct si_sm_handlers kcs_smi_handlers; | 138 | extern const struct si_sm_handlers kcs_smi_handlers; |
139 | extern struct si_sm_handlers smic_smi_handlers; | 139 | extern const struct si_sm_handlers smic_smi_handlers; |
140 | extern struct si_sm_handlers bt_smi_handlers; | 140 | extern const struct si_sm_handlers bt_smi_handlers; |
141 | 141 | ||
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c index c8e77afa8b96..8f7c73ff58f2 100644 --- a/drivers/char/ipmi/ipmi_smic_sm.c +++ b/drivers/char/ipmi/ipmi_smic_sm.c | |||
@@ -589,7 +589,7 @@ static int smic_size(void) | |||
589 | return sizeof(struct si_sm_data); | 589 | return sizeof(struct si_sm_data); |
590 | } | 590 | } |
591 | 591 | ||
592 | struct si_sm_handlers smic_smi_handlers = { | 592 | const struct si_sm_handlers smic_smi_handlers = { |
593 | .init_data = init_smic_data, | 593 | .init_data = init_smic_data, |
594 | .start_transaction = start_smic_transaction, | 594 | .start_transaction = start_smic_transaction, |
595 | .get_result = smic_get_result, | 595 | .get_result = smic_get_result, |
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 207689c444a8..877205d22046 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c | |||
@@ -1136,6 +1136,10 @@ module_param_array(slave_addrs, int, &num_slave_addrs, 0); | |||
1136 | MODULE_PARM_DESC(slave_addrs, | 1136 | MODULE_PARM_DESC(slave_addrs, |
1137 | "The default IPMB slave address for the controller."); | 1137 | "The default IPMB slave address for the controller."); |
1138 | 1138 | ||
1139 | static bool alerts_broken; | ||
1140 | module_param(alerts_broken, bool, 0); | ||
1141 | MODULE_PARM_DESC(alerts_broken, "Don't enable alerts for the controller."); | ||
1142 | |||
1139 | /* | 1143 | /* |
1140 | * Bit 0 enables message debugging, bit 1 enables state debugging, and | 1144 | * Bit 0 enables message debugging, bit 1 enables state debugging, and |
1141 | * bit 2 enables timing debugging. This is an array indexed by | 1145 | * bit 2 enables timing debugging. This is an array indexed by |
@@ -1154,11 +1158,11 @@ static int use_thread; | |||
1154 | module_param(use_thread, int, 0); | 1158 | module_param(use_thread, int, 0); |
1155 | MODULE_PARM_DESC(use_thread, "Use the thread interface."); | 1159 | MODULE_PARM_DESC(use_thread, "Use the thread interface."); |
1156 | 1160 | ||
1157 | static bool ssif_tryacpi = 1; | 1161 | static bool ssif_tryacpi = true; |
1158 | module_param_named(tryacpi, ssif_tryacpi, bool, 0); | 1162 | module_param_named(tryacpi, ssif_tryacpi, bool, 0); |
1159 | MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI"); | 1163 | MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI"); |
1160 | 1164 | ||
1161 | static bool ssif_trydmi = 1; | 1165 | static bool ssif_trydmi = true; |
1162 | module_param_named(trydmi, ssif_trydmi, bool, 0); | 1166 | module_param_named(trydmi, ssif_trydmi, bool, 0); |
1163 | MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the default scan of the interfaces identified via DMI (SMBIOS)"); | 1167 | MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the default scan of the interfaces identified via DMI (SMBIOS)"); |
1164 | 1168 | ||
@@ -1582,6 +1586,10 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1582 | ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF; | 1586 | ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF; |
1583 | } | 1587 | } |
1584 | 1588 | ||
1589 | /* Some systems don't behave well if you enable alerts. */ | ||
1590 | if (alerts_broken) | ||
1591 | goto found; | ||
1592 | |||
1585 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | 1593 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; |
1586 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | 1594 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; |
1587 | msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR; | 1595 | msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR; |
@@ -1787,7 +1795,7 @@ skip_addr: | |||
1787 | } | 1795 | } |
1788 | 1796 | ||
1789 | #ifdef CONFIG_ACPI | 1797 | #ifdef CONFIG_ACPI |
1790 | static struct acpi_device_id ssif_acpi_match[] = { | 1798 | static const struct acpi_device_id ssif_acpi_match[] = { |
1791 | { "IPI0001", 0 }, | 1799 | { "IPI0001", 0 }, |
1792 | { }, | 1800 | { }, |
1793 | }; | 1801 | }; |
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 0b1e569f5ff5..f8cea14485dd 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h | |||
@@ -115,6 +115,11 @@ struct ipmi_smi_handlers { | |||
115 | implement it. */ | 115 | implement it. */ |
116 | void (*set_need_watch)(void *send_info, bool enable); | 116 | void (*set_need_watch)(void *send_info, bool enable); |
117 | 117 | ||
118 | /* | ||
119 | * Called when flushing all pending messages. | ||
120 | */ | ||
121 | void (*flush_messages)(void *send_info); | ||
122 | |||
118 | /* Called when the interface should go into "run to | 123 | /* Called when the interface should go into "run to |
119 | completion" mode. If this call sets the value to true, the | 124 | completion" mode. If this call sets the value to true, the |
120 | interface should make sure that all messages are flushed | 125 | interface should make sure that all messages are flushed |
@@ -207,7 +212,7 @@ static inline int ipmi_demangle_device_id(const unsigned char *data, | |||
207 | upper layer until the start_processing() function in the handlers | 212 | upper layer until the start_processing() function in the handlers |
208 | is called, and the lower layer must get the interface from that | 213 | is called, and the lower layer must get the interface from that |
209 | call. */ | 214 | call. */ |
210 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | 215 | int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, |
211 | void *send_info, | 216 | void *send_info, |
212 | struct ipmi_device_id *device_id, | 217 | struct ipmi_device_id *device_id, |
213 | struct device *dev, | 218 | struct device *dev, |