root/drivers/char/ipmi/ipmi_plat_data.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ipmi_platform_add

   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 
  11 struct 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 = platform_device_add_properties(pdev, pr);
 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 
 120 err:
 121         platform_device_put(pdev);
 122         return NULL;
 123 }
 124 EXPORT_SYMBOL(ipmi_platform_add);

/* [<][>][^][v][top][bottom][index][help] */