You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'for-linus-4.3' of git://git.code.sf.net/p/openipmi/linux-ipmi
Pull IPMI updates from Corey Minyard:
"Most of these have been sitting in linux-next for more than a release,
particularly commit 0fbcf4af7c ("ipmi: Convert the IPMI SI ACPI
handling to a platform device") which is probably the most complex
patch.
That is also the one that changes drivers/acpi/acpi_pnp.c. The change
in that file is only removing IPMI from a "special platform devices"
list, since I convert it to the standard PNP interface. I posted this
one to the ACPI list twice and got no response, and it seems to work
well in my testing, so I'm hoping it's good.
Hidehiro Kawai posted a set of changes that improves the panic time
handling in the IPMI driver.
The rest of the changes are minor bug fixes or cleanups and some
documentation"
* tag 'for-linus-4.3' of git://git.code.sf.net/p/openipmi/linux-ipmi:
ipmi:ssif: Add a module parm to specify that SMBus alerts don't work
ipmi: add of_device_id in MODULE_DEVICE_TABLE
ipmi: Compensate for BMCs that wont set the irq enable bit
ipmi: Don't call receive handler in the panic context
ipmi: Avoid touching possible corrupted lists in the panic context
ipmi: Don't flush messages in sender() in run-to-completion mode
ipmi: Factor out message flushing procedure
ipmi: Remove unneeded set_run_to_completion call
ipmi: Make some data const that was only read
ipmi: constify SSIF ACPI device ids
ipmi: Delete an unnecessary check before the function call "cleanup_one_si"
char:ipmi - Change 1 to true for bool type variables during initialization.
impi:Remove unneeded setting of module owner to THIS_MODULE in the platform structure, powernv_ipmi_driver
ipmi: Add a comment in how messages are delivered from the lower layer
ipmi/powernv: Fix potential invalid pointer dereference
ipmi: Convert the IPMI SI ACPI handling to a platform device
ipmi: Add device tree bindings information
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
IPMI device
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of ipmi-kcs, ipmi-smic, or ipmi-bt
|
||||
- device_type: should be ipmi
|
||||
- reg: Address and length of the register set for the device
|
||||
|
||||
Optional properties:
|
||||
- interrupts: The interrupt for the device. Without this the interface
|
||||
is polled.
|
||||
- reg-size - The size of the register. Defaults to 1
|
||||
- reg-spacing - The number of bytes between register starts. Defaults to 1
|
||||
- reg-shift - The amount to shift the registers to the right to get the data
|
||||
into bit zero.
|
||||
|
||||
Example:
|
||||
|
||||
smic@fff3a000 {
|
||||
compatible = "ipmi-smic";
|
||||
device_type = "ipmi";
|
||||
reg = <0xfff3a000 0x1000>;
|
||||
interrupts = <0 24 4>;
|
||||
reg-size = <4>;
|
||||
reg-spacing = <4>;
|
||||
};
|
||||
@@ -19,8 +19,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
|
||||
{"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */
|
||||
/* floppy */
|
||||
{"PNP0700"},
|
||||
/* ipmi_si */
|
||||
{"IPI0001"},
|
||||
/* tpm_inf_pnp */
|
||||
{"IFX0101"}, /* Infineon TPMs */
|
||||
{"IFX0102"}, /* Infineon TPMs */
|
||||
|
||||
@@ -694,7 +694,7 @@ static int bt_size(void)
|
||||
return sizeof(struct si_sm_data);
|
||||
}
|
||||
|
||||
struct si_sm_handlers bt_smi_handlers = {
|
||||
const struct si_sm_handlers bt_smi_handlers = {
|
||||
.init_data = bt_init_data,
|
||||
.start_transaction = bt_start_transaction,
|
||||
.get_result = bt_get_result,
|
||||
|
||||
@@ -540,7 +540,7 @@ static void kcs_cleanup(struct si_sm_data *kcs)
|
||||
{
|
||||
}
|
||||
|
||||
struct si_sm_handlers kcs_smi_handlers = {
|
||||
const struct si_sm_handlers kcs_smi_handlers = {
|
||||
.init_data = init_kcs_data,
|
||||
.start_transaction = start_kcs_transaction,
|
||||
.get_result = get_kcs_result,
|
||||
|
||||
@@ -342,7 +342,7 @@ struct ipmi_smi {
|
||||
* an umpreemptible region to use this. You must fetch the
|
||||
* value into a local variable and make sure it is not NULL.
|
||||
*/
|
||||
struct ipmi_smi_handlers *handlers;
|
||||
const struct ipmi_smi_handlers *handlers;
|
||||
void *send_info;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
@@ -744,7 +744,13 @@ static void deliver_response(struct ipmi_recv_msg *msg)
|
||||
ipmi_inc_stat(intf, unhandled_local_responses);
|
||||
}
|
||||
ipmi_free_recv_msg(msg);
|
||||
} else {
|
||||
} else if (!oops_in_progress) {
|
||||
/*
|
||||
* If we are running in the panic context, calling the
|
||||
* receive handler doesn't much meaning and has a deadlock
|
||||
* risk. At this moment, simply skip it in that case.
|
||||
*/
|
||||
|
||||
ipmi_user_t user = msg->user;
|
||||
user->handler->ipmi_recv_hndl(msg, user->handler_data);
|
||||
}
|
||||
@@ -1015,7 +1021,7 @@ int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
|
||||
{
|
||||
int rv = 0;
|
||||
ipmi_smi_t intf;
|
||||
struct ipmi_smi_handlers *handlers;
|
||||
const struct ipmi_smi_handlers *handlers;
|
||||
|
||||
mutex_lock(&ipmi_interfaces_mutex);
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
static void smi_send(ipmi_smi_t intf, struct ipmi_smi_handlers *handlers,
|
||||
static void smi_send(ipmi_smi_t intf, const struct ipmi_smi_handlers *handlers,
|
||||
struct ipmi_smi_msg *smi_msg, int priority)
|
||||
{
|
||||
int run_to_completion = intf->run_to_completion;
|
||||
@@ -2747,7 +2753,7 @@ void ipmi_poll_interface(ipmi_user_t user)
|
||||
}
|
||||
EXPORT_SYMBOL(ipmi_poll_interface);
|
||||
|
||||
int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
|
||||
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
|
||||
void *send_info,
|
||||
struct ipmi_device_id *device_id,
|
||||
struct device *si_dev,
|
||||
@@ -3959,6 +3965,10 @@ free_msg:
|
||||
|
||||
if (!run_to_completion)
|
||||
spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
|
||||
/*
|
||||
* We can get an asynchronous event or receive message in addition
|
||||
* to commands we send.
|
||||
*/
|
||||
if (msg == intf->curr_msg)
|
||||
intf->curr_msg = NULL;
|
||||
if (!run_to_completion)
|
||||
@@ -4015,7 +4025,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
||||
unsigned int *waiting_msgs)
|
||||
{
|
||||
struct ipmi_recv_msg *msg;
|
||||
struct ipmi_smi_handlers *handlers;
|
||||
const struct ipmi_smi_handlers *handlers;
|
||||
|
||||
if (intf->in_shutdown)
|
||||
return;
|
||||
@@ -4082,7 +4092,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
|
||||
ipmi_inc_stat(intf,
|
||||
retransmitted_ipmb_commands);
|
||||
|
||||
smi_send(intf, intf->handlers, smi_msg, 0);
|
||||
smi_send(intf, handlers, smi_msg, 0);
|
||||
} else
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
|
||||
@@ -4291,6 +4301,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
|
||||
0, 1); /* Don't retry, and don't wait. */
|
||||
if (rv)
|
||||
atomic_sub(2, &panic_done_count);
|
||||
else if (intf->handlers->flush_messages)
|
||||
intf->handlers->flush_messages(intf->send_info);
|
||||
|
||||
while (atomic_read(&panic_done_count) != 0)
|
||||
ipmi_poll(intf);
|
||||
}
|
||||
@@ -4364,9 +4377,7 @@ static void send_panic_events(char *str)
|
||||
/* Interface is not ready. */
|
||||
continue;
|
||||
|
||||
intf->run_to_completion = 1;
|
||||
/* Send the event announcing the panic. */
|
||||
intf->handlers->set_run_to_completion(intf->send_info, 1);
|
||||
ipmi_panic_request_and_wait(intf, &addr, &msg);
|
||||
}
|
||||
|
||||
@@ -4506,6 +4517,23 @@ static int panic_event(struct notifier_block *this,
|
||||
/* Interface is not ready. */
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If we were interrupted while locking xmit_msgs_lock or
|
||||
* waiting_rcv_msgs_lock, the corresponding list may be
|
||||
* corrupted. In this case, drop items on the list for
|
||||
* the safety.
|
||||
*/
|
||||
if (!spin_trylock(&intf->xmit_msgs_lock)) {
|
||||
INIT_LIST_HEAD(&intf->xmit_msgs);
|
||||
INIT_LIST_HEAD(&intf->hp_xmit_msgs);
|
||||
} else
|
||||
spin_unlock(&intf->xmit_msgs_lock);
|
||||
|
||||
if (!spin_trylock(&intf->waiting_rcv_msgs_lock))
|
||||
INIT_LIST_HEAD(&intf->waiting_rcv_msgs);
|
||||
else
|
||||
spin_unlock(&intf->waiting_rcv_msgs_lock);
|
||||
|
||||
intf->run_to_completion = 1;
|
||||
intf->handlers->set_run_to_completion(intf->send_info, 1);
|
||||
}
|
||||
|
||||
@@ -143,8 +143,15 @@ static int ipmi_powernv_recv(struct ipmi_smi_powernv *smi)
|
||||
pr_devel("%s: -> %d (size %lld)\n", __func__,
|
||||
rc, rc == 0 ? size : 0);
|
||||
if (rc) {
|
||||
/* If came via the poll, and response was not yet ready */
|
||||
if (rc == OPAL_EMPTY) {
|
||||
spin_unlock_irqrestore(&smi->msg_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
smi->cur_msg = NULL;
|
||||
spin_unlock_irqrestore(&smi->msg_lock, flags);
|
||||
ipmi_free_smi_msg(msg);
|
||||
send_error_reply(smi, msg, IPMI_ERR_UNSPECIFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -300,7 +307,6 @@ static const struct of_device_id ipmi_powernv_match[] = {
|
||||
static struct platform_driver powernv_ipmi_driver = {
|
||||
.driver = {
|
||||
.name = "ipmi-powernv",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ipmi_powernv_match,
|
||||
},
|
||||
.probe = ipmi_powernv_probe,
|
||||
|
||||
+343
-256
File diff suppressed because it is too large
Load Diff
@@ -46,8 +46,8 @@ struct si_sm_data;
|
||||
* this interface.
|
||||
*/
|
||||
struct si_sm_io {
|
||||
unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset);
|
||||
void (*outputb)(struct si_sm_io *io,
|
||||
unsigned char (*inputb)(const struct si_sm_io *io, unsigned int offset);
|
||||
void (*outputb)(const struct si_sm_io *io,
|
||||
unsigned int offset,
|
||||
unsigned char b);
|
||||
|
||||
@@ -135,7 +135,7 @@ struct si_sm_handlers {
|
||||
};
|
||||
|
||||
/* Current state machines that we can use. */
|
||||
extern struct si_sm_handlers kcs_smi_handlers;
|
||||
extern struct si_sm_handlers smic_smi_handlers;
|
||||
extern struct si_sm_handlers bt_smi_handlers;
|
||||
extern const struct si_sm_handlers kcs_smi_handlers;
|
||||
extern const struct si_sm_handlers smic_smi_handlers;
|
||||
extern const struct si_sm_handlers bt_smi_handlers;
|
||||
|
||||
|
||||
@@ -589,7 +589,7 @@ static int smic_size(void)
|
||||
return sizeof(struct si_sm_data);
|
||||
}
|
||||
|
||||
struct si_sm_handlers smic_smi_handlers = {
|
||||
const struct si_sm_handlers smic_smi_handlers = {
|
||||
.init_data = init_smic_data,
|
||||
.start_transaction = start_smic_transaction,
|
||||
.get_result = smic_get_result,
|
||||
|
||||
@@ -1136,6 +1136,10 @@ module_param_array(slave_addrs, int, &num_slave_addrs, 0);
|
||||
MODULE_PARM_DESC(slave_addrs,
|
||||
"The default IPMB slave address for the controller.");
|
||||
|
||||
static bool alerts_broken;
|
||||
module_param(alerts_broken, bool, 0);
|
||||
MODULE_PARM_DESC(alerts_broken, "Don't enable alerts for the controller.");
|
||||
|
||||
/*
|
||||
* Bit 0 enables message debugging, bit 1 enables state debugging, and
|
||||
* bit 2 enables timing debugging. This is an array indexed by
|
||||
@@ -1154,11 +1158,11 @@ static int use_thread;
|
||||
module_param(use_thread, int, 0);
|
||||
MODULE_PARM_DESC(use_thread, "Use the thread interface.");
|
||||
|
||||
static bool ssif_tryacpi = 1;
|
||||
static bool ssif_tryacpi = true;
|
||||
module_param_named(tryacpi, ssif_tryacpi, bool, 0);
|
||||
MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI");
|
||||
|
||||
static bool ssif_trydmi = 1;
|
||||
static bool ssif_trydmi = true;
|
||||
module_param_named(trydmi, ssif_trydmi, bool, 0);
|
||||
MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the default scan of the interfaces identified via DMI (SMBIOS)");
|
||||
|
||||
@@ -1582,6 +1586,10 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF;
|
||||
}
|
||||
|
||||
/* Some systems don't behave well if you enable alerts. */
|
||||
if (alerts_broken)
|
||||
goto found;
|
||||
|
||||
msg[0] = IPMI_NETFN_APP_REQUEST << 2;
|
||||
msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
|
||||
msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR;
|
||||
@@ -1787,7 +1795,7 @@ skip_addr:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static struct acpi_device_id ssif_acpi_match[] = {
|
||||
static const struct acpi_device_id ssif_acpi_match[] = {
|
||||
{ "IPI0001", 0 },
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -115,6 +115,11 @@ struct ipmi_smi_handlers {
|
||||
implement it. */
|
||||
void (*set_need_watch)(void *send_info, bool enable);
|
||||
|
||||
/*
|
||||
* Called when flushing all pending messages.
|
||||
*/
|
||||
void (*flush_messages)(void *send_info);
|
||||
|
||||
/* Called when the interface should go into "run to
|
||||
completion" mode. If this call sets the value to true, the
|
||||
interface should make sure that all messages are flushed
|
||||
@@ -207,7 +212,7 @@ static inline int ipmi_demangle_device_id(const unsigned char *data,
|
||||
upper layer until the start_processing() function in the handlers
|
||||
is called, and the lower layer must get the interface from that
|
||||
call. */
|
||||
int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
|
||||
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
|
||||
void *send_info,
|
||||
struct ipmi_device_id *device_id,
|
||||
struct device *dev,
|
||||
|
||||
Reference in New Issue
Block a user