root/drivers/pnp/core.c

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

DEFINITIONS

This source file includes following definitions.
  1. pnp_alloc
  2. pnp_remove_protocol
  3. pnp_register_protocol
  4. pnp_unregister_protocol
  5. pnp_free_ids
  6. pnp_free_resource
  7. pnp_free_resources
  8. pnp_release_device
  9. pnp_alloc_dev
  10. pnp_delist_device
  11. __pnp_add_device
  12. pnp_add_device
  13. __pnp_remove_device
  14. pnp_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * core.c - contains all core device and protocol registration functions
   4  *
   5  * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
   6  */
   7 
   8 #include <linux/pnp.h>
   9 #include <linux/types.h>
  10 #include <linux/list.h>
  11 #include <linux/device.h>
  12 #include <linux/module.h>
  13 #include <linux/mutex.h>
  14 #include <linux/init.h>
  15 #include <linux/string.h>
  16 #include <linux/slab.h>
  17 #include <linux/errno.h>
  18 #include <linux/dma-mapping.h>
  19 
  20 #include "base.h"
  21 
  22 static LIST_HEAD(pnp_protocols);
  23 LIST_HEAD(pnp_global);
  24 DEFINE_MUTEX(pnp_lock);
  25 
  26 /*
  27  * ACPI or PNPBIOS should tell us about all platform devices, so we can
  28  * skip some blind probes.  ISAPNP typically enumerates only plug-in ISA
  29  * devices, not built-in things like COM ports.
  30  */
  31 int pnp_platform_devices;
  32 EXPORT_SYMBOL(pnp_platform_devices);
  33 
  34 void *pnp_alloc(long size)
  35 {
  36         void *result;
  37 
  38         result = kzalloc(size, GFP_KERNEL);
  39         if (!result) {
  40                 printk(KERN_ERR "pnp: Out of Memory\n");
  41                 return NULL;
  42         }
  43         return result;
  44 }
  45 
  46 static void pnp_remove_protocol(struct pnp_protocol *protocol)
  47 {
  48         mutex_lock(&pnp_lock);
  49         list_del(&protocol->protocol_list);
  50         mutex_unlock(&pnp_lock);
  51 }
  52 
  53 /**
  54  * pnp_protocol_register - adds a pnp protocol to the pnp layer
  55  * @protocol: pointer to the corresponding pnp_protocol structure
  56  *
  57  *  Ex protocols: ISAPNP, PNPBIOS, etc
  58  */
  59 int pnp_register_protocol(struct pnp_protocol *protocol)
  60 {
  61         struct list_head *pos;
  62         int nodenum, ret;
  63 
  64         INIT_LIST_HEAD(&protocol->devices);
  65         INIT_LIST_HEAD(&protocol->cards);
  66         nodenum = 0;
  67 
  68         mutex_lock(&pnp_lock);
  69 
  70         /* assign the lowest unused number */
  71         list_for_each(pos, &pnp_protocols) {
  72                 struct pnp_protocol *cur = to_pnp_protocol(pos);
  73                 if (cur->number == nodenum) {
  74                         pos = &pnp_protocols;
  75                         nodenum++;
  76                 }
  77         }
  78 
  79         protocol->number = nodenum;
  80         dev_set_name(&protocol->dev, "pnp%d", nodenum);
  81 
  82         list_add_tail(&protocol->protocol_list, &pnp_protocols);
  83 
  84         mutex_unlock(&pnp_lock);
  85 
  86         ret = device_register(&protocol->dev);
  87         if (ret)
  88                 pnp_remove_protocol(protocol);
  89 
  90         return ret;
  91 }
  92 
  93 /**
  94  * pnp_protocol_unregister - removes a pnp protocol from the pnp layer
  95  * @protocol: pointer to the corresponding pnp_protocol structure
  96  */
  97 void pnp_unregister_protocol(struct pnp_protocol *protocol)
  98 {
  99         pnp_remove_protocol(protocol);
 100         device_unregister(&protocol->dev);
 101 }
 102 
 103 static void pnp_free_ids(struct pnp_dev *dev)
 104 {
 105         struct pnp_id *id;
 106         struct pnp_id *next;
 107 
 108         id = dev->id;
 109         while (id) {
 110                 next = id->next;
 111                 kfree(id);
 112                 id = next;
 113         }
 114 }
 115 
 116 void pnp_free_resource(struct pnp_resource *pnp_res)
 117 {
 118         list_del(&pnp_res->list);
 119         kfree(pnp_res);
 120 }
 121 
 122 void pnp_free_resources(struct pnp_dev *dev)
 123 {
 124         struct pnp_resource *pnp_res, *tmp;
 125 
 126         list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
 127                 pnp_free_resource(pnp_res);
 128         }
 129 }
 130 
 131 static void pnp_release_device(struct device *dmdev)
 132 {
 133         struct pnp_dev *dev = to_pnp_dev(dmdev);
 134 
 135         pnp_free_ids(dev);
 136         pnp_free_resources(dev);
 137         pnp_free_options(dev);
 138         kfree(dev);
 139 }
 140 
 141 struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
 142                               const char *pnpid)
 143 {
 144         struct pnp_dev *dev;
 145         struct pnp_id *dev_id;
 146 
 147         dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
 148         if (!dev)
 149                 return NULL;
 150 
 151         INIT_LIST_HEAD(&dev->resources);
 152         INIT_LIST_HEAD(&dev->options);
 153         dev->protocol = protocol;
 154         dev->number = id;
 155         dev->dma_mask = DMA_BIT_MASK(24);
 156 
 157         dev->dev.parent = &dev->protocol->dev;
 158         dev->dev.bus = &pnp_bus_type;
 159         dev->dev.dma_mask = &dev->dma_mask;
 160         dev->dev.coherent_dma_mask = dev->dma_mask;
 161         dev->dev.release = &pnp_release_device;
 162 
 163         dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
 164 
 165         dev_id = pnp_add_id(dev, pnpid);
 166         if (!dev_id) {
 167                 kfree(dev);
 168                 return NULL;
 169         }
 170 
 171         return dev;
 172 }
 173 
 174 static void pnp_delist_device(struct pnp_dev *dev)
 175 {
 176         mutex_lock(&pnp_lock);
 177         list_del(&dev->global_list);
 178         list_del(&dev->protocol_list);
 179         mutex_unlock(&pnp_lock);
 180 }
 181 
 182 int __pnp_add_device(struct pnp_dev *dev)
 183 {
 184         int ret;
 185 
 186         pnp_fixup_device(dev);
 187         dev->status = PNP_READY;
 188 
 189         mutex_lock(&pnp_lock);
 190 
 191         list_add_tail(&dev->global_list, &pnp_global);
 192         list_add_tail(&dev->protocol_list, &dev->protocol->devices);
 193 
 194         mutex_unlock(&pnp_lock);
 195 
 196         ret = device_register(&dev->dev);
 197         if (ret)
 198                 pnp_delist_device(dev);
 199         else if (dev->protocol->can_wakeup)
 200                 device_set_wakeup_capable(&dev->dev,
 201                                 dev->protocol->can_wakeup(dev));
 202 
 203         return ret;
 204 }
 205 
 206 /*
 207  * pnp_add_device - adds a pnp device to the pnp layer
 208  * @dev: pointer to dev to add
 209  *
 210  *  adds to driver model, name database, fixups, interface, etc.
 211  */
 212 int pnp_add_device(struct pnp_dev *dev)
 213 {
 214         int ret;
 215         char buf[128];
 216         int len = 0;
 217         struct pnp_id *id;
 218 
 219         if (dev->card)
 220                 return -EINVAL;
 221 
 222         ret = __pnp_add_device(dev);
 223         if (ret)
 224                 return ret;
 225 
 226         buf[0] = '\0';
 227         for (id = dev->id; id; id = id->next)
 228                 len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id);
 229 
 230         dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs%s (%s)\n",
 231                    dev->protocol->name, buf,
 232                    dev->active ? "active" : "disabled");
 233         return 0;
 234 }
 235 
 236 void __pnp_remove_device(struct pnp_dev *dev)
 237 {
 238         pnp_delist_device(dev);
 239         device_unregister(&dev->dev);
 240 }
 241 
 242 static int __init pnp_init(void)
 243 {
 244         return bus_register(&pnp_bus_type);
 245 }
 246 
 247 subsys_initcall(pnp_init);
 248 
 249 int pnp_debug;
 250 
 251 #if defined(CONFIG_PNP_DEBUG_MESSAGES)
 252 module_param_named(debug, pnp_debug, int, 0644);
 253 #endif

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