Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipmi: Add the i2c-addr property for SSIF interfaces

This is required for SSIF to work.

There was no way to know if the interface being added was SI
or SSIF from the platform data, but that was required so the
i2c-addr is only added for SSIF interfaces. So add a field
for that.

Also rework the logic a bit so that ipmi-type is not set
for SSIF interfaces, as it is not necessary for that.

Fixes: 3cd83bac481d ("ipmi: Consolidate the adding of platform devices")
Reported-by: Kamlakant Patel <kamlakantp@marvell.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # 5.1

+22 -12
+2
drivers/char/ipmi/ipmi_dmi.c
··· 47 47 memset(&p, 0, sizeof(p)); 48 48 49 49 name = "dmi-ipmi-si"; 50 + p.iftype = IPMI_PLAT_IF_SI; 50 51 switch (type) { 51 52 case IPMI_DMI_TYPE_SSIF: 52 53 name = "dmi-ipmi-ssif"; 54 + p.iftype = IPMI_PLAT_IF_SSIF; 53 55 p.type = SI_TYPE_INVALID; 54 56 break; 55 57 case IPMI_DMI_TYPE_BT:
+15 -12
drivers/char/ipmi/ipmi_plat_data.c
··· 12 12 struct ipmi_plat_data *p) 13 13 { 14 14 struct platform_device *pdev; 15 - unsigned int num_r = 1, size, pidx = 0; 15 + unsigned int num_r = 1, size = 0, pidx = 0; 16 16 struct resource r[4]; 17 17 struct property_entry pr[6]; 18 18 u32 flags; ··· 21 21 memset(pr, 0, sizeof(pr)); 22 22 memset(r, 0, sizeof(r)); 23 23 24 - if (p->type == SI_BT) 25 - size = 3; 26 - else if (p->type == SI_TYPE_INVALID) 27 - size = 0; 28 - else 29 - size = 2; 24 + if (p->iftype == IPMI_PLAT_IF_SI) { 25 + if (p->type == SI_BT) 26 + size = 3; 27 + else if (p->type != SI_TYPE_INVALID) 28 + size = 2; 30 29 31 - if (p->regsize == 0) 32 - p->regsize = DEFAULT_REGSIZE; 33 - if (p->regspacing == 0) 34 - p->regspacing = p->regsize; 30 + if (p->regsize == 0) 31 + p->regsize = DEFAULT_REGSIZE; 32 + if (p->regspacing == 0) 33 + p->regspacing = p->regsize; 35 34 36 - pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", p->type); 35 + pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", p->type); 36 + } else if (p->iftype == IPMI_PLAT_IF_SSIF) { 37 + pr[pidx++] = PROPERTY_ENTRY_U16("i2c-addr", p->addr); 38 + } 39 + 37 40 if (p->slave_addr) 38 41 pr[pidx++] = PROPERTY_ENTRY_U8("slave-addr", p->slave_addr); 39 42 pr[pidx++] = PROPERTY_ENTRY_U8("addr-source", p->addr_source);
+3
drivers/char/ipmi/ipmi_plat_data.h
··· 6 6 7 7 #include <linux/ipmi.h> 8 8 9 + enum ipmi_plat_interface_type { IPMI_PLAT_IF_SI, IPMI_PLAT_IF_SSIF }; 10 + 9 11 struct ipmi_plat_data { 12 + enum ipmi_plat_interface_type iftype; 10 13 unsigned int type; /* si_type for si, SI_INVALID for others */ 11 14 unsigned int space; /* addr_space for si, intf# for ssif. */ 12 15 unsigned long addr;
+1
drivers/char/ipmi/ipmi_si_hardcode.c
··· 83 83 84 84 memset(&p, 0, sizeof(p)); 85 85 86 + p.iftype = IPMI_PLAT_IF_SI; 86 87 if (!si_type_str || !*si_type_str || strcmp(si_type_str, "kcs") == 0) { 87 88 p.type = SI_KCS; 88 89 } else if (strcmp(si_type_str, "smic") == 0) {
+1
drivers/char/ipmi/ipmi_si_hotmod.c
··· 108 108 int rv; 109 109 unsigned int ival; 110 110 111 + h->iftype = IPMI_PLAT_IF_SI; 111 112 rv = parse_str(hotmod_ops, &ival, "operation", &curr); 112 113 if (rv) 113 114 return rv;