Blob Blame History Raw
From 910840f24bb7f9ea80fce4073445329becfdcb58 Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Tue, 12 Sep 2017 14:41:56 -0500
Subject: [PATCH] ipmi_si: Move some platform data into the io structure
Git-commit: 910840f24bb7f9ea80fce4073445329becfdcb58
Patch-mainline: v4.15-rc1
References: FATE#326156

That's where it belongs, and we are getting ready for moving the
platform handling out of the main ipmi_si_intf.c file.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/char/ipmi/ipmi_si_intf.c | 415 +++++++++++++++----------------
 drivers/char/ipmi/ipmi_si_sm.h   |  14 ++
 2 files changed, 213 insertions(+), 216 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 6ba70c2fc25f..8cc101ea82d9 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -104,10 +104,6 @@ enum si_intf_state {
 #define IPMI_BT_INTMASK_CLEAR_IRQ_BIT	2
 #define IPMI_BT_INTMASK_ENABLE_IRQ_BIT	1
 
-enum si_type {
-	SI_KCS, SI_SMIC, SI_BT
-};
-
 static const char * const si_to_str[] = { "kcs", "smic", "bt" };
 
 #define DEVICE_NAME "ipmi_si"
@@ -167,7 +163,6 @@ struct smi_info {
 	ipmi_smi_t             intf;
 	struct si_sm_data      *si_sm;
 	const struct si_sm_handlers *handlers;
-	enum si_type           si_type;
 	spinlock_t             si_lock;
 	struct ipmi_smi_msg    *waiting_msg;
 	struct ipmi_smi_msg    *curr_msg;
@@ -183,9 +178,6 @@ struct smi_info {
 	int (*irq_setup)(struct smi_info *info);
 	void (*irq_cleanup)(struct smi_info *info);
 	unsigned int io_size;
-	enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */
-	void (*addr_source_cleanup)(struct smi_info *info);
-	void *addr_source_data;
 
 	/*
 	 * Per-OEM handler, called from handle_flags().  Returns 1
@@ -236,9 +228,6 @@ struct smi_info {
 	 */
 	unsigned int        spacing;
 
-	/* zero if no irq; */
-	int                 irq;
-
 	/* The timer for this si. */
 	struct timer_list   si_timer;
 
@@ -289,19 +278,9 @@ struct smi_info {
 	/* From the get device id response... */
 	struct ipmi_device_id device_id;
 
-	/* Driver model stuff. */
-	struct device *dev;
+	/* Default driver model device. */
 	struct platform_device *pdev;
 
-	/*
-	 * True if we allocated the device, false if it came from
-	 * someplace else (like PCI).
-	 */
-	bool dev_registered;
-
-	/* Slave address, could be reported from DMI. */
-	unsigned char slave_addr;
-
 	/* Counters and things for the proc filesystem. */
 	atomic_t stats[SI_NUM_STATS];
 
@@ -498,7 +477,7 @@ static void start_getting_events(struct smi_info *smi_info)
  */
 static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer)
 {
-	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
+	if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) {
 		smi_info->interrupt_disabled = true;
 		start_check_enables(smi_info, start_timer);
 		return true;
@@ -508,7 +487,7 @@ static inline bool disable_si_irq(struct smi_info *smi_info, bool start_timer)
 
 static inline bool enable_si_irq(struct smi_info *smi_info)
 {
-	if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
+	if ((smi_info->io.irq) && (smi_info->interrupt_disabled)) {
 		smi_info->interrupt_disabled = false;
 		start_check_enables(smi_info, true);
 		return true;
@@ -584,13 +563,13 @@ static u8 current_global_enables(struct smi_info *smi_info, u8 base,
 	if (smi_info->supports_event_msg_buff)
 		enables |= IPMI_BMC_EVT_MSG_BUFF;
 
-	if (((smi_info->irq && !smi_info->interrupt_disabled) ||
+	if (((smi_info->io.irq && !smi_info->interrupt_disabled) ||
 	     smi_info->cannot_disable_irq) &&
 	    !smi_info->irq_enable_broken)
 		enables |= IPMI_BMC_RCV_MSG_INTR;
 
 	if (smi_info->supports_event_msg_buff &&
-	    smi_info->irq && !smi_info->interrupt_disabled &&
+	    smi_info->io.irq && !smi_info->interrupt_disabled &&
 	    !smi_info->irq_enable_broken)
 		enables |= IPMI_BMC_EVT_MSG_INTR;
 
@@ -672,7 +651,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
 		smi_info->handlers->get_result(smi_info->si_sm, msg, 3);
 		if (msg[2] != 0) {
 			/* Error clearing flags */
-			dev_warn(smi_info->dev,
+			dev_warn(smi_info->io.dev,
 				 "Error clearing flags: %2.2x\n", msg[2]);
 		}
 		smi_info->si_state = SI_NORMAL;
@@ -764,15 +743,15 @@ static void handle_transaction_done(struct smi_info *smi_info)
 		/* We got the flags from the SMI, now handle them. */
 		smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
 		if (msg[2] != 0) {
-			dev_warn(smi_info->dev,
+			dev_warn(smi_info->io.dev,
 				 "Couldn't get irq info: %x.\n", msg[2]);
-			dev_warn(smi_info->dev,
+			dev_warn(smi_info->io.dev,
 				 "Maybe ok, but ipmi might run very slowly.\n");
 			smi_info->si_state = SI_NORMAL;
 			break;
 		}
 		enables = current_global_enables(smi_info, 0, &irq_on);
-		if (smi_info->si_type == SI_BT)
+		if (smi_info->io.si_type == SI_BT)
 			/* BT has its own interrupt enable bit. */
 			check_bt_irq(smi_info, irq_on);
 		if (enables != (msg[3] & GLOBAL_ENABLES_MASK)) {
@@ -802,7 +781,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
 
 		smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
 		if (msg[2] != 0)
-			dev_warn(smi_info->dev,
+			dev_warn(smi_info->io.dev,
 				 "Could not set the global enables: 0x%x.\n",
 				 msg[2]);
 
@@ -926,7 +905,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
 		 * asynchronously reset, and may thus get interrupts
 		 * disable and messages disabled.
 		 */
-		if (smi_info->supports_event_msg_buff || smi_info->irq) {
+		if (smi_info->supports_event_msg_buff || smi_info->io.irq) {
 			start_check_enables(smi_info, true);
 		} else {
 			smi_info->curr_msg = alloc_msg_handle_irq(smi_info);
@@ -1171,7 +1150,7 @@ static void smi_timeout(unsigned long data)
 		     * SI_USEC_PER_JIFFY);
 	smi_result = smi_event_handler(smi_info, time_diff);
 
-	if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
+	if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) {
 		/* Running with interrupts, only do long timeouts. */
 		timeout = jiffies + SI_TIMEOUT_JIFFIES;
 		smi_inc_stat(smi_info, long_timeouts);
@@ -1249,14 +1228,14 @@ static int smi_start_processing(void       *send_info,
 	 * The BT interface is efficient enough to not need a thread,
 	 * and there is no need for a thread if we have interrupts.
 	 */
-	else if ((new_smi->si_type != SI_BT) && (!new_smi->irq))
+	else if ((new_smi->io.si_type != SI_BT) && (!new_smi->io.irq))
 		enable = 1;
 
 	if (enable) {
 		new_smi->thread = kthread_run(ipmi_thread, new_smi,
 					      "kipmi%d", new_smi->intf_num);
 		if (IS_ERR(new_smi->thread)) {
-			dev_notice(new_smi->dev, "Could not start"
+			dev_notice(new_smi->io.dev, "Could not start"
 				   " kernel thread due to error %ld, only using"
 				   " timers to drive the interface\n",
 				   PTR_ERR(new_smi->thread));
@@ -1271,10 +1250,10 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
 {
 	struct smi_info *smi = send_info;
 
-	data->addr_src = smi->addr_source;
-	data->dev = smi->dev;
+	data->addr_src = smi->io.addr_source;
+	data->dev = smi->io.dev;
 	data->addr_info = smi->addr_info;
-	get_device(smi->dev);
+	get_device(smi->io.dev);
 
 	return 0;
 }
@@ -1424,21 +1403,21 @@ MODULE_PARM_DESC(kipmid_max_busy_us,
 
 static void std_irq_cleanup(struct smi_info *info)
 {
-	if (info->si_type == SI_BT)
+	if (info->io.si_type == SI_BT)
 		/* Disable the interrupt in the BT interface. */
 		info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
-	free_irq(info->irq, info);
+	free_irq(info->io.irq, info);
 }
 
 static int std_irq_setup(struct smi_info *info)
 {
 	int rv;
 
-	if (!info->irq)
+	if (!info->io.irq)
 		return 0;
 
-	if (info->si_type == SI_BT) {
-		rv = request_irq(info->irq,
+	if (info->io.si_type == SI_BT) {
+		rv = request_irq(info->io.irq,
 				 si_bt_irq_handler,
 				 IRQF_SHARED,
 				 DEVICE_NAME,
@@ -1448,19 +1427,19 @@ static int std_irq_setup(struct smi_info *info)
 			info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
 					 IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
 	} else
-		rv = request_irq(info->irq,
+		rv = request_irq(info->io.irq,
 				 si_irq_handler,
 				 IRQF_SHARED,
 				 DEVICE_NAME,
 				 info);
 	if (rv) {
-		dev_warn(info->dev, "%s unable to claim interrupt %d,"
+		dev_warn(info->io.dev, "%s unable to claim interrupt %d,"
 			 " running polled\n",
-			 DEVICE_NAME, info->irq);
-		info->irq = 0;
+			 DEVICE_NAME, info->io.irq);
+		info->io.irq = 0;
 	} else {
 		info->irq_cleanup = std_irq_cleanup;
-		dev_info(info->dev, "Using irq %d\n", info->irq);
+		dev_info(info->io.dev, "Using irq %d\n", info->io.irq);
 	}
 
 	return rv;
@@ -1551,7 +1530,7 @@ static int port_setup(struct smi_info *info)
 		info->io.outputb = port_outl;
 		break;
 	default:
-		dev_warn(info->dev, "Invalid register size: %d\n",
+		dev_warn(info->io.dev, "Invalid register size: %d\n",
 			 info->io.regsize);
 		return -EINVAL;
 	}
@@ -1679,7 +1658,7 @@ static int mem_setup(struct smi_info *info)
 		break;
 #endif
 	default:
-		dev_warn(info->dev, "Invalid register size: %d\n",
+		dev_warn(info->io.dev, "Invalid register size: %d\n",
 			 info->io.regsize);
 		return -EINVAL;
 	}
@@ -1922,8 +1901,8 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
 				goto out;
 			}
 
-			info->addr_source = SI_HOTMOD;
-			info->si_type = si_type;
+			info->io.addr_source = SI_HOTMOD;
+			info->io.si_type = si_type;
 			info->io.addr_data = addr;
 			info->io.addr_type = addr_space;
 			if (addr_space == IPMI_MEM_ADDR_SPACE)
@@ -1939,10 +1918,10 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
 			if (!info->io.regsize)
 				info->io.regsize = DEFAULT_REGSIZE;
 			info->io.regshift = regshift;
-			info->irq = irq;
-			if (info->irq)
+			info->io.irq = irq;
+			if (info->io.irq)
 				info->irq_setup = std_irq_setup;
-			info->slave_addr = ipmb;
+			info->io.slave_addr = ipmb;
 
 			rv = ipmi_si_add_smi(info);
 			if (rv) {
@@ -1964,7 +1943,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
 			list_for_each_entry_safe(e, tmp_e, &smi_infos, link) {
 				if (e->io.addr_type != addr_space)
 					continue;
-				if (e->si_type != si_type)
+				if (e->io.si_type != si_type)
 					continue;
 				if (e->io.addr_data == addr)
 					cleanup_one_si(e);
@@ -1992,15 +1971,15 @@ static int hardcode_find_bmc(void)
 		if (!info)
 			return -ENOMEM;
 
-		info->addr_source = SI_HARDCODED;
+		info->io.addr_source = SI_HARDCODED;
 		pr_info(PFX "probing via hardcoded address\n");
 
 		if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
-			info->si_type = SI_KCS;
+			info->io.si_type = SI_KCS;
 		} else if (strcmp(si_type[i], "smic") == 0) {
-			info->si_type = SI_SMIC;
+			info->io.si_type = SI_SMIC;
 		} else if (strcmp(si_type[i], "bt") == 0) {
-			info->si_type = SI_BT;
+			info->io.si_type = SI_BT;
 		} else {
 			pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
 				i, si_type[i]);
@@ -2033,10 +2012,10 @@ static int hardcode_find_bmc(void)
 		if (!info->io.regsize)
 			info->io.regsize = DEFAULT_REGSIZE;
 		info->io.regshift = regshifts[i];
-		info->irq = irqs[i];
-		if (info->irq)
+		info->io.irq = irqs[i];
+		if (info->io.irq)
 			info->irq_setup = std_irq_setup;
-		info->slave_addr = slave_addrs[i];
+		info->io.slave_addr = slave_addrs[i];
 
 		if (!ipmi_si_add_smi(info)) {
 			mutex_lock(&smi_infos_lock);
@@ -2081,32 +2060,32 @@ static u32 ipmi_acpi_gpe(acpi_handle gpe_device,
 
 static void acpi_gpe_irq_cleanup(struct smi_info *info)
 {
-	if (!info->irq)
+	if (!info->io.irq)
 		return;
 
-	acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe);
+	acpi_remove_gpe_handler(NULL, info->io.irq, &ipmi_acpi_gpe);
 }
 
 static int acpi_gpe_irq_setup(struct smi_info *info)
 {
 	acpi_status status;
 
-	if (!info->irq)
+	if (!info->io.irq)
 		return 0;
 
 	status = acpi_install_gpe_handler(NULL,
-					  info->irq,
+					  info->io.irq,
 					  ACPI_GPE_LEVEL_TRIGGERED,
 					  &ipmi_acpi_gpe,
 					  info);
 	if (status != AE_OK) {
-		dev_warn(info->dev, "%s unable to claim ACPI GPE %d,"
-			 " running polled\n", DEVICE_NAME, info->irq);
-		info->irq = 0;
+		dev_warn(info->io.dev, "%s unable to claim ACPI GPE %d,"
+			 " running polled\n", DEVICE_NAME, info->io.irq);
+		info->io.irq = 0;
 		return -EINVAL;
 	} else {
 		info->irq_cleanup = acpi_gpe_irq_cleanup;
-		dev_info(info->dev, "Using ACPI GPE %d\n", info->irq);
+		dev_info(info->io.dev, "Using ACPI GPE %d\n", info->io.irq);
 		return 0;
 	}
 }
@@ -2173,19 +2152,19 @@ static int try_init_spmi(struct SPMITable *spmi)
 		return -ENOMEM;
 	}
 
-	info->addr_source = SI_SPMI;
+	info->io.addr_source = SI_SPMI;
 	pr_info(PFX "probing via SPMI\n");
 
 	/* Figure out the interface type. */
 	switch (spmi->InterfaceType) {
 	case 1:	/* KCS */
-		info->si_type = SI_KCS;
+		info->io.si_type = SI_KCS;
 		break;
 	case 2:	/* SMIC */
-		info->si_type = SI_SMIC;
+		info->io.si_type = SI_SMIC;
 		break;
 	case 3:	/* BT */
-		info->si_type = SI_BT;
+		info->io.si_type = SI_BT;
 		break;
 	case 4: /* SSIF, just ignore */
 		kfree(info);
@@ -2199,15 +2178,15 @@ static int try_init_spmi(struct SPMITable *spmi)
 
 	if (spmi->InterruptType & 1) {
 		/* We've got a GPE interrupt. */
-		info->irq = spmi->GPE;
+		info->io.irq = spmi->GPE;
 		info->irq_setup = acpi_gpe_irq_setup;
 	} else if (spmi->InterruptType & 2) {
 		/* We've got an APIC/SAPIC interrupt. */
-		info->irq = spmi->GlobalSystemInterrupt;
+		info->io.irq = spmi->GlobalSystemInterrupt;
 		info->irq_setup = std_irq_setup;
 	} else {
 		/* Use the default interrupt setting. */
-		info->irq = 0;
+		info->io.irq = 0;
 		info->irq_setup = NULL;
 	}
 
@@ -2236,7 +2215,7 @@ static int try_init_spmi(struct SPMITable *spmi)
 	pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
 		(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
 		info->io.addr_data, info->io.regsize, info->io.regspacing,
-		info->irq);
+		info->io.irq);
 
 	rv = ipmi_si_add_smi(info);
 	if (rv)
@@ -2330,18 +2309,18 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	info->addr_source = SI_SMBIOS;
+	info->io.addr_source = SI_SMBIOS;
 	pr_info(PFX "probing via SMBIOS\n");
 
 	switch (type) {
 	case IPMI_DMI_TYPE_KCS:
-		info->si_type = SI_KCS;
+		info->io.si_type = SI_KCS;
 		break;
 	case IPMI_DMI_TYPE_SMIC:
-		info->si_type = SI_SMIC;
+		info->io.si_type = SI_SMIC;
 		break;
 	case IPMI_DMI_TYPE_BT:
-		info->si_type = SI_BT;
+		info->io.si_type = SI_BT;
 		break;
 	default:
 		kfree(info);
@@ -2356,23 +2335,23 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
 	rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr);
 	if (rv) {
 		dev_warn(&pdev->dev, "device has no slave-addr property");
-		info->slave_addr = 0x20;
+		info->io.slave_addr = 0x20;
 	} else {
-		info->slave_addr = slave_addr;
+		info->io.slave_addr = slave_addr;
 	}
 
-	info->irq = platform_get_irq(pdev, 0);
-	if (info->irq > 0)
+	info->io.irq = platform_get_irq(pdev, 0);
+	if (info->io.irq > 0)
 		info->irq_setup = std_irq_setup;
 	else
-		info->irq = 0;
+		info->io.irq = 0;
 
-	info->dev = &pdev->dev;
+	info->io.dev = &pdev->dev;
 
 	pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
 		(info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
 		info->io.addr_data, info->io.regsize, info->io.regspacing,
-		info->irq);
+		info->io.irq);
 
 	if (ipmi_si_add_smi(info))
 		kfree(info);
@@ -2403,16 +2382,16 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
 #define PCI_MMC_DEVICE_ID   0x121A
 #define PCI_MMC_ADDR_CW     0x10
 
-static void ipmi_pci_cleanup(struct smi_info *info)
+static void ipmi_pci_cleanup(struct si_sm_io *io)
 {
-	struct pci_dev *pdev = info->addr_source_data;
+	struct pci_dev *pdev = io->addr_source_data;
 
 	pci_disable_device(pdev);
 }
 
 static int ipmi_pci_probe_regspacing(struct smi_info *info)
 {
-	if (info->si_type == SI_KCS) {
+	if (info->io.si_type == SI_KCS) {
 		unsigned char	status;
 		int		regspacing;
 
@@ -2425,7 +2404,7 @@ static int ipmi_pci_probe_regspacing(struct smi_info *info)
 		for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
 			info->io.regspacing = regspacing;
 			if (info->io_setup(info)) {
-				dev_err(info->dev,
+				dev_err(info->io.dev,
 					"Could not setup I/O space\n");
 				return DEFAULT_REGSPACING;
 			}
@@ -2453,20 +2432,20 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
 	if (!info)
 		return -ENOMEM;
 
-	info->addr_source = SI_PCI;
+	info->io.addr_source = SI_PCI;
 	dev_info(&pdev->dev, "probing via PCI");
 
 	switch (class_type) {
 	case PCI_ERMC_CLASSCODE_TYPE_SMIC:
-		info->si_type = SI_SMIC;
+		info->io.si_type = SI_SMIC;
 		break;
 
 	case PCI_ERMC_CLASSCODE_TYPE_KCS:
-		info->si_type = SI_KCS;
+		info->io.si_type = SI_KCS;
 		break;
 
 	case PCI_ERMC_CLASSCODE_TYPE_BT:
-		info->si_type = SI_BT;
+		info->io.si_type = SI_BT;
 		break;
 
 	default:
@@ -2482,8 +2461,8 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
 		return rv;
 	}
 
-	info->addr_source_cleanup = ipmi_pci_cleanup;
-	info->addr_source_data = pdev;
+	info->io.addr_source_cleanup = ipmi_pci_cleanup;
+	info->io.addr_source_data = pdev;
 
 	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
 		info->io_setup = port_setup;
@@ -2498,16 +2477,16 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
 	info->io.regsize = DEFAULT_REGSIZE;
 	info->io.regshift = 0;
 
-	info->irq = pdev->irq;
-	if (info->irq)
+	info->io.irq = pdev->irq;
+	if (info->io.irq)
 		info->irq_setup = std_irq_setup;
 
-	info->dev = &pdev->dev;
+	info->io.dev = &pdev->dev;
 	pci_set_drvdata(pdev, info);
 
 	dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n",
 		&pdev->resource[0], info->io.regsize, info->io.regspacing,
-		info->irq);
+		info->io.irq);
 
 	rv = ipmi_si_add_smi(info);
 	if (rv) {
@@ -2551,19 +2530,19 @@ static const struct of_device_id of_ipmi_match[] = {
 };
 MODULE_DEVICE_TABLE(of, of_ipmi_match);
 
-static int of_ipmi_probe(struct platform_device *dev)
+static int of_ipmi_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct smi_info *info;
 	struct resource resource;
 	const __be32 *regsize, *regspacing, *regshift;
-	struct device_node *np = dev->dev.of_node;
+	struct device_node *np = pdev->dev.of_node;
 	int ret;
 	int proplen;
 
-	dev_info(&dev->dev, "probing via device tree\n");
+	dev_info(&pdev->dev, "probing via device tree\n");
 
-	match = of_match_device(of_ipmi_match, &dev->dev);
+	match = of_match_device(of_ipmi_match, &pdev->dev);
 	if (!match)
 		return -ENODEV;
 
@@ -2572,39 +2551,39 @@ static int of_ipmi_probe(struct platform_device *dev)
 
 	ret = of_address_to_resource(np, 0, &resource);
 	if (ret) {
-		dev_warn(&dev->dev, PFX "invalid address from OF\n");
+		dev_warn(&pdev->dev, PFX "invalid address from OF\n");
 		return ret;
 	}
 
 	regsize = of_get_property(np, "reg-size", &proplen);
 	if (regsize && proplen != 4) {
-		dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
+		dev_warn(&pdev->dev, PFX "invalid regsize from OF\n");
 		return -EINVAL;
 	}
 
 	regspacing = of_get_property(np, "reg-spacing", &proplen);
 	if (regspacing && proplen != 4) {
-		dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
+		dev_warn(&pdev->dev, PFX "invalid regspacing from OF\n");
 		return -EINVAL;
 	}
 
 	regshift = of_get_property(np, "reg-shift", &proplen);
 	if (regshift && proplen != 4) {
-		dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
+		dev_warn(&pdev->dev, PFX "invalid regshift from OF\n");
 		return -EINVAL;
 	}
 
 	info = smi_info_alloc();
 
 	if (!info) {
-		dev_err(&dev->dev,
+		dev_err(&pdev->dev,
 			"could not allocate memory for OF probe\n");
 		return -ENOMEM;
 	}
 
-	info->si_type		= (enum si_type) match->data;
-	info->addr_source	= SI_DEVICETREE;
-	info->irq_setup		= std_irq_setup;
+	info->io.si_type	= (enum si_type) match->data;
+	info->io.addr_source	= SI_DEVICETREE;
+	info->io.irq_setup	= std_irq_setup;
 
 	if (resource.flags & IORESOURCE_IO) {
 		info->io_setup		= port_setup;
@@ -2620,14 +2599,14 @@ static int of_ipmi_probe(struct platform_device *dev)
 	info->io.regspacing	= regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING;
 	info->io.regshift	= regshift ? be32_to_cpup(regshift) : 0;
 
-	info->irq		= irq_of_parse_and_map(dev->dev.of_node, 0);
-	info->dev		= &dev->dev;
+	info->io.irq		= irq_of_parse_and_map(pdev->dev.of_node, 0);
+	info->io.dev		= &pdev->dev;
 
-	dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n",
+	dev_dbg(&pdev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n",
 		info->io.addr_data, info->io.regsize, info->io.regspacing,
-		info->irq);
+		info->io.irq);
 
-	dev_set_drvdata(&dev->dev, info);
+	dev_set_drvdata(&pdev->dev, info);
 
 	ret = ipmi_si_add_smi(info);
 	if (ret) {
@@ -2652,7 +2631,7 @@ static int find_slave_address(struct smi_info *info, int slave_addr)
 		int type = -1;
 		u32 flags = IORESOURCE_IO;
 
-		switch (info->si_type) {
+		switch (info->io.si_type) {
 		case SI_KCS:
 			type = IPMI_DMI_TYPE_KCS;
 			break;
@@ -2675,7 +2654,7 @@ static int find_slave_address(struct smi_info *info, int slave_addr)
 	return slave_addr;
 }
 
-static int acpi_ipmi_probe(struct platform_device *dev)
+static int acpi_ipmi_probe(struct platform_device *pdev)
 {
 	struct smi_info *info;
 	acpi_handle handle;
@@ -2687,7 +2666,7 @@ static int acpi_ipmi_probe(struct platform_device *dev)
 	if (!si_tryacpi)
 		return -ENODEV;
 
-	handle = ACPI_HANDLE(&dev->dev);
+	handle = ACPI_HANDLE(&pdev->dev);
 	if (!handle)
 		return -ENODEV;
 
@@ -2695,37 +2674,38 @@ static int acpi_ipmi_probe(struct platform_device *dev)
 	if (!info)
 		return -ENOMEM;
 
-	info->addr_source = SI_ACPI;
-	dev_info(&dev->dev, PFX "probing via ACPI\n");
+	info->io.addr_source = SI_ACPI;
+	dev_info(&pdev->dev, PFX "probing via ACPI\n");
 
 	info->addr_info.acpi_info.acpi_handle = handle;
 
 	/* _IFT tells us the interface type: KCS, BT, etc */
 	status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
 	if (ACPI_FAILURE(status)) {
-		dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n");
+		dev_err(&pdev->dev,
+			"Could not find ACPI IPMI interface type\n");
 		goto err_free;
 	}
 
 	switch (tmp) {
 	case 1:
-		info->si_type = SI_KCS;
+		info->io.si_type = SI_KCS;
 		break;
 	case 2:
-		info->si_type = SI_SMIC;
+		info->io.si_type = SI_SMIC;
 		break;
 	case 3:
-		info->si_type = SI_BT;
+		info->io.si_type = SI_BT;
 		break;
 	case 4: /* SSIF, just ignore */
 		rv = -ENODEV;
 		goto err_free;
 	default:
-		dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp);
+		dev_info(&pdev->dev, "unknown IPMI type %lld\n", tmp);
 		goto err_free;
 	}
 
-	res = ipmi_get_info_from_resources(dev, info);
+	res = ipmi_get_info_from_resources(pdev, info);
 	if (!res) {
 		rv = -EINVAL;
 		goto err_free;
@@ -2734,25 +2714,25 @@ static int acpi_ipmi_probe(struct platform_device *dev)
 	/* If _GPE exists, use it; otherwise use standard interrupts */
 	status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
 	if (ACPI_SUCCESS(status)) {
-		info->irq = tmp;
+		info->io.irq = tmp;
 		info->irq_setup = acpi_gpe_irq_setup;
 	} else {
-		int irq = platform_get_irq(dev, 0);
+		int irq = platform_get_irq(pdev, 0);
 
 		if (irq > 0) {
-			info->irq = irq;
+			info->io.irq = irq;
 			info->irq_setup = std_irq_setup;
 		}
 	}
 
-	info->slave_addr = find_slave_address(info, info->slave_addr);
+	info->io.slave_addr = find_slave_address(info, info->io.slave_addr);
 
-	info->dev = &dev->dev;
-	platform_set_drvdata(dev, info);
+	info->io.dev = &pdev->dev;
+	platform_set_drvdata(pdev, info);
 
-	dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n",
+	dev_info(info->io.dev, "%pR regsize %d spacing %d irq %d\n",
 		 res, info->io.regsize, info->io.regspacing,
-		 info->irq);
+		 info->io.irq);
 
 	rv = ipmi_si_add_smi(info);
 	if (rv)
@@ -2777,20 +2757,20 @@ static int acpi_ipmi_probe(struct platform_device *dev)
 }
 #endif
 
-static int ipmi_probe(struct platform_device *dev)
+static int ipmi_probe(struct platform_device *pdev)
 {
-	if (dev->dev.of_node && of_ipmi_probe(dev) == 0)
+	if (pdev->dev.of_node && of_ipmi_probe(pdev) == 0)
 		return 0;
 
-	if (acpi_ipmi_probe(dev) == 0)
+	if (acpi_ipmi_probe(pdev) == 0)
 		return 0;
 
-	return dmi_ipmi_probe(dev);
+	return dmi_ipmi_probe(pdev);
 }
 
-static int ipmi_remove(struct platform_device *dev)
+static int ipmi_remove(struct platform_device *pdev)
 {
-	struct smi_info *info = dev_get_drvdata(&dev->dev);
+	struct smi_info *info = dev_get_drvdata(&pdev->dev);
 
 	cleanup_one_si(info);
 	return 0;
@@ -2820,17 +2800,17 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev)
 		return -ENOMEM;
 	}
 
-	info->si_type		= SI_KCS;
-	info->addr_source	= SI_DEVICETREE;
+	info->io.si_type	= SI_KCS;
+	info->io.addr_source	= SI_DEVICETREE;
 	info->io_setup		= mem_setup;
 	info->io.addr_type	= IPMI_MEM_ADDR_SPACE;
 	info->io.addr_data	= dev->hpa.start;
 	info->io.regsize	= 1;
 	info->io.regspacing	= 1;
 	info->io.regshift	= 0;
-	info->irq		= 0; /* no interrupt */
+	info->io.irq		= 0; /* no interrupt */
 	info->irq_setup		= NULL;
-	info->dev		= &dev->dev;
+	info->io.dev		= &dev->dev;
 
 	dev_dbg(&dev->dev, "addr 0x%lx\n", info->io.addr_data);
 
@@ -2945,7 +2925,7 @@ static int get_global_enables(struct smi_info *smi_info, u8 *enables)
 
 	rv = wait_for_msg_done(smi_info);
 	if (rv) {
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "Error getting response from get global enables command: %d\n",
 			 rv);
 		goto out;
@@ -2958,7 +2938,7 @@ static int get_global_enables(struct smi_info *smi_info, u8 *enables)
 			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
 			resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD   ||
 			resp[2] != 0) {
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "Invalid return from get global enables command: %ld %x %x %x\n",
 			 resp_len, resp[0], resp[1], resp[2]);
 		rv = -EINVAL;
@@ -2993,7 +2973,7 @@ static int set_global_enables(struct smi_info *smi_info, u8 enables)
 
 	rv = wait_for_msg_done(smi_info);
 	if (rv) {
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "Error getting response from set global enables command: %d\n",
 			 rv);
 		goto out;
@@ -3005,7 +2985,7 @@ static int set_global_enables(struct smi_info *smi_info, u8 enables)
 	if (resp_len < 3 ||
 			resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 ||
 			resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) {
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "Invalid return from set global enables command: %ld %x %x\n",
 			 resp_len, resp[0], resp[1]);
 		rv = -EINVAL;
@@ -3041,7 +3021,7 @@ static void check_clr_rcv_irq(struct smi_info *smi_info)
 	}
 
 	if (rv < 0) {
-		dev_err(smi_info->dev,
+		dev_err(smi_info->io.dev,
 			"Cannot check clearing the rcv irq: %d\n", rv);
 		return;
 	}
@@ -3051,7 +3031,7 @@ static void check_clr_rcv_irq(struct smi_info *smi_info)
 		 * An error when setting the event buffer bit means
 		 * clearing the bit is not supported.
 		 */
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "The BMC does not support clearing the recv irq bit, compensating, but the BMC needs to be fixed.\n");
 		smi_info->cannot_disable_irq = true;
 	}
@@ -3067,7 +3047,7 @@ static void check_set_rcv_irq(struct smi_info *smi_info)
 	u8 enables = 0;
 	int rv;
 
-	if (!smi_info->irq)
+	if (!smi_info->io.irq)
 		return;
 
 	rv = get_global_enables(smi_info, &enables);
@@ -3077,7 +3057,7 @@ static void check_set_rcv_irq(struct smi_info *smi_info)
 	}
 
 	if (rv < 0) {
-		dev_err(smi_info->dev,
+		dev_err(smi_info->io.dev,
 			"Cannot check setting the rcv irq: %d\n", rv);
 		return;
 	}
@@ -3087,7 +3067,7 @@ static void check_set_rcv_irq(struct smi_info *smi_info)
 		 * An error when setting the event buffer bit means
 		 * setting the bit is not supported.
 		 */
-		dev_warn(smi_info->dev,
+		dev_warn(smi_info->io.dev,
 			 "The BMC does not support setting the recv irq bit, compensating, but the BMC needs to be fixed.\n");
 		smi_info->cannot_disable_irq = true;
 		smi_info->irq_enable_broken = true;
@@ -3173,7 +3153,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v)
 {
 	struct smi_info *smi = m->private;
 
-	seq_printf(m, "%s\n", si_to_str[smi->si_type]);
+	seq_printf(m, "%s\n", si_to_str[smi->io.si_type]);
 
 	return 0;
 }
@@ -3195,7 +3175,7 @@ static int smi_si_stats_proc_show(struct seq_file *m, void *v)
 	struct smi_info *smi = m->private;
 
 	seq_printf(m, "interrupts_enabled:    %d\n",
-		       smi->irq && !smi->interrupt_disabled);
+		       smi->io.irq && !smi->interrupt_disabled);
 	seq_printf(m, "short_timeouts:        %u\n",
 		       smi_get_stat(smi, short_timeouts));
 	seq_printf(m, "long_timeouts:         %u\n",
@@ -3239,14 +3219,14 @@ static int smi_params_proc_show(struct seq_file *m, void *v)
 
 	seq_printf(m,
 		   "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
-		   si_to_str[smi->si_type],
+		   si_to_str[smi->io.si_type],
 		   addr_space_to_str[smi->io.addr_type],
 		   smi->io.addr_data,
 		   smi->io.regspacing,
 		   smi->io.regsize,
 		   smi->io.regshift,
-		   smi->irq,
-		   smi->slave_addr);
+		   smi->io.irq,
+		   smi->io.slave_addr);
 
 	return 0;
 }
@@ -3384,7 +3364,7 @@ setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
 {
 	struct ipmi_device_id *id = &smi_info->device_id;
 	if (id->manufacturer_id == DELL_IANA_MFR_ID &&
-	    smi_info->si_type == SI_BT)
+	    smi_info->io.si_type == SI_BT)
 		register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
 }
 
@@ -3433,8 +3413,8 @@ static struct smi_info *find_dup_si(struct smi_info *info)
 			 * slave address but SMBIOS does.  Pick it up from
 			 * any source that has it available.
 			 */
-			if (info->slave_addr && !e->slave_addr)
-				e->slave_addr = info->slave_addr;
+			if (info->io.slave_addr && !e->io.slave_addr)
+				e->io.slave_addr = info->io.slave_addr;
 			return e;
 		}
 	}
@@ -3450,26 +3430,26 @@ int ipmi_si_add_smi(struct smi_info *new_smi)
 	mutex_lock(&smi_infos_lock);
 	dup = find_dup_si(new_smi);
 	if (dup) {
-		if (new_smi->addr_source == SI_ACPI &&
-		    dup->addr_source == SI_SMBIOS) {
+		if (new_smi->io.addr_source == SI_ACPI &&
+		    dup->io.addr_source == SI_SMBIOS) {
 			/* We prefer ACPI over SMBIOS. */
-			dev_info(dup->dev,
+			dev_info(dup->io.dev,
 				 "Removing SMBIOS-specified %s state machine in favor of ACPI\n",
-				 si_to_str[new_smi->si_type]);
+				 si_to_str[new_smi->io.si_type]);
 			cleanup_one_si(dup);
 		} else {
-			dev_info(new_smi->dev,
+			dev_info(new_smi->io.dev,
 				 "%s-specified %s state machine: duplicate\n",
-				 ipmi_addr_src_to_str(new_smi->addr_source),
-				 si_to_str[new_smi->si_type]);
+				 ipmi_addr_src_to_str(new_smi->io.addr_source),
+				 si_to_str[new_smi->io.si_type]);
 			rv = -EBUSY;
 			goto out_err;
 		}
 	}
 
 	pr_info(PFX "Adding %s-specified %s state machine\n",
-		ipmi_addr_src_to_str(new_smi->addr_source),
-		si_to_str[new_smi->si_type]);
+		ipmi_addr_src_to_str(new_smi->io.addr_source),
+		si_to_str[new_smi->io.si_type]);
 
 	/* So we know not to free it unless we have allocated one. */
 	new_smi->intf = NULL;
@@ -3495,13 +3475,13 @@ static int try_smi_init(struct smi_info *new_smi)
 	char *init_name = NULL;
 
 	pr_info(PFX "Trying %s-specified %s state machine at %s address 0x%lx, slave address 0x%x, irq %d\n",
-		ipmi_addr_src_to_str(new_smi->addr_source),
-		si_to_str[new_smi->si_type],
+		ipmi_addr_src_to_str(new_smi->io.addr_source),
+		si_to_str[new_smi->io.si_type],
 		addr_space_to_str[new_smi->io.addr_type],
 		new_smi->io.addr_data,
-		new_smi->slave_addr, new_smi->irq);
+		new_smi->io.slave_addr, new_smi->io.irq);
 
-	switch (new_smi->si_type) {
+	switch (new_smi->io.si_type) {
 	case SI_KCS:
 		new_smi->handlers = &kcs_smi_handlers;
 		break;
@@ -3523,7 +3503,7 @@ static int try_smi_init(struct smi_info *new_smi)
 	new_smi->intf_num = smi_num;
 
 	/* Do this early so it's available for logs. */
-	if (!new_smi->dev) {
+	if (!new_smi->io.dev) {
 		init_name = kasprintf(GFP_KERNEL, "ipmi_si.%d",
 				      new_smi->intf_num);
 
@@ -3537,10 +3517,10 @@ static int try_smi_init(struct smi_info *new_smi)
 			pr_err(PFX "Unable to allocate platform device\n");
 			goto out_err;
 		}
-		new_smi->dev = &new_smi->pdev->dev;
-		new_smi->dev->driver = &ipmi_driver.driver;
+		new_smi->io.dev = &new_smi->pdev->dev;
+		new_smi->io.dev->driver = &ipmi_driver.driver;
 		/* Nulled by device_add() */
-		new_smi->dev->init_name = init_name;
+		new_smi->io.dev->init_name = init_name;
 	}
 
 	/* Allocate the state machine's data and initialize it. */
@@ -3556,14 +3536,15 @@ static int try_smi_init(struct smi_info *new_smi)
 	/* Now that we know the I/O size, we can set up the I/O. */
 	rv = new_smi->io_setup(new_smi);
 	if (rv) {
-		dev_err(new_smi->dev, "Could not set up I/O space\n");
+		dev_err(new_smi->io.dev, "Could not set up I/O space\n");
 		goto out_err;
 	}
 
 	/* Do low-level detection first. */
 	if (new_smi->handlers->detect(new_smi->si_sm)) {
-		if (new_smi->addr_source)
-			dev_err(new_smi->dev, "Interface detection failed\n");
+		if (new_smi->io.addr_source)
+			dev_err(new_smi->io.dev,
+				"Interface detection failed\n");
 		rv = -ENODEV;
 		goto out_err;
 	}
@@ -3574,8 +3555,9 @@ static int try_smi_init(struct smi_info *new_smi)
 	 */
 	rv = try_get_dev_id(new_smi);
 	if (rv) {
-		if (new_smi->addr_source)
-			dev_err(new_smi->dev, "There appears to be no BMC at this location\n");
+		if (new_smi->io.addr_source)
+			dev_err(new_smi->io.dev,
+			       "There appears to be no BMC at this location\n");
 		goto out_err;
 	}
 
@@ -3607,7 +3589,7 @@ static int try_smi_init(struct smi_info *new_smi)
 	 * IRQ is defined to be set when non-zero.  req_events will
 	 * cause a global flags check that will enable interrupts.
 	 */
-	if (new_smi->irq) {
+	if (new_smi->io.irq) {
 		new_smi->interrupt_disabled = false;
 		atomic_set(&new_smi->req_events, 1);
 	}
@@ -3615,20 +3597,20 @@ static int try_smi_init(struct smi_info *new_smi)
 	if (new_smi->pdev) {
 		rv = platform_device_add(new_smi->pdev);
 		if (rv) {
-			dev_err(new_smi->dev,
+			dev_err(new_smi->io.dev,
 				"Unable to register system interface device: %d\n",
 				rv);
 			goto out_err;
 		}
-		new_smi->dev_registered = true;
 	}
 
 	rv = ipmi_register_smi(&handlers,
 			       new_smi,
-			       new_smi->dev,
-			       new_smi->slave_addr);
+			       new_smi->io.dev,
+			       new_smi->io.slave_addr);
 	if (rv) {
-		dev_err(new_smi->dev, "Unable to register device: error %d\n",
+		dev_err(new_smi->io.dev,
+			"Unable to register device: error %d\n",
 			rv);
 		goto out_err_stop_timer;
 	}
@@ -3637,7 +3619,8 @@ static int try_smi_init(struct smi_info *new_smi)
 				     &smi_type_proc_ops,
 				     new_smi);
 	if (rv) {
-		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
+		dev_err(new_smi->io.dev,
+			"Unable to create proc entry: %d\n", rv);
 		goto out_err_stop_timer;
 	}
 
@@ -3645,7 +3628,8 @@ static int try_smi_init(struct smi_info *new_smi)
 				     &smi_si_stats_proc_ops,
 				     new_smi);
 	if (rv) {
-		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
+		dev_err(new_smi->io.dev,
+			"Unable to create proc entry: %d\n", rv);
 		goto out_err_stop_timer;
 	}
 
@@ -3653,17 +3637,18 @@ static int try_smi_init(struct smi_info *new_smi)
 				     &smi_params_proc_ops,
 				     new_smi);
 	if (rv) {
-		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
+		dev_err(new_smi->io.dev,
+			"Unable to create proc entry: %d\n", rv);
 		goto out_err_stop_timer;
 	}
 
 	/* Don't increment till we know we have succeeded. */
 	smi_num++;
 
-	dev_info(new_smi->dev, "IPMI %s interface initialized\n",
-		 si_to_str[new_smi->si_type]);
+	dev_info(new_smi->io.dev, "IPMI %s interface initialized\n",
+		 si_to_str[new_smi->io.si_type]);
 
-	WARN_ON(new_smi->dev->init_name != NULL);
+	WARN_ON(new_smi->io.dev->init_name != NULL);
 	kfree(init_name);
 
 	return 0;
@@ -3698,22 +3683,20 @@ static int try_smi_init(struct smi_info *new_smi)
 		kfree(new_smi->si_sm);
 		new_smi->si_sm = NULL;
 	}
-	if (new_smi->addr_source_cleanup) {
-		new_smi->addr_source_cleanup(new_smi);
-		new_smi->addr_source_cleanup = NULL;
+	if (new_smi->io.addr_source_cleanup) {
+		new_smi->io.addr_source_cleanup(&new_smi->io);
+		new_smi->io.addr_source_cleanup = NULL;
 	}
 	if (new_smi->io_cleanup) {
 		new_smi->io_cleanup(new_smi);
 		new_smi->io_cleanup = NULL;
 	}
 
-	if (new_smi->dev_registered) {
+	if (new_smi->pdev) {
 		platform_device_unregister(new_smi->pdev);
-		new_smi->dev_registered = false;
 		new_smi->pdev = NULL;
 	} else if (new_smi->pdev) {
 		platform_device_put(new_smi->pdev);
-		new_smi->pdev = NULL;
 	}
 
 	kfree(init_name);
@@ -3792,9 +3775,9 @@ static int init_ipmi_si(void)
 		/* Try to register a device if it has an IRQ and we either
 		   haven't successfully registered a device yet or this
 		   device has the same type as one we successfully registered */
-		if (e->irq && (!type || e->addr_source == type)) {
+		if (e->io.irq && (!type || e->io.addr_source == type)) {
 			if (!try_smi_init(e)) {
-				type = e->addr_source;
+				type = e->io.addr_source;
 			}
 		}
 	}
@@ -3808,9 +3791,9 @@ static int init_ipmi_si(void)
 	/* Fall back to the preferred device */
 
 	list_for_each_entry(e, &smi_infos, link) {
-		if (!e->irq && (!type || e->addr_source == type)) {
+		if (!e->io.irq && (!type || e->io.addr_source == type)) {
 			if (!try_smi_init(e)) {
-				type = e->addr_source;
+				type = e->io.addr_source;
 			}
 		}
 	}
@@ -3850,8 +3833,8 @@ static void cleanup_one_si(struct smi_info *to_clean)
 		}
 	}
 
-	if (to_clean->dev)
-		dev_set_drvdata(to_clean->dev, NULL);
+	if (to_clean->io.dev)
+		dev_set_drvdata(to_clean->io.dev, NULL);
 
 	list_del(&to_clean->link);
 
@@ -3884,12 +3867,12 @@ static void cleanup_one_si(struct smi_info *to_clean)
 
 	kfree(to_clean->si_sm);
 
-	if (to_clean->addr_source_cleanup)
-		to_clean->addr_source_cleanup(to_clean);
+	if (to_clean->io.addr_source_cleanup)
+		to_clean->io.addr_source_cleanup(&to_clean->io);
 	if (to_clean->io_cleanup)
 		to_clean->io_cleanup(to_clean);
 
-	if (to_clean->dev_registered)
+	if (to_clean->pdev)
 		platform_device_unregister(to_clean->pdev);
 
 	kfree(to_clean);
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index a705027c0493..ffbf67f630a9 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -34,12 +34,18 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/ipmi.h>
+
 /*
  * This is defined by the state machines themselves, it is an opaque
  * data type for them to use.
  */
 struct si_sm_data;
 
+enum si_type {
+	SI_KCS, SI_SMIC, SI_BT
+};
+
 /*
  * The structure for doing I/O in the state machine.  The state
  * machine doesn't have the actual I/O routines, they are done through
@@ -61,6 +67,14 @@ struct si_sm_io {
 	int  regshift;
 	int addr_type;
 	long addr_data;
+	enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */
+	void (*addr_source_cleanup)(struct si_sm_io *io);
+	void *addr_source_data;
+
+	int irq;
+	u8 slave_addr;
+	enum si_type si_type;
+	struct device *dev;
 };
 
 /* Results of SMI events. */
-- 
2.19.2