aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2016-02-03 11:45:28 -0500
committerCorey Minyard <cminyard@mvista.com>2017-06-19 13:49:38 -0400
commit0944d889a237b6107f9ceeee053fe7221cdd1089 (patch)
tree7da1960bd53c5d63bcc9cff81f893ec0e2aa9318
parent9f88145f1871456de67ae6a242ac2661187bd4ff (diff)
ipmi: Convert DMI handling over to a platform device
Now that the IPMI DMI code creates a platform device for IPMI devices in the firmware, use that instead of handling all the DMI work in the IPMI drivers themselves. Signed-off-by: Corey Minyard <cminyard@mvista.com> Cc: Andy Lutomirski <luto@kernel.org>
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c261
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c162
2 files changed, 219 insertions, 204 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b89078bff1c1..edaf6284c663 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -61,6 +61,7 @@
61#include <linux/ipmi_smi.h> 61#include <linux/ipmi_smi.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#include "ipmi_si_sm.h" 63#include "ipmi_si_sm.h"
64#include "ipmi_dmi.h"
64#include <linux/dmi.h> 65#include <linux/dmi.h>
65#include <linux/string.h> 66#include <linux/string.h>
66#include <linux/ctype.h> 67#include <linux/ctype.h>
@@ -2273,136 +2274,105 @@ static void spmi_find_bmc(void)
2273} 2274}
2274#endif 2275#endif
2275 2276
2276#ifdef CONFIG_DMI 2277#if defined(CONFIG_DMI) || defined(CONFIG_ACPI)
2277struct dmi_ipmi_data { 2278struct resource *ipmi_get_info_from_resources(struct platform_device *pdev,
2278 u8 type; 2279 struct smi_info *info)
2279 u8 addr_space;
2280 unsigned long base_addr;
2281 u8 irq;
2282 u8 offset;
2283 u8 slave_addr;
2284};
2285
2286static int decode_dmi(const struct dmi_header *dm,
2287 struct dmi_ipmi_data *dmi)
2288{ 2280{
2289 const u8 *data = (const u8 *)dm; 2281 struct resource *res, *res_second;
2290 unsigned long base_addr;
2291 u8 reg_spacing;
2292 u8 len = dm->length;
2293
2294 dmi->type = data[4];
2295 2282
2296 memcpy(&base_addr, data+8, sizeof(unsigned long)); 2283 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
2297 if (len >= 0x11) { 2284 if (res) {
2298 if (base_addr & 1) { 2285 info->io_setup = port_setup;
2299 /* I/O */ 2286 info->io.addr_type = IPMI_IO_ADDR_SPACE;
2300 base_addr &= 0xFFFE;
2301 dmi->addr_space = IPMI_IO_ADDR_SPACE;
2302 } else
2303 /* Memory */
2304 dmi->addr_space = IPMI_MEM_ADDR_SPACE;
2305
2306 /* If bit 4 of byte 0x10 is set, then the lsb for the address
2307 is odd. */
2308 dmi->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
2309
2310 dmi->irq = data[0x11];
2311
2312 /* The top two bits of byte 0x10 hold the register spacing. */
2313 reg_spacing = (data[0x10] & 0xC0) >> 6;
2314 switch (reg_spacing) {
2315 case 0x00: /* Byte boundaries */
2316 dmi->offset = 1;
2317 break;
2318 case 0x01: /* 32-bit boundaries */
2319 dmi->offset = 4;
2320 break;
2321 case 0x02: /* 16-byte boundaries */
2322 dmi->offset = 16;
2323 break;
2324 default:
2325 /* Some other interface, just ignore it. */
2326 return -EIO;
2327 }
2328 } else { 2287 } else {
2329 /* Old DMI spec. */ 2288 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2330 /* 2289 if (res) {
2331 * Note that technically, the lower bit of the base 2290 info->io_setup = mem_setup;
2332 * address should be 1 if the address is I/O and 0 if 2291 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2333 * the address is in memory. So many systems get that 2292 }
2334 * wrong (and all that I have seen are I/O) so we just
2335 * ignore that bit and assume I/O. Systems that use
2336 * memory should use the newer spec, anyway.
2337 */
2338 dmi->base_addr = base_addr & 0xfffe;
2339 dmi->addr_space = IPMI_IO_ADDR_SPACE;
2340 dmi->offset = 1;
2341 } 2293 }
2294 if (!res) {
2295 dev_err(&pdev->dev, "no I/O or memory address\n");
2296 return NULL;
2297 }
2298 info->io.addr_data = res->start;
2342 2299
2343 dmi->slave_addr = data[6]; 2300 info->io.regspacing = DEFAULT_REGSPACING;
2301 res_second = platform_get_resource(pdev,
2302 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
2303 IORESOURCE_IO : IORESOURCE_MEM,
2304 1);
2305 if (res_second) {
2306 if (res_second->start > info->io.addr_data)
2307 info->io.regspacing =
2308 res_second->start - info->io.addr_data;
2309 }
2310 info->io.regsize = DEFAULT_REGSIZE;
2311 info->io.regshift = 0;
2344 2312
2345 return 0; 2313 return res;
2346} 2314}
2347 2315
2348static void try_init_dmi(struct dmi_ipmi_data *ipmi_data) 2316#endif
2317
2318#ifdef CONFIG_DMI
2319static int dmi_ipmi_probe(struct platform_device *pdev)
2349{ 2320{
2350 struct smi_info *info; 2321 struct smi_info *info;
2322 u8 type, slave_addr;
2323 int rv;
2324
2325 if (!si_trydmi)
2326 return -ENODEV;
2327
2328 rv = device_property_read_u8(&pdev->dev, "ipmi-type", &type);
2329 if (rv)
2330 return -ENODEV;
2351 2331
2352 info = smi_info_alloc(); 2332 info = smi_info_alloc();
2353 if (!info) { 2333 if (!info) {
2354 pr_err(PFX "Could not allocate SI data\n"); 2334 pr_err(PFX "Could not allocate SI data\n");
2355 return; 2335 return -ENOMEM;
2356 } 2336 }
2357 2337
2358 info->addr_source = SI_SMBIOS; 2338 info->addr_source = SI_SMBIOS;
2359 pr_info(PFX "probing via SMBIOS\n"); 2339 pr_info(PFX "probing via SMBIOS\n");
2360 2340
2361 switch (ipmi_data->type) { 2341 switch (type) {
2362 case 0x01: /* KCS */ 2342 case IPMI_DMI_TYPE_KCS:
2363 info->si_type = SI_KCS; 2343 info->si_type = SI_KCS;
2364 break; 2344 break;
2365 case 0x02: /* SMIC */ 2345 case IPMI_DMI_TYPE_SMIC:
2366 info->si_type = SI_SMIC; 2346 info->si_type = SI_SMIC;
2367 break; 2347 break;
2368 case 0x03: /* BT */ 2348 case IPMI_DMI_TYPE_BT:
2369 info->si_type = SI_BT; 2349 info->si_type = SI_BT;
2370 break; 2350 break;
2371 default: 2351 default:
2372 kfree(info); 2352 kfree(info);
2373 return; 2353 return -EINVAL;
2374 } 2354 }
2375 2355
2376 switch (ipmi_data->addr_space) { 2356 if (!ipmi_get_info_from_resources(pdev, info)) {
2377 case IPMI_MEM_ADDR_SPACE: 2357 rv = -EINVAL;
2378 info->io_setup = mem_setup; 2358 goto err_free;
2379 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2380 break;
2381
2382 case IPMI_IO_ADDR_SPACE:
2383 info->io_setup = port_setup;
2384 info->io.addr_type = IPMI_IO_ADDR_SPACE;
2385 break;
2386
2387 default:
2388 kfree(info);
2389 pr_warn(PFX "Unknown SMBIOS I/O Address type: %d\n",
2390 ipmi_data->addr_space);
2391 return;
2392 } 2359 }
2393 info->io.addr_data = ipmi_data->base_addr;
2394 2360
2395 info->io.regspacing = ipmi_data->offset; 2361 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr);
2396 if (!info->io.regspacing) 2362 if (rv) {
2397 info->io.regspacing = DEFAULT_REGSPACING; 2363 dev_warn(&pdev->dev, "device has no slave-addr property");
2398 info->io.regsize = DEFAULT_REGSIZE; 2364 info->slave_addr = 0x20;
2399 info->io.regshift = 0; 2365 } else {
2400 2366 info->slave_addr = slave_addr;
2401 info->slave_addr = ipmi_data->slave_addr; 2367 }
2402 2368
2403 info->irq = ipmi_data->irq; 2369 info->irq = platform_get_irq(pdev, 0);
2404 if (info->irq) 2370 if (info->irq > 0)
2405 info->irq_setup = std_irq_setup; 2371 info->irq_setup = std_irq_setup;
2372 else
2373 info->irq = 0;
2374
2375 info->dev = &pdev->dev;
2406 2376
2407 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", 2377 pr_info("ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n",
2408 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem", 2378 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? "io" : "mem",
@@ -2411,21 +2381,17 @@ static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
2411 2381
2412 if (add_smi(info)) 2382 if (add_smi(info))
2413 kfree(info); 2383 kfree(info);
2414}
2415 2384
2416static void dmi_find_bmc(void) 2385 return 0;
2417{
2418 const struct dmi_device *dev = NULL;
2419 struct dmi_ipmi_data data;
2420 int rv;
2421 2386
2422 while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { 2387err_free:
2423 memset(&data, 0, sizeof(data)); 2388 kfree(info);
2424 rv = decode_dmi((const struct dmi_header *) dev->device_data, 2389 return rv;
2425 &data); 2390}
2426 if (!rv) 2391#else
2427 try_init_dmi(&data); 2392static int dmi_ipmi_probe(struct platform_device *pdev)
2428 } 2393{
2394 return -ENODEV;
2429} 2395}
2430#endif /* CONFIG_DMI */ 2396#endif /* CONFIG_DMI */
2431 2397
@@ -2684,17 +2650,47 @@ static int of_ipmi_probe(struct platform_device *dev)
2684#endif 2650#endif
2685 2651
2686#ifdef CONFIG_ACPI 2652#ifdef CONFIG_ACPI
2653static int find_slave_address(struct smi_info *info, int slave_addr)
2654{
2655#ifdef CONFIG_IPMI_DMI_DECODE
2656 if (!slave_addr) {
2657 int type = -1;
2658 u32 flags = IORESOURCE_IO;
2659
2660 switch (info->si_type) {
2661 case SI_KCS:
2662 type = IPMI_DMI_TYPE_KCS;
2663 break;
2664 case SI_BT:
2665 type = IPMI_DMI_TYPE_BT;
2666 break;
2667 case SI_SMIC:
2668 type = IPMI_DMI_TYPE_SMIC;
2669 break;
2670 }
2671
2672 if (info->io.addr_type == IPMI_MEM_ADDR_SPACE)
2673 flags = IORESOURCE_MEM;
2674
2675 slave_addr = ipmi_dmi_get_slave_addr(type, flags,
2676 info->io.addr_data);
2677 }
2678#endif
2679
2680 return slave_addr;
2681}
2682
2687static int acpi_ipmi_probe(struct platform_device *dev) 2683static int acpi_ipmi_probe(struct platform_device *dev)
2688{ 2684{
2689 struct smi_info *info; 2685 struct smi_info *info;
2690 struct resource *res, *res_second;
2691 acpi_handle handle; 2686 acpi_handle handle;
2692 acpi_status status; 2687 acpi_status status;
2693 unsigned long long tmp; 2688 unsigned long long tmp;
2689 struct resource *res;
2694 int rv = -EINVAL; 2690 int rv = -EINVAL;
2695 2691
2696 if (!si_tryacpi) 2692 if (!si_tryacpi)
2697 return 0; 2693 return -ENODEV;
2698 2694
2699 handle = ACPI_HANDLE(&dev->dev); 2695 handle = ACPI_HANDLE(&dev->dev);
2700 if (!handle) 2696 if (!handle)
@@ -2734,35 +2730,11 @@ static int acpi_ipmi_probe(struct platform_device *dev)
2734 goto err_free; 2730 goto err_free;
2735 } 2731 }
2736 2732
2737 res = platform_get_resource(dev, IORESOURCE_IO, 0); 2733 res = ipmi_get_info_from_resources(dev, info);
2738 if (res) {
2739 info->io_setup = port_setup;
2740 info->io.addr_type = IPMI_IO_ADDR_SPACE;
2741 } else {
2742 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
2743 if (res) {
2744 info->io_setup = mem_setup;
2745 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2746 }
2747 }
2748 if (!res) { 2734 if (!res) {
2749 dev_err(&dev->dev, "no I/O or memory address\n"); 2735 rv = -EINVAL;
2750 goto err_free; 2736 goto err_free;
2751 } 2737 }
2752 info->io.addr_data = res->start;
2753
2754 info->io.regspacing = DEFAULT_REGSPACING;
2755 res_second = platform_get_resource(dev,
2756 (info->io.addr_type == IPMI_IO_ADDR_SPACE) ?
2757 IORESOURCE_IO : IORESOURCE_MEM,
2758 1);
2759 if (res_second) {
2760 if (res_second->start > info->io.addr_data)
2761 info->io.regspacing =
2762 res_second->start - info->io.addr_data;
2763 }
2764 info->io.regsize = DEFAULT_REGSIZE;
2765 info->io.regshift = 0;
2766 2738
2767 /* If _GPE exists, use it; otherwise use standard interrupts */ 2739 /* If _GPE exists, use it; otherwise use standard interrupts */
2768 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); 2740 status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
@@ -2778,6 +2750,8 @@ static int acpi_ipmi_probe(struct platform_device *dev)
2778 } 2750 }
2779 } 2751 }
2780 2752
2753 info->slave_addr = find_slave_address(info, info->slave_addr);
2754
2781 info->dev = &dev->dev; 2755 info->dev = &dev->dev;
2782 platform_set_drvdata(dev, info); 2756 platform_set_drvdata(dev, info);
2783 2757
@@ -2813,7 +2787,10 @@ static int ipmi_probe(struct platform_device *dev)
2813 if (of_ipmi_probe(dev) == 0) 2787 if (of_ipmi_probe(dev) == 0)
2814 return 0; 2788 return 0;
2815 2789
2816 return acpi_ipmi_probe(dev); 2790 if (acpi_ipmi_probe(dev) == 0)
2791 return 0;
2792
2793 return dmi_ipmi_probe(dev);
2817} 2794}
2818 2795
2819static int ipmi_remove(struct platform_device *dev) 2796static int ipmi_remove(struct platform_device *dev)
@@ -3786,11 +3763,6 @@ static int init_ipmi_si(void)
3786 } 3763 }
3787#endif 3764#endif
3788 3765
3789#ifdef CONFIG_DMI
3790 if (si_trydmi)
3791 dmi_find_bmc();
3792#endif
3793
3794#ifdef CONFIG_ACPI 3766#ifdef CONFIG_ACPI
3795 if (si_tryacpi) 3767 if (si_tryacpi)
3796 spmi_find_bmc(); 3768 spmi_find_bmc();
@@ -3938,6 +3910,7 @@ static void cleanup_ipmi_si(void)
3938} 3910}
3939module_exit(cleanup_ipmi_si); 3911module_exit(cleanup_ipmi_si);
3940 3912
3913MODULE_ALIAS("platform:dmi-ipmi-si");
3941MODULE_LICENSE("GPL"); 3914MODULE_LICENSE("GPL");
3942MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); 3915MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
3943MODULE_DESCRIPTION("Interface to the IPMI driver for the KCS, SMIC, and BT" 3916MODULE_DESCRIPTION("Interface to the IPMI driver for the KCS, SMIC, and BT"
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 05e18041c357..61434830e641 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -53,6 +53,7 @@
53#include <linux/acpi.h> 53#include <linux/acpi.h>
54#include <linux/ctype.h> 54#include <linux/ctype.h>
55#include <linux/time64.h> 55#include <linux/time64.h>
56#include "ipmi_dmi.h"
56 57
57#define PFX "ipmi_ssif: " 58#define PFX "ipmi_ssif: "
58#define DEVICE_NAME "ipmi_ssif" 59#define DEVICE_NAME "ipmi_ssif"
@@ -180,6 +181,8 @@ struct ssif_addr_info {
180 int slave_addr; 181 int slave_addr;
181 enum ipmi_addr_src addr_src; 182 enum ipmi_addr_src addr_src;
182 union ipmi_smi_info_union addr_info; 183 union ipmi_smi_info_union addr_info;
184 struct device *dev;
185 struct i2c_client *client;
183 186
184 struct mutex clients_mutex; 187 struct mutex clients_mutex;
185 struct list_head clients; 188 struct list_head clients;
@@ -1171,6 +1174,7 @@ static LIST_HEAD(ssif_infos);
1171static int ssif_remove(struct i2c_client *client) 1174static int ssif_remove(struct i2c_client *client)
1172{ 1175{
1173 struct ssif_info *ssif_info = i2c_get_clientdata(client); 1176 struct ssif_info *ssif_info = i2c_get_clientdata(client);
1177 struct ssif_addr_info *addr_info;
1174 int rv; 1178 int rv;
1175 1179
1176 if (!ssif_info) 1180 if (!ssif_info)
@@ -1198,6 +1202,13 @@ static int ssif_remove(struct i2c_client *client)
1198 kthread_stop(ssif_info->thread); 1202 kthread_stop(ssif_info->thread);
1199 } 1203 }
1200 1204
1205 list_for_each_entry(addr_info, &ssif_infos, link) {
1206 if (addr_info->client == client) {
1207 addr_info->client = NULL;
1208 break;
1209 }
1210 }
1211
1201 /* 1212 /*
1202 * No message can be outstanding now, we have removed the 1213 * No message can be outstanding now, we have removed the
1203 * upper layer and it permitted us to do so. 1214 * upper layer and it permitted us to do so.
@@ -1406,27 +1417,13 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
1406 1417
1407static int find_slave_address(struct i2c_client *client, int slave_addr) 1418static int find_slave_address(struct i2c_client *client, int slave_addr)
1408{ 1419{
1409 struct ssif_addr_info *info; 1420#ifdef CONFIG_IPMI_DMI_DECODE
1410 1421 if (!slave_addr)
1411 if (slave_addr) 1422 slave_addr = ipmi_dmi_get_slave_addr(
1412 return slave_addr; 1423 IPMI_DMI_TYPE_SSIF,
1413 1424 i2c_adapter_id(client->adapter),
1414 /* 1425 client->addr);
1415 * Came in without a slave address, search around to see if 1426#endif
1416 * the other sources have a slave address. This lets us pick
1417 * up an SMBIOS slave address when using ACPI.
1418 */
1419 list_for_each_entry(info, &ssif_infos, link) {
1420 if (info->binfo.addr != client->addr)
1421 continue;
1422 if (info->adapter_name && strcmp_nospace(info->adapter_name,
1423 client->adapter->name))
1424 continue;
1425 if (info->slave_addr) {
1426 slave_addr = info->slave_addr;
1427 break;
1428 }
1429 }
1430 1427
1431 return slave_addr; 1428 return slave_addr;
1432} 1429}
@@ -1448,7 +1445,6 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1448 u8 slave_addr = 0; 1445 u8 slave_addr = 0;
1449 struct ssif_addr_info *addr_info = NULL; 1446 struct ssif_addr_info *addr_info = NULL;
1450 1447
1451
1452 resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); 1448 resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
1453 if (!resp) 1449 if (!resp)
1454 return -ENOMEM; 1450 return -ENOMEM;
@@ -1469,6 +1465,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1469 ssif_info->addr_source = addr_info->addr_src; 1465 ssif_info->addr_source = addr_info->addr_src;
1470 ssif_info->ssif_debug = addr_info->debug; 1466 ssif_info->ssif_debug = addr_info->debug;
1471 ssif_info->addr_info = addr_info->addr_info; 1467 ssif_info->addr_info = addr_info->addr_info;
1468 addr_info->client = client;
1472 slave_addr = addr_info->slave_addr; 1469 slave_addr = addr_info->slave_addr;
1473 } 1470 }
1474 } 1471 }
@@ -1707,8 +1704,19 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1707 } 1704 }
1708 1705
1709 out: 1706 out:
1710 if (rv) 1707 if (rv) {
1708 /*
1709 * Note that if addr_info->client is assigned, we
1710 * leave it. The i2c client hangs around even if we
1711 * return a failure here, and the failure here is not
1712 * propagated back to the i2c code. This seems to be
1713 * design intent, strange as it may be. But if we
1714 * don't leave it, ssif_platform_remove will not remove
1715 * the client like it should.
1716 */
1717 dev_err(&client->dev, "Unable to start IPMI SSIF: %d\n", rv);
1711 kfree(ssif_info); 1718 kfree(ssif_info);
1719 }
1712 kfree(resp); 1720 kfree(resp);
1713 return rv; 1721 return rv;
1714 1722
@@ -1733,7 +1741,8 @@ static int ssif_adapter_handler(struct device *adev, void *opaque)
1733 1741
1734static int new_ssif_client(int addr, char *adapter_name, 1742static int new_ssif_client(int addr, char *adapter_name,
1735 int debug, int slave_addr, 1743 int debug, int slave_addr,
1736 enum ipmi_addr_src addr_src) 1744 enum ipmi_addr_src addr_src,
1745 struct device *dev)
1737{ 1746{
1738 struct ssif_addr_info *addr_info; 1747 struct ssif_addr_info *addr_info;
1739 int rv = 0; 1748 int rv = 0;
@@ -1766,6 +1775,9 @@ static int new_ssif_client(int addr, char *adapter_name,
1766 addr_info->debug = debug; 1775 addr_info->debug = debug;
1767 addr_info->slave_addr = slave_addr; 1776 addr_info->slave_addr = slave_addr;
1768 addr_info->addr_src = addr_src; 1777 addr_info->addr_src = addr_src;
1778 addr_info->dev = dev;
1779
1780 dev_set_drvdata(dev, addr_info);
1769 1781
1770 list_add_tail(&addr_info->link, &ssif_infos); 1782 list_add_tail(&addr_info->link, &ssif_infos);
1771 1783
@@ -1904,7 +1916,7 @@ static int try_init_spmi(struct SPMITable *spmi)
1904 1916
1905 myaddr = spmi->addr.address & 0x7f; 1917 myaddr = spmi->addr.address & 0x7f;
1906 1918
1907 return new_ssif_client(myaddr, NULL, 0, 0, SI_SPMI); 1919 return new_ssif_client(myaddr, NULL, 0, 0, SI_SPMI, NULL);
1908} 1920}
1909 1921
1910static void spmi_find_bmc(void) 1922static void spmi_find_bmc(void)
@@ -1933,48 +1945,40 @@ static void spmi_find_bmc(void) { }
1933#endif 1945#endif
1934 1946
1935#ifdef CONFIG_DMI 1947#ifdef CONFIG_DMI
1936static int decode_dmi(const struct dmi_device *dmi_dev) 1948static int dmi_ipmi_probe(struct platform_device *pdev)
1937{ 1949{
1938 struct dmi_header *dm = dmi_dev->device_data; 1950 u8 type, slave_addr = 0;
1939 u8 *data = (u8 *) dm; 1951 u16 i2c_addr;
1940 u8 len = dm->length; 1952 int rv;
1941 unsigned short myaddr;
1942 int slave_addr;
1943 1953
1944 if (num_addrs >= MAX_SSIF_BMCS) 1954 if (!ssif_trydmi)
1945 return -1; 1955 return -ENODEV;
1946 1956
1947 if (len < 9) 1957 rv = device_property_read_u8(&pdev->dev, "ipmi-type", &type);
1948 return -1; 1958 if (rv)
1959 return -ENODEV;
1949 1960
1950 if (data[0x04] != 4) /* Not SSIF */ 1961 if (type != IPMI_DMI_TYPE_SSIF)
1951 return -1; 1962 return -ENODEV;
1952 1963
1953 if ((data[8] >> 1) == 0) { 1964 rv = device_property_read_u16(&pdev->dev, "i2c-addr", &i2c_addr);
1954 /* 1965 if (rv) {
1955 * Some broken systems put the I2C address in 1966 dev_warn(&pdev->dev, PFX "No i2c-addr property\n");
1956 * the slave address field. We try to 1967 return -ENODEV;
1957 * accommodate them here.
1958 */
1959 myaddr = data[6] >> 1;
1960 slave_addr = 0;
1961 } else {
1962 myaddr = data[8] >> 1;
1963 slave_addr = data[6];
1964 } 1968 }
1965 1969
1966 return new_ssif_client(myaddr, NULL, 0, slave_addr, SI_SMBIOS); 1970 rv = device_property_read_u8(&pdev->dev, "slave-addr", &slave_addr);
1967} 1971 if (rv)
1968 1972 dev_warn(&pdev->dev, "device has no slave-addr property");
1969static void dmi_iterator(void)
1970{
1971 const struct dmi_device *dev = NULL;
1972 1973
1973 while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) 1974 return new_ssif_client(i2c_addr, NULL, 0,
1974 decode_dmi(dev); 1975 slave_addr, SI_SMBIOS, &pdev->dev);
1975} 1976}
1976#else 1977#else
1977static void dmi_iterator(void) { } 1978static int dmi_ipmi_probe(struct platform_device *pdev)
1979{
1980 return -ENODEV;
1981}
1978#endif 1982#endif
1979 1983
1980static const struct i2c_device_id ssif_id[] = { 1984static const struct i2c_device_id ssif_id[] = {
@@ -1995,6 +1999,36 @@ static struct i2c_driver ssif_i2c_driver = {
1995 .detect = ssif_detect 1999 .detect = ssif_detect
1996}; 2000};
1997 2001
2002static int ssif_platform_probe(struct platform_device *dev)
2003{
2004 return dmi_ipmi_probe(dev);
2005}
2006
2007static int ssif_platform_remove(struct platform_device *dev)
2008{
2009 struct ssif_addr_info *addr_info = dev_get_drvdata(&dev->dev);
2010
2011 if (!addr_info)
2012 return 0;
2013
2014 mutex_lock(&ssif_infos_mutex);
2015 if (addr_info->client)
2016 i2c_unregister_device(addr_info->client);
2017
2018 list_del(&addr_info->link);
2019 kfree(addr_info);
2020 mutex_unlock(&ssif_infos_mutex);
2021 return 0;
2022}
2023
2024static struct platform_driver ipmi_driver = {
2025 .driver = {
2026 .name = DEVICE_NAME,
2027 },
2028 .probe = ssif_platform_probe,
2029 .remove = ssif_platform_remove,
2030};
2031
1998static int init_ipmi_ssif(void) 2032static int init_ipmi_ssif(void)
1999{ 2033{
2000 int i; 2034 int i;
@@ -2009,7 +2043,7 @@ static int init_ipmi_ssif(void)
2009 for (i = 0; i < num_addrs; i++) { 2043 for (i = 0; i < num_addrs; i++) {
2010 rv = new_ssif_client(addr[i], adapter_name[i], 2044 rv = new_ssif_client(addr[i], adapter_name[i],
2011 dbg[i], slave_addrs[i], 2045 dbg[i], slave_addrs[i],
2012 SI_HARDCODED); 2046 SI_HARDCODED, NULL);
2013 if (rv) 2047 if (rv)
2014 pr_err(PFX 2048 pr_err(PFX
2015 "Couldn't add hardcoded device at addr 0x%x\n", 2049 "Couldn't add hardcoded device at addr 0x%x\n",
@@ -2019,11 +2053,16 @@ static int init_ipmi_ssif(void)
2019 if (ssif_tryacpi) 2053 if (ssif_tryacpi)
2020 ssif_i2c_driver.driver.acpi_match_table = 2054 ssif_i2c_driver.driver.acpi_match_table =
2021 ACPI_PTR(ssif_acpi_match); 2055 ACPI_PTR(ssif_acpi_match);
2022 if (ssif_trydmi) 2056
2023 dmi_iterator();
2024 if (ssif_tryacpi) 2057 if (ssif_tryacpi)
2025 spmi_find_bmc(); 2058 spmi_find_bmc();
2026 2059
2060 if (ssif_trydmi) {
2061 rv = platform_driver_register(&ipmi_driver);
2062 if (rv)
2063 pr_err(PFX "Unable to register driver: %d\n", rv);
2064 }
2065
2027 ssif_i2c_driver.address_list = ssif_address_list(); 2066 ssif_i2c_driver.address_list = ssif_address_list();
2028 2067
2029 rv = i2c_add_driver(&ssif_i2c_driver); 2068 rv = i2c_add_driver(&ssif_i2c_driver);
@@ -2043,10 +2082,13 @@ static void cleanup_ipmi_ssif(void)
2043 2082
2044 i2c_del_driver(&ssif_i2c_driver); 2083 i2c_del_driver(&ssif_i2c_driver);
2045 2084
2085 platform_driver_unregister(&ipmi_driver);
2086
2046 free_ssif_clients(); 2087 free_ssif_clients();
2047} 2088}
2048module_exit(cleanup_ipmi_ssif); 2089module_exit(cleanup_ipmi_ssif);
2049 2090
2091MODULE_ALIAS("platform:dmi-ipmi-ssif");
2050MODULE_AUTHOR("Todd C Davis <todd.c.davis@intel.com>, Corey Minyard <minyard@acm.org>"); 2092MODULE_AUTHOR("Todd C Davis <todd.c.davis@intel.com>, Corey Minyard <minyard@acm.org>");
2051MODULE_DESCRIPTION("IPMI driver for management controllers on a SMBus"); 2093MODULE_DESCRIPTION("IPMI driver for management controllers on a SMBus");
2052MODULE_LICENSE("GPL"); 2094MODULE_LICENSE("GPL");