summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2016-11-07 12:07:09 -0600
committerCorey Minyard <cminyard@mvista.com>2016-11-24 18:09:48 -0600
commit94671710183c3f5eed7cf33f73600c836e4777fd (patch)
tree8f34b9c83c713fad030ced77a4ae1c00080964fe /drivers
parentbb2a08c01a66e77917bd2fdaf5cffd917ec03573 (diff)
downloadlinux-next-94671710183c3f5eed7cf33f73600c836e4777fd.tar.gz
ipmi: Pick up slave address from SMBIOS on an ACPI device
When added by ACPI, the information does not contain the slave address of the BMC. However, that information is available from SMBIOS. So if we add a device that doesn't have a slave address, look at the other devices that are duplicate interfaces and see if they have a slave address. Signed-off-by: Corey Minyard <cminyard@mvista.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c10
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c33
2 files changed, 40 insertions, 3 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 017994900ad7..2a7c425ddfa7 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -3448,8 +3448,16 @@ static int is_new_interface(struct smi_info *info)
list_for_each_entry(e, &smi_infos, link) {
if (e->io.addr_type != info->io.addr_type)
continue;
- if (e->io.addr_data == info->io.addr_data)
+ if (e->io.addr_data == info->io.addr_data) {
+ /*
+ * This is a cheap hack, ACPI doesn't have a defined
+ * 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;
return 0;
+ }
}
return 1;
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 04232431eaf7..cca6e5bc1cea 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -174,7 +174,6 @@ enum ssif_stat_indexes {
};
struct ssif_addr_info {
- unsigned short addr;
struct i2c_board_info binfo;
char *adapter_name;
int debug;
@@ -1401,6 +1400,34 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
return false;
}
+static int find_slave_address(struct i2c_client *client, int slave_addr)
+{
+ struct ssif_addr_info *info;
+
+ if (slave_addr)
+ return slave_addr;
+
+ /*
+ * Came in without a slave address, search around to see if
+ * the other sources have a slave address. This lets us pick
+ * up an SMBIOS slave address when using ACPI.
+ */
+ list_for_each_entry(info, &ssif_infos, link) {
+ if (info->binfo.addr != client->addr)
+ continue;
+ if (info->adapter_name && client->adapter->name &&
+ strcmp_nospace(info->adapter_name,
+ client->adapter->name))
+ continue;
+ if (info->slave_addr) {
+ slave_addr = info->slave_addr;
+ break;
+ }
+ }
+
+ return slave_addr;
+}
+
/*
* Global enables we care about.
*/
@@ -1443,6 +1470,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
+ slave_addr = find_slave_address(client, slave_addr);
+
pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n",
ipmi_addr_src_to_str(ssif_info->addr_source),
client->addr, client->adapter->name, slave_addr);
@@ -1931,7 +1960,7 @@ static int decode_dmi(const struct dmi_device *dmi_dev)
slave_addr = data[6];
}
- return new_ssif_client(myaddr, NULL, 0, 0, SI_SMBIOS);
+ return new_ssif_client(myaddr, NULL, 0, slave_addr, SI_SMBIOS);
}
static void dmi_iterator(void)