// SPDX-License-Identifier: GPL-2.0+
/*
* Add an IPMI platform device.
*/
#include <linux/platform_device.h>
#include "ipmi_plat_data.h"
#include "ipmi_si.h"
struct platform_device *ipmi_platform_add(const char *name, unsigned int inst,
struct ipmi_plat_data *p)
{
struct platform_device *pdev;
unsigned int num_r = 1, size = 0, pidx = 0;
struct resource r[4];
struct property_entry pr[6];
u32 flags;
int rv;
memset(pr, 0, sizeof (pr));
memset(r, 0, sizeof (r));
if (p->iftype == IPMI_PLAT_IF_SI) {
if (p->type == SI_BT)
size = 3;
else if (p->type != SI_TYPE_INVALID)
size = 2;
if (p->regsize == 0)
p->regsize = DEFAULT_REGSIZE;
if (p->regspacing == 0)
p->regspacing = p->regsize;
pr[pidx++] = PROPERTY_ENTRY_U8("ipmi-type" , p->type);
} else if (p->iftype == IPMI_PLAT_IF_SSIF) {
pr[pidx++] = PROPERTY_ENTRY_U16("i2c-addr" , p->addr);
}
if (p->slave_addr)
pr[pidx++] = PROPERTY_ENTRY_U8("slave-addr" , p->slave_addr);
pr[pidx++] = PROPERTY_ENTRY_U8("addr-source" , p->addr_source);
if (p->regshift)
pr[pidx++] = PROPERTY_ENTRY_U8("reg-shift" , p->regshift);
pr[pidx++] = PROPERTY_ENTRY_U8("reg-size" , p->regsize);
/* Last entry must be left NULL to terminate it. */
pdev = platform_device_alloc(name, inst);
if (!pdev) {
pr_err("Error allocating IPMI platform device %s.%d\n" ,
name, inst);
return NULL;
}
if (size == 0)
/* An invalid or SSIF interface, no resources. */
goto add_properties;
/*
* Register spacing is derived from the resources in
* the IPMI platform code.
*/
if (p->space == IPMI_IO_ADDR_SPACE)
flags = IORESOURCE_IO;
else
flags = IORESOURCE_MEM;
r[0].start = p->addr;
r[0].end = r[0].start + p->regsize - 1;
r[0].name = "IPMI Address 1" ;
r[0].flags = flags;
if (size > 1) {
r[1].start = r[0].start + p->regspacing;
r[1].end = r[1].start + p->regsize - 1;
r[1].name = "IPMI Address 2" ;
r[1].flags = flags;
num_r++;
}
if (size > 2) {
r[2].start = r[1].start + p->regspacing;
r[2].end = r[2].start + p->regsize - 1;
r[2].name = "IPMI Address 3" ;
r[2].flags = flags;
num_r++;
}
if (p->irq) {
r[num_r].start = p->irq;
r[num_r].end = p->irq;
r[num_r].name = "IPMI IRQ" ;
r[num_r].flags = IORESOURCE_IRQ;
num_r++;
}
rv = platform_device_add_resources(pdev, r, num_r);
if (rv) {
dev_err(&pdev->dev,
"Unable to add hard-code resources: %d\n" , rv);
goto err;
}
add_properties:
rv = device_create_managed_software_node(&pdev->dev, pr, NULL);
if (rv) {
dev_err(&pdev->dev,
"Unable to add hard-code properties: %d\n" , rv);
goto err;
}
rv = platform_device_add(pdev);
if (rv) {
dev_err(&pdev->dev,
"Unable to add hard-code device: %d\n" , rv);
goto err;
}
return pdev;
err:
platform_device_put(pdev);
return NULL;
}
EXPORT_SYMBOL(ipmi_platform_add);
Messung V0.5 C=97 H=81 G=89
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland