summaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_ssif.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_ssif.c')
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c183
1 files changed, 33 insertions, 150 deletions
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 35a82f4bfd78f..22f634eb09fd5 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -193,8 +193,7 @@ typedef void (*ssif_i2c_done)(struct ssif_info *ssif_info, int result,
unsigned char *data, unsigned int len);
struct ssif_info {
- ipmi_smi_t intf;
- int intf_num;
+ struct ipmi_smi *intf;
spinlock_t lock;
struct ipmi_smi_msg *waiting_msg;
struct ipmi_smi_msg *curr_msg;
@@ -290,8 +289,6 @@ struct ssif_info {
static bool initialized;
-static atomic_t next_intf = ATOMIC_INIT(0);
-
static void return_hosed_msg(struct ssif_info *ssif_info,
struct ipmi_smi_msg *msg);
static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags);
@@ -315,17 +312,13 @@ static void ipmi_ssif_unlock_cond(struct ssif_info *ssif_info,
static void deliver_recv_msg(struct ssif_info *ssif_info,
struct ipmi_smi_msg *msg)
{
- ipmi_smi_t intf = ssif_info->intf;
-
- if (!intf) {
- ipmi_free_smi_msg(msg);
- } else if (msg->rsp_size < 0) {
+ if (msg->rsp_size < 0) {
return_hosed_msg(ssif_info, msg);
pr_err(PFX
"Malformed message in deliver_recv_msg: rsp_size = %d\n",
msg->rsp_size);
} else {
- ipmi_smi_msg_received(intf, msg);
+ ipmi_smi_msg_received(ssif_info->intf, msg);
}
}
@@ -452,12 +445,10 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info,
static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags)
{
if (ssif_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
- ipmi_smi_t intf = ssif_info->intf;
/* Watchdog pre-timeout */
ssif_inc_stat(ssif_info, watchdog_pretimeouts);
start_clear_flags(ssif_info, flags);
- if (intf)
- ipmi_smi_watchdog_pretimeout(intf);
+ ipmi_smi_watchdog_pretimeout(ssif_info->intf);
} else if (ssif_info->msg_flags & RECEIVE_MSG_AVAIL)
/* Messages available. */
start_recv_msg_fetch(ssif_info, flags);
@@ -1094,27 +1085,8 @@ static void request_events(void *send_info)
}
}
-static int inc_usecount(void *send_info)
-{
- struct ssif_info *ssif_info = send_info;
-
- if (!i2c_get_adapter(i2c_adapter_id(ssif_info->client->adapter)))
- return -ENODEV;
-
- i2c_use_client(ssif_info->client);
- return 0;
-}
-
-static void dec_usecount(void *send_info)
-{
- struct ssif_info *ssif_info = send_info;
-
- i2c_release_client(ssif_info->client);
- i2c_put_adapter(ssif_info->client->adapter);
-}
-
-static int ssif_start_processing(void *send_info,
- ipmi_smi_t intf)
+static int ssif_start_processing(void *send_info,
+ struct ipmi_smi *intf)
{
struct ssif_info *ssif_info = send_info;
@@ -1225,25 +1197,9 @@ static const struct attribute_group ipmi_ssif_dev_attr_group = {
.attrs = ipmi_ssif_dev_attrs,
};
-static int ssif_remove(struct i2c_client *client)
+static void shutdown_ssif(void *send_info)
{
- struct ssif_info *ssif_info = i2c_get_clientdata(client);
- struct ssif_addr_info *addr_info;
- int rv;
-
- if (!ssif_info)
- return 0;
-
- /*
- * After this point, we won't deliver anything asychronously
- * to the message handler. We can unregister ourself.
- */
- rv = ipmi_unregister_smi(ssif_info->intf);
- if (rv) {
- pr_err(PFX "Unable to unregister device: errno=%d\n", rv);
- return rv;
- }
- ssif_info->intf = NULL;
+ struct ssif_info *ssif_info = send_info;
device_remove_group(&ssif_info->client->dev, &ipmi_ssif_dev_attr_group);
dev_set_drvdata(&ssif_info->client->dev, NULL);
@@ -1259,6 +1215,30 @@ static int ssif_remove(struct i2c_client *client)
kthread_stop(ssif_info->thread);
}
+ /*
+ * No message can be outstanding now, we have removed the
+ * upper layer and it permitted us to do so.
+ */
+ kfree(ssif_info);
+}
+
+static int ssif_remove(struct i2c_client *client)
+{
+ struct ssif_info *ssif_info = i2c_get_clientdata(client);
+ struct ipmi_smi *intf;
+ struct ssif_addr_info *addr_info;
+
+ if (!ssif_info)
+ return 0;
+
+ /*
+ * After this point, we won't deliver anything asychronously
+ * to the message handler. We can unregister ourself.
+ */
+ intf = ssif_info->intf;
+ ssif_info->intf = NULL;
+ ipmi_unregister_smi(intf);
+
list_for_each_entry(addr_info, &ssif_infos, link) {
if (addr_info->client == client) {
addr_info->client = NULL;
@@ -1266,11 +1246,6 @@ static int ssif_remove(struct i2c_client *client)
}
}
- /*
- * No message can be outstanding now, we have removed the
- * upper layer and it permitted us to do so.
- */
- kfree(ssif_info);
return 0;
}
@@ -1341,72 +1316,6 @@ static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info)
return rv;
}
-#ifdef CONFIG_IPMI_PROC_INTERFACE
-static int smi_type_proc_show(struct seq_file *m, void *v)
-{
- seq_puts(m, "ssif\n");
-
- return 0;
-}
-
-static int smi_type_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, smi_type_proc_show, inode->i_private);
-}
-
-static const struct file_operations smi_type_proc_ops = {
- .open = smi_type_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int smi_stats_proc_show(struct seq_file *m, void *v)
-{
- struct ssif_info *ssif_info = m->private;
-
- seq_printf(m, "sent_messages: %u\n",
- ssif_get_stat(ssif_info, sent_messages));
- seq_printf(m, "sent_messages_parts: %u\n",
- ssif_get_stat(ssif_info, sent_messages_parts));
- seq_printf(m, "send_retries: %u\n",
- ssif_get_stat(ssif_info, send_retries));
- seq_printf(m, "send_errors: %u\n",
- ssif_get_stat(ssif_info, send_errors));
- seq_printf(m, "received_messages: %u\n",
- ssif_get_stat(ssif_info, received_messages));
- seq_printf(m, "received_message_parts: %u\n",
- ssif_get_stat(ssif_info, received_message_parts));
- seq_printf(m, "receive_retries: %u\n",
- ssif_get_stat(ssif_info, receive_retries));
- seq_printf(m, "receive_errors: %u\n",
- ssif_get_stat(ssif_info, receive_errors));
- seq_printf(m, "flag_fetches: %u\n",
- ssif_get_stat(ssif_info, flag_fetches));
- seq_printf(m, "hosed: %u\n",
- ssif_get_stat(ssif_info, hosed));
- seq_printf(m, "events: %u\n",
- ssif_get_stat(ssif_info, events));
- seq_printf(m, "watchdog_pretimeouts: %u\n",
- ssif_get_stat(ssif_info, watchdog_pretimeouts));
- seq_printf(m, "alerts: %u\n",
- ssif_get_stat(ssif_info, alerts));
- return 0;
-}
-
-static int smi_stats_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, smi_stats_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations smi_stats_proc_ops = {
- .open = smi_stats_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif
-
static int strcmp_nospace(char *s1, char *s2)
{
while (*s1 && *s2) {
@@ -1678,8 +1587,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
found:
- ssif_info->intf_num = atomic_inc_return(&next_intf);
-
if (ssif_dbg_probe) {
pr_info("ssif_probe: i2c_probe found device at i2c address %x\n",
client->addr);
@@ -1697,11 +1604,10 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
ssif_info->handlers.owner = THIS_MODULE;
ssif_info->handlers.start_processing = ssif_start_processing;
+ ssif_info->handlers.shutdown = shutdown_ssif;
ssif_info->handlers.get_smi_info = get_smi_info;
ssif_info->handlers.sender = sender;
ssif_info->handlers.request_events = request_events;
- ssif_info->handlers.inc_usecount = inc_usecount;
- ssif_info->handlers.dec_usecount = dec_usecount;
{
unsigned int thread_num;
@@ -1740,24 +1646,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto out_remove_attr;
}
-#ifdef CONFIG_IPMI_PROC_INTERFACE
- rv = ipmi_smi_add_proc_entry(ssif_info->intf, "type",
- &smi_type_proc_ops,
- ssif_info);
- if (rv) {
- pr_err(PFX "Unable to create proc entry: %d\n", rv);
- goto out_err_unreg;
- }
-
- rv = ipmi_smi_add_proc_entry(ssif_info->intf, "ssif_stats",
- &smi_stats_proc_ops,
- ssif_info);
- if (rv) {
- pr_err(PFX "Unable to create proc entry: %d\n", rv);
- goto out_err_unreg;
- }
-#endif
-
out:
if (rv) {
/*
@@ -1775,11 +1663,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
kfree(resp);
return rv;
-#ifdef CONFIG_IPMI_PROC_INTERFACE
-out_err_unreg:
- ipmi_unregister_smi(ssif_info->intf);
-#endif
-
out_remove_attr:
device_remove_group(&ssif_info->client->dev, &ipmi_ssif_dev_attr_group);
dev_set_drvdata(&ssif_info->client->dev, NULL);