| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
|---|
| 2 | 2 | |
|---|
| 3 | +#define pr_fmt(fmt) "ipmi_hardcode: " fmt |
|---|
| 4 | + |
|---|
| 3 | 5 | #include <linux/moduleparam.h> |
|---|
| 4 | 6 | #include <linux/platform_device.h> |
|---|
| 5 | 7 | #include "ipmi_si.h" |
|---|
| 8 | +#include "ipmi_plat_data.h" |
|---|
| 6 | 9 | |
|---|
| 7 | | -#define PFX "ipmi_hardcode: " |
|---|
| 8 | 10 | /* |
|---|
| 9 | 11 | * There can be 4 IO ports passed in (with or without IRQs), 4 addresses, |
|---|
| 10 | 12 | * a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS. |
|---|
| .. | .. |
|---|
| 72 | 74 | " overridden by this parm. This is an array indexed" |
|---|
| 73 | 75 | " by interface number."); |
|---|
| 74 | 76 | |
|---|
| 75 | | -static struct platform_device *ipmi_hc_pdevs[SI_MAX_PARMS]; |
|---|
| 76 | | - |
|---|
| 77 | 77 | static void __init ipmi_hardcode_init_one(const char *si_type_str, |
|---|
| 78 | 78 | unsigned int i, |
|---|
| 79 | 79 | unsigned long addr, |
|---|
| 80 | | - unsigned int flags) |
|---|
| 80 | + enum ipmi_addr_space addr_space) |
|---|
| 81 | 81 | { |
|---|
| 82 | | - struct platform_device *pdev; |
|---|
| 83 | | - unsigned int num_r = 1, size; |
|---|
| 84 | | - struct resource r[4]; |
|---|
| 85 | | - struct property_entry p[6]; |
|---|
| 86 | | - enum si_type si_type; |
|---|
| 87 | | - unsigned int regspacing, regsize; |
|---|
| 88 | | - int rv; |
|---|
| 82 | + struct ipmi_plat_data p; |
|---|
| 89 | 83 | |
|---|
| 90 | | - memset(p, 0, sizeof(p)); |
|---|
| 91 | | - memset(r, 0, sizeof(r)); |
|---|
| 84 | + memset(&p, 0, sizeof(p)); |
|---|
| 92 | 85 | |
|---|
| 86 | + p.iftype = IPMI_PLAT_IF_SI; |
|---|
| 93 | 87 | if (!si_type_str || !*si_type_str || strcmp(si_type_str, "kcs") == 0) { |
|---|
| 94 | | - size = 2; |
|---|
| 95 | | - si_type = SI_KCS; |
|---|
| 88 | + p.type = SI_KCS; |
|---|
| 96 | 89 | } else if (strcmp(si_type_str, "smic") == 0) { |
|---|
| 97 | | - size = 2; |
|---|
| 98 | | - si_type = SI_SMIC; |
|---|
| 90 | + p.type = SI_SMIC; |
|---|
| 99 | 91 | } else if (strcmp(si_type_str, "bt") == 0) { |
|---|
| 100 | | - size = 3; |
|---|
| 101 | | - si_type = SI_BT; |
|---|
| 92 | + p.type = SI_BT; |
|---|
| 102 | 93 | } else if (strcmp(si_type_str, "invalid") == 0) { |
|---|
| 103 | 94 | /* |
|---|
| 104 | 95 | * Allow a firmware-specified interface to be |
|---|
| 105 | 96 | * disabled. |
|---|
| 106 | 97 | */ |
|---|
| 107 | | - size = 1; |
|---|
| 108 | | - si_type = SI_TYPE_INVALID; |
|---|
| 98 | + p.type = SI_TYPE_INVALID; |
|---|
| 109 | 99 | } else { |
|---|
| 110 | 100 | pr_warn("Interface type specified for interface %d, was invalid: %s\n", |
|---|
| 111 | 101 | i, si_type_str); |
|---|
| 112 | 102 | return; |
|---|
| 113 | 103 | } |
|---|
| 114 | 104 | |
|---|
| 115 | | - regsize = regsizes[i]; |
|---|
| 116 | | - if (regsize == 0) |
|---|
| 117 | | - regsize = DEFAULT_REGSIZE; |
|---|
| 105 | + p.regsize = regsizes[i]; |
|---|
| 106 | + p.slave_addr = slave_addrs[i]; |
|---|
| 107 | + p.addr_source = SI_HARDCODED; |
|---|
| 108 | + p.regshift = regshifts[i]; |
|---|
| 109 | + p.regsize = regsizes[i]; |
|---|
| 110 | + p.addr = addr; |
|---|
| 111 | + p.space = addr_space; |
|---|
| 118 | 112 | |
|---|
| 119 | | - p[0] = PROPERTY_ENTRY_U8("ipmi-type", si_type); |
|---|
| 120 | | - p[1] = PROPERTY_ENTRY_U8("slave-addr", slave_addrs[i]); |
|---|
| 121 | | - p[2] = PROPERTY_ENTRY_U8("addr-source", SI_HARDCODED); |
|---|
| 122 | | - p[3] = PROPERTY_ENTRY_U8("reg-shift", regshifts[i]); |
|---|
| 123 | | - p[4] = PROPERTY_ENTRY_U8("reg-size", regsize); |
|---|
| 124 | | - /* Last entry must be left NULL to terminate it. */ |
|---|
| 125 | | - |
|---|
| 126 | | - /* |
|---|
| 127 | | - * Register spacing is derived from the resources in |
|---|
| 128 | | - * the IPMI platform code. |
|---|
| 129 | | - */ |
|---|
| 130 | | - regspacing = regspacings[i]; |
|---|
| 131 | | - if (regspacing == 0) |
|---|
| 132 | | - regspacing = regsize; |
|---|
| 133 | | - |
|---|
| 134 | | - r[0].start = addr; |
|---|
| 135 | | - r[0].end = r[0].start + regsize - 1; |
|---|
| 136 | | - r[0].name = "IPMI Address 1"; |
|---|
| 137 | | - r[0].flags = flags; |
|---|
| 138 | | - |
|---|
| 139 | | - if (size > 1) { |
|---|
| 140 | | - r[1].start = r[0].start + regspacing; |
|---|
| 141 | | - r[1].end = r[1].start + regsize - 1; |
|---|
| 142 | | - r[1].name = "IPMI Address 2"; |
|---|
| 143 | | - r[1].flags = flags; |
|---|
| 144 | | - num_r++; |
|---|
| 145 | | - } |
|---|
| 146 | | - |
|---|
| 147 | | - if (size > 2) { |
|---|
| 148 | | - r[2].start = r[1].start + regspacing; |
|---|
| 149 | | - r[2].end = r[2].start + regsize - 1; |
|---|
| 150 | | - r[2].name = "IPMI Address 3"; |
|---|
| 151 | | - r[2].flags = flags; |
|---|
| 152 | | - num_r++; |
|---|
| 153 | | - } |
|---|
| 154 | | - |
|---|
| 155 | | - if (irqs[i]) { |
|---|
| 156 | | - r[num_r].start = irqs[i]; |
|---|
| 157 | | - r[num_r].end = irqs[i]; |
|---|
| 158 | | - r[num_r].name = "IPMI IRQ"; |
|---|
| 159 | | - r[num_r].flags = IORESOURCE_IRQ; |
|---|
| 160 | | - num_r++; |
|---|
| 161 | | - } |
|---|
| 162 | | - |
|---|
| 163 | | - pdev = platform_device_alloc("hardcode-ipmi-si", i); |
|---|
| 164 | | - if (!pdev) { |
|---|
| 165 | | - pr_err("Error allocating IPMI platform device %d\n", i); |
|---|
| 166 | | - return; |
|---|
| 167 | | - } |
|---|
| 168 | | - |
|---|
| 169 | | - rv = platform_device_add_resources(pdev, r, num_r); |
|---|
| 170 | | - if (rv) { |
|---|
| 171 | | - dev_err(&pdev->dev, |
|---|
| 172 | | - "Unable to add hard-code resources: %d\n", rv); |
|---|
| 173 | | - goto err; |
|---|
| 174 | | - } |
|---|
| 175 | | - |
|---|
| 176 | | - rv = platform_device_add_properties(pdev, p); |
|---|
| 177 | | - if (rv) { |
|---|
| 178 | | - dev_err(&pdev->dev, |
|---|
| 179 | | - "Unable to add hard-code properties: %d\n", rv); |
|---|
| 180 | | - goto err; |
|---|
| 181 | | - } |
|---|
| 182 | | - |
|---|
| 183 | | - rv = platform_device_add(pdev); |
|---|
| 184 | | - if (rv) { |
|---|
| 185 | | - dev_err(&pdev->dev, |
|---|
| 186 | | - "Unable to add hard-code device: %d\n", rv); |
|---|
| 187 | | - goto err; |
|---|
| 188 | | - } |
|---|
| 189 | | - |
|---|
| 190 | | - ipmi_hc_pdevs[i] = pdev; |
|---|
| 191 | | - return; |
|---|
| 192 | | - |
|---|
| 193 | | -err: |
|---|
| 194 | | - platform_device_put(pdev); |
|---|
| 113 | + ipmi_platform_add("hardcode-ipmi-si", i, &p); |
|---|
| 195 | 114 | } |
|---|
| 196 | 115 | |
|---|
| 197 | 116 | void __init ipmi_hardcode_init(void) |
|---|
| .. | .. |
|---|
| 220 | 139 | for (i = 0; i < SI_MAX_PARMS; i++) { |
|---|
| 221 | 140 | if (i < num_ports && ports[i]) |
|---|
| 222 | 141 | ipmi_hardcode_init_one(si_type[i], i, ports[i], |
|---|
| 223 | | - IORESOURCE_IO); |
|---|
| 142 | + IPMI_IO_ADDR_SPACE); |
|---|
| 224 | 143 | if (i < num_addrs && addrs[i]) |
|---|
| 225 | 144 | ipmi_hardcode_init_one(si_type[i], i, addrs[i], |
|---|
| 226 | | - IORESOURCE_MEM); |
|---|
| 145 | + IPMI_MEM_ADDR_SPACE); |
|---|
| 227 | 146 | } |
|---|
| 228 | 147 | } |
|---|
| 229 | 148 | |
|---|
| 149 | + |
|---|
| 230 | 150 | void ipmi_si_hardcode_exit(void) |
|---|
| 231 | 151 | { |
|---|
| 232 | | - unsigned int i; |
|---|
| 233 | | - |
|---|
| 234 | | - for (i = 0; i < SI_MAX_PARMS; i++) { |
|---|
| 235 | | - if (ipmi_hc_pdevs[i]) |
|---|
| 236 | | - platform_device_unregister(ipmi_hc_pdevs[i]); |
|---|
| 237 | | - } |
|---|
| 152 | + ipmi_remove_platform_device_by_name("hardcode-ipmi-si"); |
|---|
| 238 | 153 | } |
|---|
| 239 | 154 | |
|---|
| 240 | 155 | /* |
|---|
| 241 | 156 | * Returns true of the given address exists as a hardcoded address, |
|---|
| 242 | 157 | * false if not. |
|---|
| 243 | 158 | */ |
|---|
| 244 | | -int ipmi_si_hardcode_match(int addr_type, unsigned long addr) |
|---|
| 159 | +int ipmi_si_hardcode_match(int addr_space, unsigned long addr) |
|---|
| 245 | 160 | { |
|---|
| 246 | 161 | unsigned int i; |
|---|
| 247 | 162 | |
|---|
| 248 | | - if (addr_type == IPMI_IO_ADDR_SPACE) { |
|---|
| 163 | + if (addr_space == IPMI_IO_ADDR_SPACE) { |
|---|
| 249 | 164 | for (i = 0; i < num_ports; i++) { |
|---|
| 250 | 165 | if (ports[i] == addr) |
|---|
| 251 | 166 | return 1; |
|---|