aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2017-09-12 22:37:02 -0400
committerCorey Minyard <cminyard@mvista.com>2017-09-27 17:03:45 -0400
commitbb398a4cb09a0ed96cf0fc2e90012cf6bf13a824 (patch)
treed51217564b1fa5cd871dde7657a768d8e900c281
parente1eeb7f8620733fe9f6640eef48d449b925b3c23 (diff)
ipmi_si: Change ipmi_si_add_smi() to take just I/O info
Instead of allocating the smi_info structure, filling in the I/O info, and passing it to ipmi_si_add_smi(), just pass the I/O info in the io structure and let ipmi_si_add_smi() allocate the smi_info structure. This required redoing the way the remove functions for some device interfaces worked, a new function named ipmi_si_remove_by_dev() allows the device to be passed in and detected instead of using driver data, which couldn't be filled out easily othersize. After this the platform handling should be decoupled from the smi_info structure and that handling can be pulled out to its own files. Signed-off-by: Corey Minyard <cminyard@mvista.com>
-rw-r--r--drivers/char/ipmi/ipmi_si.h5
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c532
-rw-r--r--drivers/char/ipmi/ipmi_si_sm.h1
3 files changed, 229 insertions, 309 deletions
diff --git a/drivers/char/ipmi/ipmi_si.h b/drivers/char/ipmi/ipmi_si.h
index e84651acd772..9573b35d73af 100644
--- a/drivers/char/ipmi/ipmi_si.h
+++ b/drivers/char/ipmi/ipmi_si.h
@@ -14,10 +14,9 @@
14#define DEFAULT_REGSPACING 1 14#define DEFAULT_REGSPACING 1
15#define DEFAULT_REGSIZE 1 15#define DEFAULT_REGSIZE 1
16 16
17struct smi_info; 17int ipmi_si_add_smi(struct si_sm_io *io);
18
19int ipmi_si_add_smi(struct smi_info *info);
20irqreturn_t ipmi_si_irq_handler(int irq, void *data); 18irqreturn_t ipmi_si_irq_handler(int irq, void *data);
21void ipmi_irq_start_cleanup(struct si_sm_io *io); 19void ipmi_irq_start_cleanup(struct si_sm_io *io);
22int ipmi_std_irq_setup(struct si_sm_io *io); 20int ipmi_std_irq_setup(struct si_sm_io *io);
23void ipmi_irq_finish_setup(struct si_sm_io *io); 21void ipmi_irq_finish_setup(struct si_sm_io *io);
22int ipmi_si_remove_by_dev(struct device *dev);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index d0a0a5d9e5ff..6c2e14af8321 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -110,6 +110,8 @@ static const char * const si_to_str[] = { "kcs", "smic", "bt" };
110 110
111static struct platform_driver ipmi_driver; 111static struct platform_driver ipmi_driver;
112 112
113static int initialized;
114
113/* 115/*
114 * Indexes into stats[] in smi_info below. 116 * Indexes into stats[] in smi_info below.
115 */ 117 */
@@ -282,7 +284,6 @@ struct smi_info {
282 struct task_struct *thread; 284 struct task_struct *thread;
283 285
284 struct list_head link; 286 struct list_head link;
285 union ipmi_smi_info_union addr_info;
286}; 287};
287 288
288#define smi_inc_stat(smi, stat) \ 289#define smi_inc_stat(smi, stat) \
@@ -1126,8 +1127,6 @@ static void set_need_watch(void *send_info, bool enable)
1126 spin_unlock_irqrestore(&smi_info->si_lock, flags); 1127 spin_unlock_irqrestore(&smi_info->si_lock, flags);
1127} 1128}
1128 1129
1129static int initialized;
1130
1131static void smi_timeout(unsigned long data) 1130static void smi_timeout(unsigned long data)
1132{ 1131{
1133 struct smi_info *smi_info = (struct smi_info *) data; 1132 struct smi_info *smi_info = (struct smi_info *) data;
@@ -1245,7 +1244,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
1245 1244
1246 data->addr_src = smi->io.addr_source; 1245 data->addr_src = smi->io.addr_source;
1247 data->dev = smi->io.dev; 1246 data->dev = smi->io.dev;
1248 data->addr_info = smi->addr_info; 1247 data->addr_info = smi->io.addr_info;
1249 get_device(smi->io.dev); 1248 get_device(smi->io.dev);
1250 1249
1251 return 0; 1250 return 0;
@@ -1795,7 +1794,6 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
1795 int ipmb; 1794 int ipmb;
1796 int ival; 1795 int ival;
1797 int len; 1796 int len;
1798 struct smi_info *info;
1799 1797
1800 if (!str) 1798 if (!str)
1801 return -ENOMEM; 1799 return -ENOMEM;
@@ -1890,42 +1888,30 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
1890 } 1888 }
1891 1889
1892 if (op == HM_ADD) { 1890 if (op == HM_ADD) {
1893 info = smi_info_alloc(); 1891 struct si_sm_io io;
1894 if (!info) { 1892
1895 rv = -ENOMEM; 1893 memset(&io, 0, sizeof(io));
1896 goto out; 1894 io.addr_source = SI_HOTMOD;
1897 } 1895 io.si_type = si_type;
1898 1896 io.addr_data = addr;
1899 info->io.addr_source = SI_HOTMOD; 1897 io.addr_type = addr_space;
1900 info->io.si_type = si_type; 1898
1901 info->io.addr_data = addr; 1899 io.addr = NULL;
1902 info->io.addr_type = addr_space; 1900 io.regspacing = regspacing;
1903 1901 if (!io.regspacing)
1904 info->io.addr = NULL; 1902 io.regspacing = DEFAULT_REGSPACING;
1905 info->io.regspacing = regspacing; 1903 io.regsize = regsize;
1906 if (!info->io.regspacing) 1904 if (!io.regsize)
1907 info->io.regspacing = DEFAULT_REGSPACING; 1905 io.regsize = DEFAULT_REGSIZE;
1908 info->io.regsize = regsize; 1906 io.regshift = regshift;
1909 if (!info->io.regsize) 1907 io.irq = irq;
1910 info->io.regsize = DEFAULT_REGSIZE; 1908 if (io.irq)
1911 info->io.regshift = regshift; 1909 io.irq_setup = ipmi_std_irq_setup;
1912 info->io.irq = irq; 1910 io.slave_addr = ipmb;
1913 if (info->io.irq) 1911
1914 info->io.irq_setup = ipmi_std_irq_setup; 1912 rv = ipmi_si_add_smi(&io);
1915 info->io.slave_addr = ipmb; 1913 if (rv)
1916
1917 rv = ipmi_si_add_smi(info);
1918 if (rv) {
1919 kfree(info);
1920 goto out; 1914 goto out;
1921 }
1922 mutex_lock(&smi_infos_lock);
1923 rv = try_smi_init(info);
1924 mutex_unlock(&smi_infos_lock);
1925 if (rv) {
1926 cleanup_one_si(info);
1927 goto out;
1928 }
1929 } else { 1915 } else {
1930 /* remove */ 1916 /* remove */
1931 struct smi_info *e, *tmp_e; 1917 struct smi_info *e, *tmp_e;
@@ -1952,69 +1938,56 @@ static int hardcode_find_bmc(void)
1952{ 1938{
1953 int ret = -ENODEV; 1939 int ret = -ENODEV;
1954 int i; 1940 int i;
1955 struct smi_info *info; 1941 struct si_sm_io io;
1956 1942
1943 memset(&io, 0, sizeof(io));
1957 for (i = 0; i < SI_MAX_PARMS; i++) { 1944 for (i = 0; i < SI_MAX_PARMS; i++) {
1958 if (!ports[i] && !addrs[i]) 1945 if (!ports[i] && !addrs[i])
1959 continue; 1946 continue;
1960 1947
1961 info = smi_info_alloc(); 1948 io.addr_source = SI_HARDCODED;
1962 if (!info)
1963 return -ENOMEM;
1964
1965 info->io.addr_source = SI_HARDCODED;
1966 pr_info(PFX "probing via hardcoded address\n"); 1949 pr_info(PFX "probing via hardcoded address\n");
1967 1950
1968 if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { 1951 if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
1969 info->io.si_type = SI_KCS; 1952 io.si_type = SI_KCS;
1970 } else if (strcmp(si_type[i], "smic") == 0) { 1953 } else if (strcmp(si_type[i], "smic") == 0) {
1971 info->io.si_type = SI_SMIC; 1954 io.si_type = SI_SMIC;
1972 } else if (strcmp(si_type[i], "bt") == 0) { 1955 } else if (strcmp(si_type[i], "bt") == 0) {
1973 info->io.si_type = SI_BT; 1956 io.si_type = SI_BT;
1974 } else { 1957 } else {
1975 pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n", 1958 pr_warn(PFX "Interface type specified for interface %d, was invalid: %s\n",
1976 i, si_type[i]); 1959 i, si_type[i]);
1977 kfree(info);
1978 continue; 1960 continue;
1979 } 1961 }
1980 1962
1981 if (ports[i]) { 1963 if (ports[i]) {
1982 /* An I/O port */ 1964 /* An I/O port */
1983 info->io.addr_data = ports[i]; 1965 io.addr_data = ports[i];
1984 info->io.addr_type = IPMI_IO_ADDR_SPACE; 1966 io.addr_type = IPMI_IO_ADDR_SPACE;
1985 } else if (addrs[i]) { 1967 } else if (addrs[i]) {
1986 /* A memory port */ 1968 /* A memory port */
1987 info->io.addr_data = addrs[i]; 1969 io.addr_data = addrs[i];
1988 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 1970 io.addr_type = IPMI_MEM_ADDR_SPACE;
1989 } else { 1971 } else {
1990 pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n", 1972 pr_warn(PFX "Interface type specified for interface %d, but port and address were not set or set to zero.\n",
1991 i); 1973 i);
1992 kfree(info);
1993 continue; 1974 continue;
1994 } 1975 }
1995 1976
1996 info->io.addr = NULL; 1977 io.addr = NULL;
1997 info->io.regspacing = regspacings[i]; 1978 io.regspacing = regspacings[i];
1998 if (!info->io.regspacing) 1979 if (!io.regspacing)
1999 info->io.regspacing = DEFAULT_REGSPACING; 1980 io.regspacing = DEFAULT_REGSPACING;
2000 info->io.regsize = regsizes[i]; 1981 io.regsize = regsizes[i];
2001 if (!info->io.regsize) 1982 if (!io.regsize)
2002 info->io.regsize = DEFAULT_REGSIZE; 1983 io.regsize = DEFAULT_REGSIZE;
2003 info->io.regshift = regshifts[i]; 1984 io.regshift = regshifts[i];
2004 info->io.irq = irqs[i]; 1985 io.irq = irqs[i];
2005 if (info->io.irq) 1986 if (io.irq)
2006 info->io.irq_setup = ipmi_std_irq_setup; 1987 io.irq_setup = ipmi_std_irq_setup;
2007 info->io.slave_addr = slave_addrs[i]; 1988 io.slave_addr = slave_addrs[i];
2008 1989
2009 if (!ipmi_si_add_smi(info)) { 1990 ret = ipmi_si_add_smi(&io);
2010 mutex_lock(&smi_infos_lock);
2011 if (try_smi_init(info))
2012 cleanup_one_si(info);
2013 mutex_unlock(&smi_infos_lock);
2014 ret = 0;
2015 } else {
2016 kfree(info);
2017 }
2018 } 1991 }
2019 return ret; 1992 return ret;
2020} 1993}
@@ -2121,88 +2094,74 @@ struct SPMITable {
2121 2094
2122static int try_init_spmi(struct SPMITable *spmi) 2095static int try_init_spmi(struct SPMITable *spmi)
2123{ 2096{
2124 struct smi_info *info; 2097 struct si_sm_io io;
2125 int rv;
2126 2098
2127 if (spmi->IPMIlegacy != 1) { 2099 if (spmi->IPMIlegacy != 1) {
2128 pr_info(PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); 2100 pr_info(PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
2129 return -ENODEV; 2101 return -ENODEV;
2130 } 2102 }
2131 2103
2132 info = smi_info_alloc(); 2104 memset(&io, 0, sizeof(io));
2133 if (!info) { 2105 io.addr_source = SI_SPMI;
2134 pr_err(PFX "Could not allocate SI data (3)\n");
2135 return -ENOMEM;
2136 }
2137
2138 info->io.addr_source = SI_SPMI;
2139 pr_info(PFX "probing via SPMI\n"); 2106 pr_info(PFX "probing via SPMI\n");
2140 2107
2141 /* Figure out the interface type. */ 2108 /* Figure out the interface type. */
2142 switch (spmi->InterfaceType) { 2109 switch (spmi->InterfaceType) {
2143 case 1: /* KCS */ 2110 case 1: /* KCS */
2144 info->io.si_type = SI_KCS; 2111 io.si_type = SI_KCS;
2145 break; 2112 break;
2146 case 2: /* SMIC */ 2113 case 2: /* SMIC */
2147 info->io.si_type = SI_SMIC; 2114 io.si_type = SI_SMIC;
2148 break; 2115 break;
2149 case 3: /* BT */ 2116 case 3: /* BT */
2150 info->io.si_type = SI_BT; 2117 io.si_type = SI_BT;
2151 break; 2118 break;
2152 case 4: /* SSIF, just ignore */ 2119 case 4: /* SSIF, just ignore */
2153 kfree(info);
2154 return -EIO; 2120 return -EIO;
2155 default: 2121 default:
2156 pr_info(PFX "Unknown ACPI/SPMI SI type %d\n", 2122 pr_info(PFX "Unknown ACPI/SPMI SI type %d\n",
2157 spmi->InterfaceType); 2123 spmi->InterfaceType);
2158 kfree(info);
2159 return -EIO; 2124 return -EIO;
2160 } 2125 }
2161 2126
2162 if (spmi->InterruptType & 1) { 2127 if (spmi->InterruptType & 1) {
2163 /* We've got a GPE interrupt. */ 2128 /* We've got a GPE interrupt. */
2164 info->io.irq = spmi->GPE; 2129 io.irq = spmi->GPE;
2165 info->io.irq_setup = acpi_gpe_irq_setup; 2130 io.irq_setup = acpi_gpe_irq_setup;
2166 } else if (spmi->InterruptType & 2) { 2131 } else if (spmi->InterruptType & 2) {
2167 /* We've got an APIC/SAPIC interrupt. */ 2132 /* We've got an APIC/SAPIC interrupt. */
2168 info->io.irq = spmi->GlobalSystemInterrupt; 2133 io.irq = spmi->GlobalSystemInterrupt;
2169 info->io.irq_setup = ipmi_std_irq_setup; 2134 io.irq_setup = ipmi_std_irq_setup;
2170 } else { 2135 } else {
2171 /* Use the default interrupt setting. */ 2136 /* Use the default interrupt setting. */
2172 info->io.irq = 0; 2137 io.irq = 0;
2173 info->io.irq_setup = NULL; 2138 io.irq_setup = NULL;
2174 } 2139 }
2175 2140
2176 if (spmi->addr.bit_width) { 2141 if (spmi->addr.bit_width) {
2177 /* A (hopefully) properly formed register bit width. */ 2142 /* A (hopefully) properly formed register bit width. */
2178 info->io.regspacing = spmi->addr.bit_width / 8; 2143 io.regspacing = spmi->addr.bit_width / 8;
2179 } else { 2144 } else {
2180 info->io.regspacing = DEFAULT_REGSPACING; 2145 io.regspacing = DEFAULT_REGSPACING;
2181 } 2146 }
2182 info->io.regsize = info->io.regspacing; 2147 io.regsize = io.regspacing;
2183 info->io.regshift = spmi->addr.bit_offset; 2148 io.regshift = spmi->addr.bit_offset;
2184 2149
2185 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 2150 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
2186 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 2151 io.addr_type = IPMI_MEM_ADDR_SPACE;
2187 } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 2152 } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
2188 info->io.addr_type = IPMI_IO_ADDR_SPACE; 2153 io.addr_type = IPMI_IO_ADDR_SPACE;
2189 } else { 2154 } else {
2190 kfree(info);
2191 pr_warn(PFX "Unknown ACPI I/O Address type\n"); 2155 pr_warn(PFX "Unknown ACPI I/O Address type\n");
2192 return -EIO; 2156 return -EIO;
2193 } 2157 }
2194 info->io.addr_data = spmi->addr.address; 2158 io.addr_data = spmi->addr.address;
2195 2159
2196 pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n", 2160 pr_info("ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n",
2197 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", 2161 (io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
2198 info->io.addr_data, info->io.regsize, info->io.regspacing, 2162 io.addr_data, io.regsize, io.regspacing, io.irq);
2199 info->io.irq);
2200
2201 rv = ipmi_si_add_smi(info);
2202 if (rv)
2203 kfree(info);
2204 2163
2205 return rv; 2164 return ipmi_si_add_smi(&io);
2206} 2165}
2207 2166
2208static void spmi_find_bmc(void) 2167static void spmi_find_bmc(void)
@@ -2231,36 +2190,35 @@ static void spmi_find_bmc(void)
2231#if defined(CONFIG_DMI) || defined(CONFIG_ACPI) 2190#if defined(CONFIG_DMI) || defined(CONFIG_ACPI)
2232static struct resource * 2191static struct resource *
2233ipmi_get_info_from_resources(struct platform_device *pdev, 2192ipmi_get_info_from_resources(struct platform_device *pdev,
2234 struct smi_info *info) 2193 struct si_sm_io *io)
2235{ 2194{
2236 struct resource *res, *res_second; 2195 struct resource *res, *res_second;
2237 2196
2238 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 2197 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
2239 if (res) { 2198 if (res) {
2240 info->io.addr_type = IPMI_IO_ADDR_SPACE; 2199 io->addr_type = IPMI_IO_ADDR_SPACE;
2241 } else { 2200 } else {
2242 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2201 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2243 if (res) 2202 if (res)
2244 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 2203 io->addr_type = IPMI_MEM_ADDR_SPACE;
2245 } 2204 }
2246 if (!res) { 2205 if (!res) {
2247 dev_err(&pdev->dev, "no I/O or memory address\n"); 2206 dev_err(&pdev->dev, "no I/O or memory address\n");
2248 return NULL; 2207 return NULL;
2249 } 2208 }
2250 info->io.addr_data = res->start; 2209 io->addr_data = res->start;
2251 2210
2252 info->io.regspacing = DEFAULT_REGSPACING; 2211 io->regspacing = DEFAULT_REGSPACING;
2253 res_second = platform_get_resource(pdev, 2212 res_second = platform_get_resource(pdev,
2254 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? 2213 (io->addr_type == IPMI_IO_ADDR_SPACE) ?
2255 IORESOURCE_IO : IORESOURCE_MEM, 2214 IORESOURCE_IO : IORESOURCE_MEM,
2256 1); 2215 1);
2257 if (res_second) { 2216 if (res_second) {
2258 if (res_second->start > info->io.addr_data) 2217 if (res_second->start > io->addr_data)
2259 info->io.regspacing = 2218 io->regspacing = res_second->start - io->addr_data;
2260 res_second->start - info->io.addr_data;
2261 } 2219 }
2262 info->io.regsize = DEFAULT_REGSIZE; 2220 io->regsize = DEFAULT_REGSIZE;
2263 info->io.regshift = 0; 2221 io->regshift = 0;
2264 2222
2265 return res; 2223 return res;
2266} 2224}
@@ -2270,7 +2228,7 @@ ipmi_get_info_from_resources(struct platform_device *pdev,
2270#ifdef CONFIG_DMI 2228#ifdef CONFIG_DMI
2271static int dmi_ipmi_probe(struct platform_device *pdev) 2229static int dmi_ipmi_probe(struct platform_device *pdev)
2272{ 2230{
2273 struct smi_info *info; 2231 struct si_sm_io io;
2274 u8 type, slave_addr; 2232 u8 type, slave_addr;
2275 int rv; 2233 int rv;
2276 2234
@@ -2281,31 +2239,25 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
2281 if (rv) 2239 if (rv)
2282 return -ENODEV; 2240 return -ENODEV;
2283 2241
2284 info = smi_info_alloc(); 2242 memset(&io, 0, sizeof(io));
2285 if (!info) { 2243 io.addr_source = SI_SMBIOS;
2286 pr_err(PFX "Could not allocate SI data\n");
2287 return -ENOMEM;
2288 }
2289
2290 info->io.addr_source = SI_SMBIOS;
2291 pr_info(PFX "probing via SMBIOS\n"); 2244 pr_info(PFX "probing via SMBIOS\n");
2292 2245
2293 switch (type) { 2246 switch (type) {
2294 case IPMI_DMI_TYPE_KCS: 2247 case IPMI_DMI_TYPE_KCS:
2295 info->io.si_type = SI_KCS; 2248 io.si_type = SI_KCS;
2296 break; 2249 break;
2297 case IPMI_DMI_TYPE_SMIC: 2250 case IPMI_DMI_TYPE_SMIC:
2298 info->io.si_type = SI_SMIC; 2251 io.si_type = SI_SMIC;
2299 break; 2252 break;
2300 case IPMI_DMI_TYPE_BT: 2253 case IPMI_DMI_TYPE_BT:
2301 info->io.si_type = SI_BT; 2254 io.si_type = SI_BT;
2302 break; 2255 break;
2303 default: 2256 default:
2304 kfree(info);
2305 return -EINVAL; 2257 return -EINVAL;
2306 } 2258 }
2307 2259
2308 if (!ipmi_get_info_from_resources(pdev, info)) { 2260 if (!ipmi_get_info_from_resources(pdev, &io)) {
2309 rv = -EINVAL; 2261 rv = -EINVAL;
2310 goto err_free; 2262 goto err_free;
2311 } 2263 }
@@ -2313,31 +2265,28 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
2313 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr); 2265 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr);
2314 if (rv) { 2266 if (rv) {
2315 dev_warn(&pdev->dev, "device has no slave-addr property"); 2267 dev_warn(&pdev->dev, "device has no slave-addr property");
2316 info->io.slave_addr = 0x20; 2268 io.slave_addr = 0x20;
2317 } else { 2269 } else {
2318 info->io.slave_addr = slave_addr; 2270 io.slave_addr = slave_addr;
2319 } 2271 }
2320 2272
2321 info->io.irq = platform_get_irq(pdev, 0); 2273 io.irq = platform_get_irq(pdev, 0);
2322 if (info->io.irq > 0) 2274 if (io.irq > 0)
2323 info->io.irq_setup = ipmi_std_irq_setup; 2275 io.irq_setup = ipmi_std_irq_setup;
2324 else 2276 else
2325 info->io.irq = 0; 2277 io.irq = 0;
2326 2278
2327 info->io.dev = &pdev->dev; 2279 io.dev = &pdev->dev;
2328 2280
2329 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", 2281 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
2330 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", 2282 (io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
2331 info->io.addr_data, info->io.regsize, info->io.regspacing, 2283 io.addr_data, io.regsize, io.regspacing, io.irq);
2332 info->io.irq);
2333 2284
2334 if (ipmi_si_add_smi(info)) 2285 ipmi_si_add_smi(&io);
2335 kfree(info);
2336 2286
2337 return 0; 2287 return 0;
2338 2288
2339err_free: 2289err_free:
2340 kfree(info);
2341 return rv; 2290 return rv;
2342} 2291}
2343#else 2292#else
@@ -2367,30 +2316,28 @@ static void ipmi_pci_cleanup(struct si_sm_io *io)
2367 pci_disable_device(pdev); 2316 pci_disable_device(pdev);
2368} 2317}
2369 2318
2370static int ipmi_pci_probe_regspacing(struct smi_info *info) 2319static int ipmi_pci_probe_regspacing(struct si_sm_io *io)
2371{ 2320{
2372 if (info->io.si_type == SI_KCS) { 2321 if (io->si_type == SI_KCS) {
2373 unsigned char status; 2322 unsigned char status;
2374 int regspacing; 2323 int regspacing;
2375 2324
2376 info->io.regsize = DEFAULT_REGSIZE; 2325 io->regsize = DEFAULT_REGSIZE;
2377 info->io.regshift = 0; 2326 io->regshift = 0;
2378 info->io.io_size = 2;
2379 info->handlers = &kcs_smi_handlers;
2380 2327
2381 /* detect 1, 4, 16byte spacing */ 2328 /* detect 1, 4, 16byte spacing */
2382 for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) { 2329 for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
2383 info->io.regspacing = regspacing; 2330 io->regspacing = regspacing;
2384 if (info->io.io_setup(&info->io)) { 2331 if (io->io_setup(io)) {
2385 dev_err(info->io.dev, 2332 dev_err(io->dev,
2386 "Could not setup I/O space\n"); 2333 "Could not setup I/O space\n");
2387 return DEFAULT_REGSPACING; 2334 return DEFAULT_REGSPACING;
2388 } 2335 }
2389 /* write invalid cmd */ 2336 /* write invalid cmd */
2390 info->io.outputb(&info->io, 1, 0x10); 2337 io->outputb(io, 1, 0x10);
2391 /* read status back */ 2338 /* read status back */
2392 status = info->io.inputb(&info->io, 1); 2339 status = io->inputb(io, 1);
2393 info->io.io_cleanup(&info->io); 2340 io->io_cleanup(io);
2394 if (status) 2341 if (status)
2395 return regspacing; 2342 return regspacing;
2396 regspacing *= 4; 2343 regspacing *= 4;
@@ -2404,30 +2351,26 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
2404{ 2351{
2405 int rv; 2352 int rv;
2406 int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; 2353 int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK;
2407 struct smi_info *info; 2354 struct si_sm_io io;
2408
2409 info = smi_info_alloc();
2410 if (!info)
2411 return -ENOMEM;
2412 2355
2413 info->io.addr_source = SI_PCI; 2356 memset(&io, 0, sizeof(io));
2357 io.addr_source = SI_PCI;
2414 dev_info(&pdev->dev, "probing via PCI"); 2358 dev_info(&pdev->dev, "probing via PCI");
2415 2359
2416 switch (class_type) { 2360 switch (class_type) {
2417 case PCI_ERMC_CLASSCODE_TYPE_SMIC: 2361 case PCI_ERMC_CLASSCODE_TYPE_SMIC:
2418 info->io.si_type = SI_SMIC; 2362 io.si_type = SI_SMIC;
2419 break; 2363 break;
2420 2364
2421 case PCI_ERMC_CLASSCODE_TYPE_KCS: 2365 case PCI_ERMC_CLASSCODE_TYPE_KCS:
2422 info->io.si_type = SI_KCS; 2366 io.si_type = SI_KCS;
2423 break; 2367 break;
2424 2368
2425 case PCI_ERMC_CLASSCODE_TYPE_BT: 2369 case PCI_ERMC_CLASSCODE_TYPE_BT:
2426 info->io.si_type = SI_BT; 2370 io.si_type = SI_BT;
2427 break; 2371 break;
2428 2372
2429 default: 2373 default:
2430 kfree(info);
2431 dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type); 2374 dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type);
2432 return -ENOMEM; 2375 return -ENOMEM;
2433 } 2376 }
@@ -2435,47 +2378,41 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
2435 rv = pci_enable_device(pdev); 2378 rv = pci_enable_device(pdev);
2436 if (rv) { 2379 if (rv) {
2437 dev_err(&pdev->dev, "couldn't enable PCI device\n"); 2380 dev_err(&pdev->dev, "couldn't enable PCI device\n");
2438 kfree(info);
2439 return rv; 2381 return rv;
2440 } 2382 }
2441 2383
2442 info->io.addr_source_cleanup = ipmi_pci_cleanup; 2384 io.addr_source_cleanup = ipmi_pci_cleanup;
2443 info->io.addr_source_data = pdev; 2385 io.addr_source_data = pdev;
2444 2386
2445 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) 2387 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO)
2446 info->io.addr_type = IPMI_IO_ADDR_SPACE; 2388 io.addr_type = IPMI_IO_ADDR_SPACE;
2447 else 2389 else
2448 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 2390 io.addr_type = IPMI_MEM_ADDR_SPACE;
2449 info->io.addr_data = pci_resource_start(pdev, 0); 2391 io.addr_data = pci_resource_start(pdev, 0);
2450 2392
2451 info->io.regspacing = ipmi_pci_probe_regspacing(info); 2393 io.regspacing = ipmi_pci_probe_regspacing(&io);
2452 info->io.regsize = DEFAULT_REGSIZE; 2394 io.regsize = DEFAULT_REGSIZE;
2453 info->io.regshift = 0; 2395 io.regshift = 0;
2454 2396
2455 info->io.irq = pdev->irq; 2397 io.irq = pdev->irq;
2456 if (info->io.irq) 2398 if (io.irq)
2457 info->io.irq_setup = ipmi_std_irq_setup; 2399 io.irq_setup = ipmi_std_irq_setup;
2458 2400
2459 info->io.dev = &pdev->dev; 2401 io.dev = &pdev->dev;
2460 pci_set_drvdata(pdev, info);
2461 2402
2462 dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n", 2403 dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n",
2463 &pdev->resource[0], info->io.regsize, info->io.regspacing, 2404 &pdev->resource[0], io.regsize, io.regspacing, io.irq);
2464 info->io.irq);
2465 2405
2466 rv = ipmi_si_add_smi(info); 2406 rv = ipmi_si_add_smi(&io);
2467 if (rv) { 2407 if (rv)
2468 kfree(info);
2469 pci_disable_device(pdev); 2408 pci_disable_device(pdev);
2470 }
2471 2409
2472 return rv; 2410 return rv;
2473} 2411}
2474 2412
2475static void ipmi_pci_remove(struct pci_dev *pdev) 2413static void ipmi_pci_remove(struct pci_dev *pdev)
2476{ 2414{
2477 struct smi_info *info = pci_get_drvdata(pdev); 2415 ipmi_si_remove_by_dev(&pdev->dev);
2478 cleanup_one_si(info);
2479} 2416}
2480 2417
2481static const struct pci_device_id ipmi_pci_devices[] = { 2418static const struct pci_device_id ipmi_pci_devices[] = {
@@ -2508,7 +2445,7 @@ MODULE_DEVICE_TABLE(of, of_ipmi_match);
2508static int of_ipmi_probe(struct platform_device *pdev) 2445static int of_ipmi_probe(struct platform_device *pdev)
2509{ 2446{
2510 const struct of_device_id *match; 2447 const struct of_device_id *match;
2511 struct smi_info *info; 2448 struct si_sm_io io;
2512 struct resource resource; 2449 struct resource resource;
2513 const __be32 *regsize, *regspacing, *regshift; 2450 const __be32 *regsize, *regspacing, *regshift;
2514 struct device_node *np = pdev->dev.of_node; 2451 struct device_node *np = pdev->dev.of_node;
@@ -2548,44 +2485,29 @@ static int of_ipmi_probe(struct platform_device *pdev)
2548 return -EINVAL; 2485 return -EINVAL;
2549 } 2486 }
2550 2487
2551 info = smi_info_alloc(); 2488 memset(&io, 0, sizeof(io));
2552 2489 io.si_type = (enum si_type) match->data;
2553 if (!info) { 2490 io.addr_source = SI_DEVICETREE;
2554 dev_err(&pdev->dev, 2491 io.irq_setup = ipmi_std_irq_setup;
2555 "could not allocate memory for OF probe\n");
2556 return -ENOMEM;
2557 }
2558
2559 info->io.si_type = (enum si_type) match->data;
2560 info->io.addr_source = SI_DEVICETREE;
2561 info->io.irq_setup = ipmi_std_irq_setup;
2562 2492
2563 if (resource.flags & IORESOURCE_IO) 2493 if (resource.flags & IORESOURCE_IO)
2564 info->io.addr_type = IPMI_IO_ADDR_SPACE; 2494 io.addr_type = IPMI_IO_ADDR_SPACE;
2565 else 2495 else
2566 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 2496 io.addr_type = IPMI_MEM_ADDR_SPACE;
2567 2497
2568 info->io.addr_data = resource.start; 2498 io.addr_data = resource.start;
2569 2499
2570 info->io.regsize = regsize ? be32_to_cpup(regsize) : DEFAULT_REGSIZE; 2500 io.regsize = regsize ? be32_to_cpup(regsize) : DEFAULT_REGSIZE;
2571 info->io.regspacing = regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING; 2501 io.regspacing = regspacing ? be32_to_cpup(regspacing) : DEFAULT_REGSPACING;
2572 info->io.regshift = regshift ? be32_to_cpup(regshift) : 0; 2502 io.regshift = regshift ? be32_to_cpup(regshift) : 0;
2573 2503
2574 info->io.irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 2504 io.irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
2575 info->io.dev = &pdev->dev; 2505 io.dev = &pdev->dev;
2576 2506
2577 dev_dbg(&pdev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n", 2507 dev_dbg(&pdev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n",
2578 info->io.addr_data, info->io.regsize, info->io.regspacing, 2508 io.addr_data, io.regsize, io.regspacing, io.irq);
2579 info->io.irq);
2580
2581 dev_set_drvdata(&pdev->dev, info);
2582 2509
2583 ret = ipmi_si_add_smi(info); 2510 return ipmi_si_add_smi(&io);
2584 if (ret) {
2585 kfree(info);
2586 return ret;
2587 }
2588 return 0;
2589} 2511}
2590#else 2512#else
2591#define of_ipmi_match NULL 2513#define of_ipmi_match NULL
@@ -2596,14 +2518,14 @@ static int of_ipmi_probe(struct platform_device *dev)
2596#endif 2518#endif
2597 2519
2598#ifdef CONFIG_ACPI 2520#ifdef CONFIG_ACPI
2599static int find_slave_address(struct smi_info *info, int slave_addr) 2521static int find_slave_address(struct si_sm_io *io, int slave_addr)
2600{ 2522{
2601#ifdef CONFIG_IPMI_DMI_DECODE 2523#ifdef CONFIG_IPMI_DMI_DECODE
2602 if (!slave_addr) { 2524 if (!slave_addr) {
2603 int type = -1; 2525 int type = -1;
2604 u32 flags = IORESOURCE_IO; 2526 u32 flags = IORESOURCE_IO;
2605 2527
2606 switch (info->io.si_type) { 2528 switch (io->si_type) {
2607 case SI_KCS: 2529 case SI_KCS:
2608 type = IPMI_DMI_TYPE_KCS; 2530 type = IPMI_DMI_TYPE_KCS;
2609 break; 2531 break;
@@ -2615,11 +2537,11 @@ static int find_slave_address(struct smi_info *info, int slave_addr)
2615 break; 2537 break;
2616 } 2538 }
2617 2539
2618 if (info->io.addr_type == IPMI_MEM_ADDR_SPACE) 2540 if (io->addr_type == IPMI_MEM_ADDR_SPACE)
2619 flags = IORESOURCE_MEM; 2541 flags = IORESOURCE_MEM;
2620 2542
2621 slave_addr = ipmi_dmi_get_slave_addr(type, flags, 2543 slave_addr = ipmi_dmi_get_slave_addr(type, flags,
2622 info->io.addr_data); 2544 io->addr_data);
2623 } 2545 }
2624#endif 2546#endif
2625 2547
@@ -2628,7 +2550,7 @@ static int find_slave_address(struct smi_info *info, int slave_addr)
2628 2550
2629static int acpi_ipmi_probe(struct platform_device *pdev) 2551static int acpi_ipmi_probe(struct platform_device *pdev)
2630{ 2552{
2631 struct smi_info *info; 2553 struct si_sm_io io;
2632 acpi_handle handle; 2554 acpi_handle handle;
2633 acpi_status status; 2555 acpi_status status;
2634 unsigned long long tmp; 2556 unsigned long long tmp;
@@ -2642,14 +2564,11 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
2642 if (!handle) 2564 if (!handle)
2643 return -ENODEV; 2565 return -ENODEV;
2644 2566
2645 info = smi_info_alloc(); 2567 memset(&io, 0, sizeof(io));
2646 if (!info) 2568 io.addr_source = SI_ACPI;
2647 return -ENOMEM;
2648
2649 info->io.addr_source = SI_ACPI;
2650 dev_info(&pdev->dev, PFX "probing via ACPI\n"); 2569 dev_info(&pdev->dev, PFX "probing via ACPI\n");
2651 2570
2652 info->addr_info.acpi_info.acpi_handle = handle; 2571 io.addr_info.acpi_info.acpi_handle = handle;
2653 2572
2654 /* _IFT tells us the interface type: KCS, BT, etc */ 2573 /* _IFT tells us the interface type: KCS, BT, etc */
2655 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); 2574 status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
@@ -2661,13 +2580,13 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
2661 2580
2662 switch (tmp) { 2581 switch (tmp) {
2663 case 1: 2582 case 1:
2664 info->io.si_type = SI_KCS; 2583 io.si_type = SI_KCS;
2665 break; 2584 break;
2666 case 2: 2585 case 2:
2667 info->io.si_type = SI_SMIC; 2586 io.si_type = SI_SMIC;
2668 break; 2587 break;
2669 case 3: 2588 case 3:
2670 info->io.si_type = SI_BT; 2589 io.si_type = SI_BT;
2671 break; 2590 break;
2672 case 4: /* SSIF, just ignore */ 2591 case 4: /* SSIF, just ignore */
2673 rv = -ENODEV; 2592 rv = -ENODEV;
@@ -2677,7 +2596,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
2677 goto err_free; 2596 goto err_free;
2678 } 2597 }
2679 2598
2680 res = ipmi_get_info_from_resources(pdev, info); 2599 res = ipmi_get_info_from_resources(pdev, &io);
2681 if (!res) { 2600 if (!res) {
2682 rv = -EINVAL; 2601 rv = -EINVAL;
2683 goto err_free; 2602 goto err_free;
@@ -2686,34 +2605,27 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
2686 /* If _GPE exists, use it; otherwise use standard interrupts */ 2605 /* If _GPE exists, use it; otherwise use standard interrupts */
2687 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); 2606 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
2688 if (ACPI_SUCCESS(status)) { 2607 if (ACPI_SUCCESS(status)) {
2689 info->io.irq = tmp; 2608 io.irq = tmp;
2690 info->io.irq_setup = acpi_gpe_irq_setup; 2609 io.irq_setup = acpi_gpe_irq_setup;
2691 } else { 2610 } else {
2692 int irq = platform_get_irq(pdev, 0); 2611 int irq = platform_get_irq(pdev, 0);
2693 2612
2694 if (irq > 0) { 2613 if (irq > 0) {
2695 info->io.irq = irq; 2614 io.irq = irq;
2696 info->io.irq_setup = ipmi_std_irq_setup; 2615 io.irq_setup = ipmi_std_irq_setup;
2697 } 2616 }
2698 } 2617 }
2699 2618
2700 info->io.slave_addr = find_slave_address(info, info->io.slave_addr); 2619 io.slave_addr = find_slave_address(&io, io.slave_addr);
2701
2702 info->io.dev = &pdev->dev;
2703 platform_set_drvdata(pdev, info);
2704 2620
2705 dev_info(info->io.dev, "%pR regsize %d spacing %d irq %d\n", 2621 io.dev = &pdev->dev;
2706 res, info->io.regsize, info->io.regspacing,
2707 info->io.irq);
2708 2622
2709 rv = ipmi_si_add_smi(info); 2623 dev_info(io.dev, "%pR regsize %d spacing %d irq %d\n",
2710 if (rv) 2624 res, io.regsize, io.regspacing, io.irq);
2711 kfree(info);
2712 2625
2713 return rv; 2626 return ipmi_si_add_smi(&io);
2714 2627
2715err_free: 2628err_free:
2716 kfree(info);
2717 return rv; 2629 return rv;
2718} 2630}
2719 2631
@@ -2742,10 +2654,7 @@ static int ipmi_probe(struct platform_device *pdev)
2742 2654
2743static int ipmi_remove(struct platform_device *pdev) 2655static int ipmi_remove(struct platform_device *pdev)
2744{ 2656{
2745 struct smi_info *info = dev_get_drvdata(&pdev->dev); 2657 return ipmi_si_remove_by_dev(&pdev->dev);
2746
2747 cleanup_one_si(info);
2748 return 0;
2749} 2658}
2750 2659
2751static struct platform_driver ipmi_driver = { 2660static struct platform_driver ipmi_driver = {
@@ -2761,45 +2670,27 @@ static struct platform_driver ipmi_driver = {
2761#ifdef CONFIG_PARISC 2670#ifdef CONFIG_PARISC
2762static int __init ipmi_parisc_probe(struct parisc_device *dev) 2671static int __init ipmi_parisc_probe(struct parisc_device *dev)
2763{ 2672{
2764 struct smi_info *info; 2673 struct si_sm_io io;
2765 int rv;
2766
2767 info = smi_info_alloc();
2768
2769 if (!info) {
2770 dev_err(&dev->dev,
2771 "could not allocate memory for PARISC probe\n");
2772 return -ENOMEM;
2773 }
2774
2775 info->io.si_type = SI_KCS;
2776 info->io.addr_source = SI_DEVICETREE;
2777 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2778 info->io.addr_data = dev->hpa.start;
2779 info->io.regsize = 1;
2780 info->io.regspacing = 1;
2781 info->io.regshift = 0;
2782 info->io.irq = 0; /* no interrupt */
2783 info->io.irq_setup = NULL;
2784 info->io.dev = &dev->dev;
2785
2786 dev_dbg(&dev->dev, "addr 0x%lx\n", info->io.addr_data);
2787 2674
2788 dev_set_drvdata(&dev->dev, info); 2675 io.si_type = SI_KCS;
2676 io.addr_source = SI_DEVICETREE;
2677 io.addr_type = IPMI_MEM_ADDR_SPACE;
2678 io.addr_data = dev->hpa.start;
2679 io.regsize = 1;
2680 io.regspacing = 1;
2681 io.regshift = 0;
2682 io.irq = 0; /* no interrupt */
2683 io.irq_setup = NULL;
2684 io.dev = &dev->dev;
2789 2685
2790 rv = ipmi_si_add_smi(info); 2686 dev_dbg(&dev->dev, "addr 0x%lx\n", io.addr_data);
2791 if (rv) {
2792 kfree(info);
2793 return rv;
2794 }
2795 2687
2796 return 0; 2688 return ipmi_si_add_smi(&io);
2797} 2689}
2798 2690
2799static int __exit ipmi_parisc_remove(struct parisc_device *dev) 2691static int __exit ipmi_parisc_remove(struct parisc_device *dev)
2800{ 2692{
2801 cleanup_one_si(dev_get_drvdata(&dev->dev)); 2693 return ipmi_si_remove_by_dev(&pdev->dev);
2802 return 0;
2803} 2694}
2804 2695
2805static const struct parisc_device_id ipmi_parisc_tbl[] __initconst = { 2696static const struct parisc_device_id ipmi_parisc_tbl[] __initconst = {
@@ -3393,21 +3284,27 @@ static struct smi_info *find_dup_si(struct smi_info *info)
3393 return NULL; 3284 return NULL;
3394} 3285}
3395 3286
3396int ipmi_si_add_smi(struct smi_info *new_smi) 3287int ipmi_si_add_smi(struct si_sm_io *io)
3397{ 3288{
3398 int rv = 0; 3289 int rv = 0;
3399 struct smi_info *dup; 3290 struct smi_info *new_smi, *dup;
3400 3291
3401 if (!new_smi->io.io_setup) { 3292 if (!io->io_setup) {
3402 if (new_smi->io.addr_type == IPMI_IO_ADDR_SPACE) { 3293 if (io->addr_type == IPMI_IO_ADDR_SPACE) {
3403 new_smi->io.io_setup = port_setup; 3294 io->io_setup = port_setup;
3404 } else if (new_smi->io.addr_type == IPMI_MEM_ADDR_SPACE) { 3295 } else if (io->addr_type == IPMI_MEM_ADDR_SPACE) {
3405 new_smi->io.io_setup = mem_setup; 3296 io->io_setup = mem_setup;
3406 } else { 3297 } else {
3407 return -EINVAL; 3298 return -EINVAL;
3408 } 3299 }
3409 } 3300 }
3410 3301
3302 new_smi = smi_info_alloc();
3303 if (!new_smi)
3304 return -ENOMEM;
3305
3306 new_smi->io = *io;
3307
3411 mutex_lock(&smi_infos_lock); 3308 mutex_lock(&smi_infos_lock);
3412 dup = find_dup_si(new_smi); 3309 dup = find_dup_si(new_smi);
3413 if (dup) { 3310 if (dup) {
@@ -3439,6 +3336,14 @@ int ipmi_si_add_smi(struct smi_info *new_smi)
3439 3336
3440 list_add_tail(&new_smi->link, &smi_infos); 3337 list_add_tail(&new_smi->link, &smi_infos);
3441 3338
3339 if (initialized) {
3340 rv = try_smi_init(new_smi);
3341 if (rv) {
3342 mutex_unlock(&smi_infos_lock);
3343 cleanup_one_si(new_smi);
3344 return rv;
3345 }
3346 }
3442out_err: 3347out_err:
3443 mutex_unlock(&smi_infos_lock); 3348 mutex_unlock(&smi_infos_lock);
3444 return rv; 3349 return rv;
@@ -3695,7 +3600,6 @@ static int init_ipmi_si(void)
3695 3600
3696 if (initialized) 3601 if (initialized)
3697 return 0; 3602 return 0;
3698 initialized = 1;
3699 3603
3700 if (si_tryplatform) { 3604 if (si_tryplatform) {
3701 rv = platform_driver_register(&ipmi_driver); 3605 rv = platform_driver_register(&ipmi_driver);
@@ -3764,10 +3668,8 @@ static int init_ipmi_si(void)
3764 } 3668 }
3765 3669
3766 /* type will only have been set if we successfully registered an si */ 3670 /* type will only have been set if we successfully registered an si */
3767 if (type) { 3671 if (type)
3768 mutex_unlock(&smi_infos_lock); 3672 goto skip_fallback_noirq;
3769 return 0;
3770 }
3771 3673
3772 /* Fall back to the preferred device */ 3674 /* Fall back to the preferred device */
3773 3675
@@ -3778,6 +3680,9 @@ static int init_ipmi_si(void)
3778 } 3680 }
3779 } 3681 }
3780 } 3682 }
3683
3684skip_fallback_noirq:
3685 initialized = 1;
3781 mutex_unlock(&smi_infos_lock); 3686 mutex_unlock(&smi_infos_lock);
3782 3687
3783 if (type) 3688 if (type)
@@ -3814,9 +3719,6 @@ static void cleanup_one_si(struct smi_info *to_clean)
3814 } 3719 }
3815 } 3720 }
3816 3721
3817 if (to_clean->io.dev)
3818 dev_set_drvdata(to_clean->io.dev, NULL);
3819
3820 list_del(&to_clean->link); 3722 list_del(&to_clean->link);
3821 3723
3822 /* 3724 /*
@@ -3859,6 +3761,24 @@ static void cleanup_one_si(struct smi_info *to_clean)
3859 kfree(to_clean); 3761 kfree(to_clean);
3860} 3762}
3861 3763
3764int ipmi_si_remove_by_dev(struct device *dev)
3765{
3766 struct smi_info *e;
3767 int rv = -ENOENT;
3768
3769 mutex_lock(&smi_infos_lock);
3770 list_for_each_entry(e, &smi_infos, link) {
3771 if (e->io.dev == dev) {
3772 cleanup_one_si(e);
3773 rv = 0;
3774 break;
3775 }
3776 }
3777 mutex_unlock(&smi_infos_lock);
3778
3779 return rv;
3780}
3781
3862static void cleanup_ipmi_si(void) 3782static void cleanup_ipmi_si(void)
3863{ 3783{
3864 struct smi_info *e, *tmp_e; 3784 struct smi_info *e, *tmp_e;
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index 9df77c664908..fbf5bfccde2e 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -70,6 +70,7 @@ struct si_sm_io {
70 enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */ 70 enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */
71 void (*addr_source_cleanup)(struct si_sm_io *io); 71 void (*addr_source_cleanup)(struct si_sm_io *io);
72 void *addr_source_data; 72 void *addr_source_data;
73 union ipmi_smi_info_union addr_info;
73 74
74 int (*io_setup)(struct si_sm_io *info); 75 int (*io_setup)(struct si_sm_io *info);
75 void (*io_cleanup)(struct si_sm_io *info); 76 void (*io_cleanup)(struct si_sm_io *info);