1 // SPDX-License-Identifier: GPL-2.0+
4 * Add an IPMI platform device.
7 #include <linux/platform_device.h>
8 #include "ipmi_plat_data.h"
11 struct platform_device *ipmi_platform_add(const char *name, unsigned int inst,
12 struct ipmi_plat_data *p)
14 struct platform_device *pdev;
15 unsigned int num_r = 1, size, pidx = 0;
17 struct property_entry pr[6];
21 memset(pr, 0, sizeof(pr));
22 memset(r, 0, sizeof(r));
26 else if (p->type == SI_TYPE_INVALID)
32 p->regsize = DEFAULT_REGSIZE;
33 if (p->regspacing == 0)
34 p->regspacing = p->regsize;
36 pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type", p->type);
38 pr[pidx++] = PROPERTY_ENTRY_U8("slave-addr", p->slave_addr);
39 pr[pidx++] = PROPERTY_ENTRY_U8("addr-source", p->addr_source);
41 pr[pidx++] = PROPERTY_ENTRY_U8("reg-shift", p->regshift);
42 pr[pidx++] = PROPERTY_ENTRY_U8("reg-size", p->regsize);
43 /* Last entry must be left NULL to terminate it. */
45 pdev = platform_device_alloc(name, inst);
47 pr_err("Error allocating IPMI platform device %s.%d\n",
53 /* An invalid or SSIF interface, no resources. */
57 * Register spacing is derived from the resources in
58 * the IPMI platform code.
61 if (p->space == IPMI_IO_ADDR_SPACE)
62 flags = IORESOURCE_IO;
64 flags = IORESOURCE_MEM;
67 r[0].end = r[0].start + p->regsize - 1;
68 r[0].name = "IPMI Address 1";
72 r[1].start = r[0].start + p->regspacing;
73 r[1].end = r[1].start + p->regsize - 1;
74 r[1].name = "IPMI Address 2";
80 r[2].start = r[1].start + p->regspacing;
81 r[2].end = r[2].start + p->regsize - 1;
82 r[2].name = "IPMI Address 3";
88 r[num_r].start = p->irq;
89 r[num_r].end = p->irq;
90 r[num_r].name = "IPMI IRQ";
91 r[num_r].flags = IORESOURCE_IRQ;
95 rv = platform_device_add_resources(pdev, r, num_r);
98 "Unable to add hard-code resources: %d\n", rv);
102 rv = platform_device_add_properties(pdev, pr);
105 "Unable to add hard-code properties: %d\n", rv);
109 rv = platform_device_add(pdev);
112 "Unable to add hard-code device: %d\n", rv);
118 platform_device_put(pdev);
121 EXPORT_SYMBOL(ipmi_platform_add);