Blob Blame History Raw
From 13d0b35c5c201e8e6ee520b223c88f58d022a37f Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Tue, 12 Sep 2017 23:04:35 -0500
Subject: [PATCH] ipmi_si: Move PCI setup to another file
Git-commit: 13d0b35c5c201e8e6ee520b223c88f58d022a37f
Patch-mainline: v4.15-rc1
References: FATE#326156

Signed-off-by: Corey Minyard <cminyard@mvista.com>

Stephen Rothwell <sfr@canb.auug.org.au> fixed an issue with the
include files

Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/char/ipmi/Makefile       |   3 +
 drivers/char/ipmi/ipmi_si.h      |   8 ++
 drivers/char/ipmi/ipmi_si_intf.c | 163 +-----------------------------
 drivers/char/ipmi/ipmi_si_pci.c  | 166 +++++++++++++++++++++++++++++++
 4 files changed, 179 insertions(+), 161 deletions(-)
 create mode 100644 drivers/char/ipmi/ipmi_si_pci.c

diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
index fa3858f472ac..55ec4a3d7d07 100644
--- a/drivers/char/ipmi/Makefile
+++ b/drivers/char/ipmi/Makefile
@@ -4,6 +4,9 @@
 
 ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o \
 	ipmi_si_hotmod.o ipmi_si_hardcode.o ipmi_si_platform.o
+ifdef CONFIG_PCI
+ipmi_si-y += ipmi_si_pci.o
+endif
 
 obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
 obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
diff --git a/drivers/char/ipmi/ipmi_si.h b/drivers/char/ipmi/ipmi_si.h
index ff9a30a1ead5..7627e9ada017 100644
--- a/drivers/char/ipmi/ipmi_si.h
+++ b/drivers/char/ipmi/ipmi_si.h
@@ -29,3 +29,11 @@ void ipmi_si_platform_init(void);
 void ipmi_si_platform_shutdown(void);
 
 extern struct platform_driver ipmi_platform_driver;
+
+#ifdef CONFIG_PCI
+void ipmi_si_pci_init(void);
+void ipmi_si_pci_shutdown(void);
+#else
+static inline void ipmi_si_pci_init(void) { }
+static inline void ipmi_si_pci_shutdown(void) { }
+#endif
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index bfc052bdbdd7..a2be633697e8 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -49,7 +49,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/list.h>
-#include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
@@ -283,9 +282,6 @@ struct smi_info {
 #define IPMI_MAX_INTFS 4
 static int force_kipmid[IPMI_MAX_INTFS];
 static int num_force_kipmid;
-#ifdef CONFIG_PCI
-static bool pci_registered;
-#endif
 #ifdef CONFIG_PARISC
 static bool parisc_registered;
 #endif
@@ -1263,17 +1259,8 @@ static LIST_HEAD(smi_infos);
 static DEFINE_MUTEX(smi_infos_lock);
 static int smi_num; /* Used to sequence the SMIs */
 
-#ifdef CONFIG_PCI
-static bool          si_trypci = true;
-#endif
-
 static const char * const addr_space_to_str[] = { "i/o", "mem" };
 
-#ifdef CONFIG_PCI
-module_param_named(trypci, si_trypci, bool, 0);
-MODULE_PARM_DESC(trypci, "Setting this to zero will disable the"
-		 " default scan of the interfaces identified via pci");
-#endif
 module_param_array(force_kipmid, int, &num_force_kipmid, 0);
 MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
 		 " disabled(0).  Normally the IPMI driver auto-detects"
@@ -1594,140 +1581,6 @@ static struct smi_info *smi_info_alloc(void)
 	return info;
 }
 
