1 /* 2 * A hack to create a platform device from a DMI entry. This will 3 * allow autoloading of the IPMI drive based on SMBIOS entries. 4 */ 5 6 #include <linux/ipmi.h> 7 #include <linux/init.h> 8 #include <linux/dmi.h> 9 #include <linux/platform_device.h> 10 #include <linux/property.h> 11 #include "ipmi_dmi.h" 12 13 struct ipmi_dmi_info { 14 int type; 15 u32 flags; 16 unsigned long addr; 17 u8 slave_addr; 18 struct ipmi_dmi_info *next; 19 }; 20 21 static struct ipmi_dmi_info *ipmi_dmi_infos; 22 23 static int ipmi_dmi_nr __initdata; 24 25 static void __init dmi_add_platform_ipmi(unsigned long base_addr, 26 u32 flags, 27 u8 slave_addr, 28 int irq, 29 int offset, 30 int type) 31 { 32 struct platform_device *pdev; 33 struct resource r[4]; 34 unsigned int num_r = 1, size; 35 struct property_entry p[4] = { 36 PROPERTY_ENTRY_U8("slave-addr", slave_addr), 37 PROPERTY_ENTRY_U8("ipmi-type", type), 38 PROPERTY_ENTRY_U16("i2c-addr", base_addr), 39 { } 40 }; 41 char *name, *override; 42 int rv; 43 struct ipmi_dmi_info *info; 44 45 info = kmalloc(sizeof(*info), GFP_KERNEL); 46 if (!info) { 47 pr_warn("ipmi:dmi: Could not allocate dmi info\n"); 48 } else { 49 info->type = type; 50 info->flags = flags; 51 info->addr = base_addr; 52 info->slave_addr = slave_addr; 53 info->next = ipmi_dmi_infos; 54 ipmi_dmi_infos = info; 55 } 56 57 name = "dmi-ipmi-si"; 58 override = "ipmi_si"; 59 switch (type) { 60 case IPMI_DMI_TYPE_SSIF: 61 name = "dmi-ipmi-ssif"; 62 override = "ipmi_ssif"; 63 offset = 1; 64 size = 1; 65 break; 66 case IPMI_DMI_TYPE_BT: 67 size = 3; 68 break; 69 case IPMI_DMI_TYPE_KCS: 70 case IPMI_DMI_TYPE_SMIC: 71 size = 2; 72 break; 73 default: 74 pr_err("ipmi:dmi: Invalid IPMI type: %d", type); 75 return; 76 } 77 78 pdev = platform_device_alloc(name, ipmi_dmi_nr); 79 if (!pdev) { 80 pr_err("ipmi:dmi: Error allocation IPMI platform device"); 81 return; 82 } 83 pdev->driver_override = override; 84 85 if (type == IPMI_DMI_TYPE_SSIF) 86 goto add_properties; 87 88 memset(r, 0, sizeof(r)); 89 90 r[0].start = base_addr; 91 r[0].end = r[0].start + offset - 1; 92 r[0].name = "IPMI Address 1"; 93 r[0].flags = flags; 94 95 if (size > 1) { 96 r[1].start = r[0].start + offset; 97 r[1].end = r[1].start + offset - 1; 98 r[1].name = "IPMI Address 2"; 99 r[1].flags = flags; 100 num_r++; 101 } 102 103 if (size > 2) { 104 r[2].start = r[1].start + offset; 105 r[2].end = r[2].start + offset - 1; 106 r[2].name = "IPMI Address 3"; 107 r[2].flags = flags; 108 num_r++; 109 } 110 111 if (irq) { 112 r[num_r].start = irq; 113 r[num_r].end = irq; 114 r[num_r].name = "IPMI IRQ"; 115 r[num_r].flags = IORESOURCE_IRQ; 116 num_r++; 117 } 118 119 rv = platform_device_add_resources(pdev, r, num_r); 120 if (rv) { 121 dev_err(&pdev->dev, 122 "ipmi:dmi: Unable to add resources: %d\n", rv); 123 goto err; 124 } 125 126 add_properties: 127 rv = platform_device_add_properties(pdev, p); 128 if (rv) { 129 dev_err(&pdev->dev, 130 "ipmi:dmi: Unable to add properties: %d\n", rv); 131 goto err; 132 } 133 134 rv = platform_device_add(pdev); 135 if (rv) { 136 dev_err(&pdev->dev, "ipmi:dmi: Unable to add device: %d\n", rv); 137 goto err; 138 } 139 140 ipmi_dmi_nr++; 141 return; 142 143 err: 144 platform_device_put(pdev); 145 } 146 147 /* 148 * Look up the slave address for a given interface. This is here 149 * because ACPI doesn't have a slave address while SMBIOS does, but we 150 * prefer using ACPI so the ACPI code can use the IPMI namespace. 151 * This function allows an ACPI-specified IPMI device to look up the 152 * slave address from the DMI table. 153 */ 154 int ipmi_dmi_get_slave_addr(int type, u32 flags, unsigned long base_addr) 155 { 156 struct ipmi_dmi_info *info = ipmi_dmi_infos; 157 158 while (info) { 159 if (info->type == type && 160 info->flags == flags && 161 info->addr == base_addr) 162 return info->slave_addr; 163 info = info->next; 164 } 165 166 return 0; 167 } 168 EXPORT_SYMBOL(ipmi_dmi_get_slave_addr); 169 170 #define DMI_IPMI_MIN_LENGTH 0x10 171 #define DMI_IPMI_VER2_LENGTH 0x12 172 #define DMI_IPMI_TYPE 4 173 #define DMI_IPMI_SLAVEADDR 6 174 #define DMI_IPMI_ADDR 8 175 #define DMI_IPMI_ACCESS 0x10 176 #define DMI_IPMI_IRQ 0x11 177 #define DMI_IPMI_IO_MASK 0xfffe 178 179 static void __init dmi_decode_ipmi(const struct dmi_header *dm) 180 { 181 const u8 *data = (const u8 *) dm; 182 u32 flags = IORESOURCE_IO; 183 unsigned long base_addr; 184 u8 len = dm->length; 185 u8 slave_addr; 186 int irq = 0, offset; 187 int type; 188 189 if (len < DMI_IPMI_MIN_LENGTH) 190 return; 191 192 type = data[DMI_IPMI_TYPE]; 193 slave_addr = data[DMI_IPMI_SLAVEADDR]; 194 195 memcpy(&base_addr, data + DMI_IPMI_ADDR, sizeof(unsigned long)); 196 if (len >= DMI_IPMI_VER2_LENGTH) { 197 if (type == IPMI_DMI_TYPE_SSIF) { 198 offset = 0; 199 flags = 0; 200 base_addr = data[DMI_IPMI_ADDR] >> 1; 201 if (base_addr == 0) { 202 /* 203 * Some broken systems put the I2C address in 204 * the slave address field. We try to 205 * accommodate them here. 206 */ 207 base_addr = data[DMI_IPMI_SLAVEADDR] >> 1; 208 slave_addr = 0; 209 } 210 } else { 211 if (base_addr & 1) { 212 /* I/O */ 213 base_addr &= DMI_IPMI_IO_MASK; 214 } else { 215 /* Memory */ 216 flags = IORESOURCE_MEM; 217 } 218 219 /* 220 * If bit 4 of byte 0x10 is set, then the lsb 221 * for the address is odd. 222 */ 223 base_addr |= (data[DMI_IPMI_ACCESS] >> 4) & 1; 224 225 irq = data[DMI_IPMI_IRQ]; 226 227 /* 228 * The top two bits of byte 0x10 hold the 229 * register spacing. 230 */ 231 switch ((data[DMI_IPMI_ACCESS] >> 6) & 3) { 232 case 0: /* Byte boundaries */ 233 offset = 1; 234 break; 235 case 1: /* 32-bit boundaries */ 236 offset = 4; 237 break; 238 case 2: /* 16-byte boundaries */ 239 offset = 16; 240 break; 241 default: 242 pr_err("ipmi:dmi: Invalid offset: 0"); 243 return; 244 } 245 } 246 } else { 247 /* Old DMI spec. */ 248 /* 249 * Note that technically, the lower bit of the base 250 * address should be 1 if the address is I/O and 0 if 251 * the address is in memory. So many systems get that 252 * wrong (and all that I have seen are I/O) so we just 253 * ignore that bit and assume I/O. Systems that use 254 * memory should use the newer spec, anyway. 255 */ 256 base_addr = base_addr & DMI_IPMI_IO_MASK; 257 offset = 1; 258 } 259 260 dmi_add_platform_ipmi(base_addr, flags, slave_addr, irq, 261 offset, type); 262 } 263 264 static int __init scan_for_dmi_ipmi(void) 265 { 266 const struct dmi_device *dev = NULL; 267 268 while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) 269 dmi_decode_ipmi((const struct dmi_header *) dev->device_data); 270 271 return 0; 272 } 273 subsys_initcall(scan_for_dmi_ipmi); 274