cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ipmi_plat_data.c (2825B)


      1// SPDX-License-Identifier: GPL-2.0+
      2
      3/*
      4 * Add an IPMI platform device.
      5 */
      6
      7#include <linux/platform_device.h>
      8#include "ipmi_plat_data.h"
      9#include "ipmi_si.h"
     10
     11struct platform_device *ipmi_platform_add(const char *name, unsigned int inst,
     12					  struct ipmi_plat_data *p)
     13{
     14	struct platform_device *pdev;
     15	unsigned int num_r = 1, size = 0, pidx = 0;
     16	struct resource r[4];
     17	struct property_entry pr[6];
     18	u32 flags;
     19	int rv;
     20
     21	memset(pr, 0, sizeof(pr));
     22	memset(r, 0, sizeof(r));
     23
     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;
     29
     30		if (p->regsize == 0)
     31			p->regsize = DEFAULT_REGSIZE;
     32		if (p->regspacing == 0)
     33			p->regspacing = p->regsize;
     34
     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
     40	if (p->slave_addr)
     41		pr[pidx++] = PROPERTY_ENTRY_U8("slave-addr", p->slave_addr);
     42	pr[pidx++] = PROPERTY_ENTRY_U8("addr-source", p->addr_source);
     43	if (p->regshift)
     44		pr[pidx++] = PROPERTY_ENTRY_U8("reg-shift", p->regshift);
     45	pr[pidx++] = PROPERTY_ENTRY_U8("reg-size", p->regsize);
     46	/* Last entry must be left NULL to terminate it. */
     47
     48	pdev = platform_device_alloc(name, inst);
     49	if (!pdev) {
     50		pr_err("Error allocating IPMI platform device %s.%d\n",
     51		       name, inst);
     52		return NULL;
     53	}
     54
     55	if (size == 0)
     56		/* An invalid or SSIF interface, no resources. */
     57		goto add_properties;
     58
     59	/*
     60	 * Register spacing is derived from the resources in
     61	 * the IPMI platform code.
     62	 */
     63
     64	if (p->space == IPMI_IO_ADDR_SPACE)
     65		flags = IORESOURCE_IO;
     66	else
     67		flags = IORESOURCE_MEM;
     68
     69	r[0].start = p->addr;
     70	r[0].end = r[0].start + p->regsize - 1;
     71	r[0].name = "IPMI Address 1";
     72	r[0].flags = flags;
     73
     74	if (size > 1) {
     75		r[1].start = r[0].start + p->regspacing;
     76		r[1].end = r[1].start + p->regsize - 1;
     77		r[1].name = "IPMI Address 2";
     78		r[1].flags = flags;
     79		num_r++;
     80	}
     81
     82	if (size > 2) {
     83		r[2].start = r[1].start + p->regspacing;
     84		r[2].end = r[2].start + p->regsize - 1;
     85		r[2].name = "IPMI Address 3";
     86		r[2].flags = flags;
     87		num_r++;
     88	}
     89
     90	if (p->irq) {
     91		r[num_r].start = p->irq;
     92		r[num_r].end = p->irq;
     93		r[num_r].name = "IPMI IRQ";
     94		r[num_r].flags = IORESOURCE_IRQ;
     95		num_r++;
     96	}
     97
     98	rv = platform_device_add_resources(pdev, r, num_r);
     99	if (rv) {
    100		dev_err(&pdev->dev,
    101			"Unable to add hard-code resources: %d\n", rv);
    102		goto err;
    103	}
    104 add_properties:
    105	rv = device_create_managed_software_node(&pdev->dev, pr, NULL);
    106	if (rv) {
    107		dev_err(&pdev->dev,
    108			"Unable to add hard-code properties: %d\n", rv);
    109		goto err;
    110	}
    111
    112	rv = platform_device_add(pdev);
    113	if (rv) {
    114		dev_err(&pdev->dev,
    115			"Unable to add hard-code device: %d\n", rv);
    116		goto err;
    117	}
    118	return pdev;
    119
    120err:
    121	platform_device_put(pdev);
    122	return NULL;
    123}
    124EXPORT_SYMBOL(ipmi_platform_add);