-#ifdef CONFIG_PCI
-
-#define PCI_ERMC_CLASSCODE		0x0C0700
-#define PCI_ERMC_CLASSCODE_MASK		0xffffff00
-#define PCI_ERMC_CLASSCODE_TYPE_MASK	0xff
-#define PCI_ERMC_CLASSCODE_TYPE_SMIC	0x00
-#define PCI_ERMC_CLASSCODE_TYPE_KCS	0x01
-#define PCI_ERMC_CLASSCODE_TYPE_BT	0x02
-
-#define PCI_HP_VENDOR_ID    0x103C
-#define PCI_MMC_DEVICE_ID   0x121A
-#define PCI_MMC_ADDR_CW     0x10
-
-static void ipmi_pci_cleanup(struct si_sm_io *io)
-{
-	struct pci_dev *pdev = io->addr_source_data;
-
-	pci_disable_device(pdev);
-}
-
-static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
-{
-	if (io->si_type == SI_KCS) {
-		unsigned char	status;
-		int		regspacing;
-
-		io->regsize = DEFAULT_REGSIZE;
-		io->regshift = 0;
-
-		/* detect 1, 4, 16byte spacing */
-		for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
-			io->regspacing = regspacing;
-			if (io->io_setup(io)) {
-				dev_err(io->dev,
-					"Could not setup I/O space\n");
-				return DEFAULT_REGSPACING;
-			}
-			/* write invalid cmd */
-			io->outputb(io, 1, 0x10);
-			/* read status back */
-			status = io->inputb(io, 1);
-			io->io_cleanup(io);
-			if (status)
-				return regspacing;
-			regspacing *= 4;
-		}
-	}
-	return DEFAULT_REGSPACING;
-}
-
-static int ipmi_pci_probe(struct pci_dev *pdev,
-				    const struct pci_device_id *ent)
-{
-	int rv;
-	int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK;
-	struct si_sm_io io;
-
-	memset(&io, 0, sizeof(io));
-	io.addr_source = SI_PCI;
-	dev_info(&pdev->dev, "probing via PCI");
-
-	switch (class_type) {
-	case PCI_ERMC_CLASSCODE_TYPE_SMIC:
-		io.si_type = SI_SMIC;
-		break;
-
-	case PCI_ERMC_CLASSCODE_TYPE_KCS:
-		io.si_type = SI_KCS;
-		break;
-
-	case PCI_ERMC_CLASSCODE_TYPE_BT:
-		io.si_type = SI_BT;
-		break;
-
-	default:
-		dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type);
-		return -ENOMEM;
-	}
-
-	rv = pci_enable_device(pdev);
-	if (rv) {
-		dev_err(&pdev->dev, "couldn't enable PCI device\n");
-		return rv;
-	}
-
-	io.addr_source_cleanup = ipmi_pci_cleanup;
-	io.addr_source_data = pdev;
-
-	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO)
-		io.addr_type = IPMI_IO_ADDR_SPACE;
-	else
-		io.addr_type = IPMI_MEM_ADDR_SPACE;
-	io.addr_data = pci_resource_start(pdev, 0);
-
-	io.regspacing = ipmi_pci_probe_regspacing(&io);
-	io.regsize = DEFAULT_REGSIZE;
-	io.regshift = 0;
-
-	io.irq = pdev->irq;
-	if (io.irq)
-		io.irq_setup = ipmi_std_irq_setup;
-
-	io.dev = &pdev->dev;
-
-	dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n",
-		&pdev->resource[0], io.regsize, io.regspacing, io.irq);
-
-	rv = ipmi_si_add_smi(&io);
-	if (rv)
-		pci_disable_device(pdev);
-
-	return rv;
-}
-
-static void ipmi_pci_remove(struct pci_dev *pdev)
-{
-	ipmi_si_remove_by_dev(&pdev->dev);
-}
-
-static const struct pci_device_id ipmi_pci_devices[] = {
-	{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
-	{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
-
-static struct pci_driver ipmi_pci_driver = {
-	.name =         DEVICE_NAME,
-	.id_table =     ipmi_pci_devices,
-	.probe =        ipmi_pci_probe,
-	.remove =       ipmi_pci_remove,
-};
-#endif /* CONFIG_PCI */
-
 #ifdef CONFIG_PARISC
 static int __init ipmi_parisc_probe(struct parisc_device *dev)
 {
@@ -2653,7 +2506,6 @@ static int try_smi_init(struct smi_info *new_smi)
 
 static int init_ipmi_si(void)
 {
-	int  rv;
 	struct smi_info *e;
 	enum ipmi_addr_src type = SI_INVALID;
 
@@ -2668,15 +2520,7 @@ static int init_ipmi_si(void)
 
 	ipmi_si_platform_init();
 
-#ifdef CONFIG_PCI
-	if (si_trypci) {
-		rv = pci_register_driver(&ipmi_pci_driver);
-		if (rv)
-			pr_err(PFX "Unable to register PCI driver: %d\n", rv);
-		else
-			pci_registered = true;
-	}
-#endif
+	ipmi_si_pci_init();
 
 #ifdef CONFIG_PARISC
 	register_parisc_driver(&ipmi_parisc_driver);
@@ -2837,10 +2681,7 @@ static void cleanup_ipmi_si(void)
 	if (!initialized)
 		return;
 
-#ifdef CONFIG_PCI
-	if (pci_registered)
-		pci_unregister_driver(&ipmi_pci_driver);
-#endif
+	ipmi_si_pci_shutdown();
 #ifdef CONFIG_PARISC
 	if (parisc_registered)
 		unregister_parisc_driver(&ipmi_parisc_driver);
diff --git a/drivers/char/ipmi/ipmi_si_pci.c b/drivers/char/ipmi/ipmi_si_pci.c
new file mode 100644
index 000000000000..99771f5cad07
--- /dev/null
+++ b/drivers/char/ipmi/ipmi_si_pci.c
@@ -0,0 +1,166 @@
+/*
+ * ipmi_si_pci.c
+ *
+ * Handling for IPMI devices on the PCI bus.
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include "ipmi_si.h"
+
+#define PFX "ipmi_pci: "
+
+static bool pci_registered;
+
+static bool si_trypci = true;
+
+module_param_named(trypci, si_trypci, bool, 0);
+MODULE_PARM_DESC(trypci, "Setting this to zero will disable the"
+		 " default scan of the interfaces identified via pci");
+
+#define PCI_ERMC_CLASSCODE		0x0C0700
+#define PCI_ERMC_CLASSCODE_MASK		0xffffff00
+#define PCI_ERMC_CLASSCODE_TYPE_MASK	0xff
+#define PCI_ERMC_CLASSCODE_TYPE_SMIC	0x00
+#define PCI_ERMC_CLASSCODE_TYPE_KCS	0x01
+#define PCI_ERMC_CLASSCODE_TYPE_BT	0x02
+
+#define PCI_HP_VENDOR_ID    0x103C
+#define PCI_MMC_DEVICE_ID   0x121A
+#define PCI_MMC_ADDR_CW     0x10
+
+static void ipmi_pci_cleanup(struct si_sm_io *io)
+{
+	struct pci_dev *pdev = io->addr_source_data;
+
+	pci_disable_device(pdev);
+}
+
+static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
+{
+	if (io->si_type == SI_KCS) {
+		unsigned char	status;
+		int		regspacing;
+
+		io->regsize = DEFAULT_REGSIZE;
+		io->regshift = 0;
+
+		/* detect 1, 4, 16byte spacing */
+		for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
+			io->regspacing = regspacing;
+			if (io->io_setup(io)) {
+				dev_err(io->dev,
+					"Could not setup I/O space\n");
+				return DEFAULT_REGSPACING;
+			}
+			/* write invalid cmd */
+			io->outputb(io, 1, 0x10);
+			/* read status back */
+			status = io->inputb(io, 1);
+			io->io_cleanup(io);
+			if (status)
+				return regspacing;
+			regspacing *= 4;
+		}
+	}
+	return DEFAULT_REGSPACING;
+}
+
+static int ipmi_pci_probe(struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
+{
+	int rv;
+	int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK;
+	struct si_sm_io io;
+
+	memset(&io, 0, sizeof(io));
+	io.addr_source = SI_PCI;
+	dev_info(&pdev->dev, "probing via PCI");
+
+	switch (class_type) {
+	case PCI_ERMC_CLASSCODE_TYPE_SMIC:
+		io.si_type = SI_SMIC;
+		break;
+
+	case PCI_ERMC_CLASSCODE_TYPE_KCS:
+		io.si_type = SI_KCS;
+		break;
+
+	case PCI_ERMC_CLASSCODE_TYPE_BT:
+		io.si_type = SI_BT;
+		break;
+
+	default:
+		dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type);
+		return -ENOMEM;
+	}
+
+	rv = pci_enable_device(pdev);
+	if (rv) {
+		dev_err(&pdev->dev, "couldn't enable PCI device\n");
+		return rv;
+	}
+
+	io.addr_source_cleanup = ipmi_pci_cleanup;
+	io.addr_source_data = pdev;
+
+	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO)
+		io.addr_type = IPMI_IO_ADDR_SPACE;
+	else
+		io.addr_type = IPMI_MEM_ADDR_SPACE;
+	io.addr_data = pci_resource_start(pdev, 0);
+
+	io.regspacing = ipmi_pci_probe_regspacing(&io);
+	io.regsize = DEFAULT_REGSIZE;
+	io.regshift = 0;
+
+	io.irq = pdev->irq;
+	if (io.irq)
+		io.irq_setup = ipmi_std_irq_setup;
+
+	io.dev = &pdev->dev;
+
+	dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n",
+		&pdev->resource[0], io.regsize, io.regspacing, io.irq);
+
+	rv = ipmi_si_add_smi(&io);
+	if (rv)
+		pci_disable_device(pdev);
+
+	return rv;
+}
+
+static void ipmi_pci_remove(struct pci_dev *pdev)
+{
+	ipmi_si_remove_by_dev(&pdev->dev);
+}
+
+static const struct pci_device_id ipmi_pci_devices[] = {
+	{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
+	{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
+
+static struct pci_driver ipmi_pci_driver = {
+	.name =         DEVICE_NAME,
+	.id_table =     ipmi_pci_devices,
+	.probe =        ipmi_pci_probe,
+	.remove =       ipmi_pci_remove,
+};
+
+void ipmi_si_pci_init(void)
+{
+	if (si_trypci) {
+		int rv = pci_register_driver(&ipmi_pci_driver);
+		if (rv)
+			pr_err(PFX "Unable to register PCI driver: %d\n", rv);
+		else
+			pci_registered = true;
+	}
+}
+
+void ipmi_si_pci_shutdown(void)
+{
+	if (pci_registered)
+		pci_unregister_driver(&ipmi_pci_driver);
+}
-- 
2.19.2