/* add firmware name into devres list */ static int fw_add_devm_name(struct device *dev, const char *name) { struct fw_name_devm *fwn; fwn = fw_find_devm_name(dev, name); if (fwn) return 1; fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + strlen(name) + 1, GFP_KERNEL); if (!fwn) return -ENOMEM; fwn->magic = (unsigned long)&fw_cache; strcpy(fwn->name, name); devres_add(dev, fwn); return 0; }
/** * devm_snd_soc_register_card - resource managed card registration * @dev: Device used to manage card * @card: Card to register * * Register a card with automatic unregistration when the device is * unregistered. */ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) { struct snd_soc_card **ptr; int ret; ptr = devres_alloc(devm_card_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return -ENOMEM; ret = snd_soc_register_card(card); if (ret == 0) { *ptr = card; devres_add(dev, ptr); } else { devres_free(ptr); } return ret; }
int devm_register_reboot_notifier(struct device *dev, struct notifier_block *nb) { struct notifier_block **rcnb; int ret; rcnb = devres_alloc(devm_unregister_reboot_notifier, sizeof(*rcnb), GFP_KERNEL); if (!rcnb) return -ENOMEM; ret = register_reboot_notifier(nb); if (!ret) { *rcnb = nb; devres_add(dev, rcnb); } else { devres_free(rcnb); } return ret; }
/** * devm_snd_soc_register_platform - resource managed platform registration * @dev: Device used to manage platform * @platform_drv: platform to register * * Register a platform driver with automatic unregistration when the device is * unregistered. */ int devm_snd_soc_register_platform(struct device *dev, const struct snd_soc_platform_driver *platform_drv) { struct device **ptr; int ret; ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return -ENOMEM; ret = snd_soc_register_platform(dev, platform_drv); if (ret == 0) { *ptr = dev; devres_add(dev, ptr); } else { devres_free(ptr); } return ret; }
/** * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration * @dev: The parent device for the PCM device * @config: Platform specific PCM configuration * @flags: Platform specific quirks * * Register a dmaengine based PCM device with automatic unregistration when the * device is unregistered. */ int devm_snd_dmaengine_pcm_register(struct device *dev, const struct snd_dmaengine_pcm_config *config, unsigned int flags) { struct device **ptr; int ret; ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return -ENOMEM; ret = snd_dmaengine_pcm_register(dev, config, flags); if (ret == 0) { *ptr = dev; devres_add(dev, ptr); } else { devres_free(ptr); } return ret; }
static int bcm2835_devm_add_vchi_ctx(struct device *dev) { struct bcm2835_vchi_ctx *vchi_ctx; int ret; vchi_ctx = devres_alloc(bcm2835_devm_free_vchi_ctx, sizeof(*vchi_ctx), GFP_KERNEL); if (!vchi_ctx) return -ENOMEM; ret = bcm2835_new_vchi_ctx(dev, vchi_ctx); if (ret) { devres_free(vchi_ctx); return ret; } devres_add(dev, vchi_ctx); return 0; }
int devm_gpio_request(struct device *dev, unsigned gpio, const char *label) { unsigned *dr; int rc; dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL); if (!dr) return -ENOMEM; rc = gpio_request(gpio, label); if (rc) { devres_free(dr); return rc; } *dr = gpio; devres_add(dev, dr); return 0; }
/** * devm_ioremap_exec_nocache - Managed ioremap_exec_nocache() * @dev: Generic device to remap IO address for * @offset: BUS offset to map * @size: Size of map * * Managed ioremap_exec_nocache(). Map is automatically unmapped on driver * detach. */ void __iomem *devm_ioremap_exec_nocache(struct device *dev, resource_size_t offset, unsigned long size) { void __iomem **ptr, *addr; ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return NULL; addr = ioremap_exec_nocache(offset, size); if (addr) { *ptr = addr; devres_add(dev, ptr); } else { devres_free(ptr); } return addr; }
static int snd_devm_add_child(struct device *dev, struct device *child) { struct device **dr; int ret; dr = devres_alloc(snd_devm_unregister_child, sizeof(*dr), GFP_KERNEL); if (!dr) return -ENOMEM; ret = device_add(child); if (ret) { devres_free(dr); return ret; } *dr = child; devres_add(dev, dr); return 0; }
/** * devm_snd_soc_register_component - resource managed component registration * @dev: Device used to manage component * @cmpnt_drv: Component driver * @dai_drv: DAI driver * @num_dai: Number of DAIs to register * * Register a component with automatic unregistration when the device is * unregistered. */ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai) { struct device **ptr; int ret; ptr = devres_alloc(devm_component_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return -ENOMEM; ret = snd_soc_register_component(dev, cmpnt_drv, dai_drv, num_dai); if (ret == 0) { *ptr = dev; devres_add(dev, ptr); } else { devres_free(ptr); } return ret; }
static struct snd_card *snd_devm_card_new(struct device *dev) { struct snd_card **dr; struct snd_card *card; int ret; dr = devres_alloc(snd_devm_card_free, sizeof(*dr), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); ret = snd_card_new(dev, -1, NULL, THIS_MODULE, 0, &card); if (ret) { devres_free(dr); return ERR_PTR(ret); } *dr = card; devres_add(dev, dr); return card; }
struct stm_device_state *devm_stm_device_init(struct device *dev, struct stm_device_config *config) { struct stm_device_state *state = devres_alloc(stm_device_devres_exit, sizeof(*state) + sizeof(*state->sysconf_fields) * config->sysconfs_num, GFP_KERNEL); BUG_ON(!dev); BUG_ON(!config); if (state) { if (__stm_device_init(state, config, dev) == 0) { devres_add(dev, state); } else { devres_free(state); state = NULL; } } return state; }
/** * irq_sim_init - Initialize the interrupt simulator for a managed device. * * @dev: Device to initialize the simulator object for. * @sim: The interrupt simulator object to initialize. * @num_irqs: Number of interrupts to allocate * * Returns 0 on success and a negative error number on failure. */ int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, unsigned int num_irqs) { struct irq_sim_devres *dr; int rv; dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL); if (!dr) return -ENOMEM; rv = irq_sim_init(sim, num_irqs); if (rv) { devres_free(dr); return rv; } dr->sim = sim; devres_add(dev, dr); return 0; }
struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv, unsigned int txqs, unsigned int rxqs) { struct net_device **dr; struct net_device *netdev; dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL); if (!dr) return NULL; netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs); if (!netdev) { devres_free(dr); return NULL; } *dr = netdev; devres_add(dev, dr); return netdev; }
/** * devm_led_classdev_register - resource managed led_classdev_register() * @parent: The device to register. * @led_cdev: the led_classdev structure for this device. */ int devm_led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { struct led_classdev **dr; int rc; dr = devres_alloc(devm_led_classdev_release, sizeof(*dr), GFP_KERNEL); if (!dr) return -ENOMEM; rc = led_classdev_register(parent, led_cdev); if (rc) { devres_free(dr); return rc; } *dr = led_cdev; devres_add(parent, dr); return 0; }
/** * devm_regulator_register - Resource managed regulator_register() * @regulator_desc: regulator to register * @config: runtime configuration for regulator * * Called by regulator drivers to register a regulator. Returns a * valid pointer to struct regulator_dev on success or an ERR_PTR() on * error. The regulator will automatically be released when the device * is unbound. */ struct regulator_dev *devm_regulator_register(struct device *dev, const struct regulator_desc *regulator_desc, const struct regulator_config *config) { struct regulator_dev **ptr, *rdev; ptr = devres_alloc(devm_rdev_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return ERR_PTR(-ENOMEM); rdev = regulator_register(regulator_desc, config); if (!IS_ERR(rdev)) { *ptr = rdev; devres_add(dev, ptr); } else { devres_free(ptr); } return rdev; }
struct dentry* devm_hello_create_u32(struct device *dev, const char *name, umode_t mode, struct dentry *parent, u32 *pvalue) { struct dentry *pu32 = NULL;\ void *ptr = NULL; if(!pvalue || !name || name[0] == '\0') return NULL; ptr = devres_alloc(devm_hello_release, 0, GFP_KERNEL); if (!ptr) return NULL; pu32 = debugfs_create_u32(name, mode, parent, pvalue); if (pu32) { devres_add(dev, ptr); } else { devres_free(ptr); } return pu32; }
int devm_rave_sp_register_event_notifier(struct device *dev, struct notifier_block *nb) { struct rave_sp *sp = dev_get_drvdata(dev->parent); struct notifier_block **rcnb; int ret; rcnb = devres_alloc(rave_sp_unregister_event_notifier, sizeof(*rcnb), GFP_KERNEL); if (!rcnb) return -ENOMEM; ret = blocking_notifier_chain_register(&sp->event_notifier_list, nb); if (!ret) { *rcnb = nb; devres_add(dev, rcnb); } else { devres_free(rcnb); } return ret; }
/** * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a * device's child node * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @index: index of the GPIO to obtain in the consumer * @child: firmware node (child of @dev) * @flags: GPIO initialization flags * * GPIO descriptors returned from this function are automatically disposed on * driver detach. * * On successfull request the GPIO pin is configured in accordance with * provided @flags. */ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, const char *con_id, int index, struct fwnode_handle *child, enum gpiod_flags flags, const char *label) { char prop_name[32]; /* 32 is max size of property name */ struct gpio_desc **dr; struct gpio_desc *desc; unsigned int i; dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, gpio_suffixes[i]); else snprintf(prop_name, sizeof(prop_name), "%s", gpio_suffixes[i]); desc = fwnode_get_named_gpiod(child, prop_name, index, flags, label); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } if (IS_ERR(desc)) { devres_free(dr); return desc; } *dr = desc; devres_add(dev, dr); return desc; }
int __must_check devm_clk_bulk_get_all(struct device *dev, struct clk_bulk_data **clks) { struct clk_bulk_devres *devres; int ret; devres = devres_alloc(devm_clk_bulk_release, sizeof(*devres), GFP_KERNEL); if (!devres) return -ENOMEM; ret = clk_bulk_get_all(dev, &devres->clks); if (ret > 0) { *clks = devres->clks; devres->num_clks = ret; devres_add(dev, devres); } else { devres_free(devres); } return ret; }
/** * devm_thermal_zone_of_sensor_register - Resource managed version of * thermal_zone_of_sensor_register() * @dev: a valid struct device pointer of a sensor device. Must contain * a valid .of_node, for the sensor node. * @sensor_id: a sensor identifier, in case the sensor IP has more * than one sensors * @data: a private pointer (owned by the caller) that will be passed * back, when a temperature reading is needed. * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. * * Refer thermal_zone_of_sensor_register() for more details. * * Return: On success returns a valid struct thermal_zone_device, * otherwise, it returns a corresponding ERR_PTR(). Caller must * check the return value with help of IS_ERR() helper. * Registered thermal_zone_device device will automatically be * released when device is unbounded. */ struct thermal_zone_device *devm_thermal_zone_of_sensor_register( struct device *dev, int sensor_id, void *data, const struct thermal_zone_of_device_ops *ops) { struct thermal_zone_device **ptr, *tzd; ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return ERR_PTR(-ENOMEM); tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops); if (IS_ERR(tzd)) { devres_free(ptr); return tzd; } *ptr = tzd; devres_add(dev, ptr); return tzd; }
struct dentry* devm_hello_create_dir(struct device *dev, const char *name, struct dentry *parent) { struct dentry *dir = NULL; void *ptr = NULL; if(!name || name[0] == '\0') return NULL; ptr = devres_alloc(devm_hello_release, 0, GFP_KERNEL); if (!ptr) return NULL; dir = debugfs_create_dir(name, parent); if (dir) { devres_add(dev, ptr); } else { devres_free(ptr); } return dir; }
static int ux500_pd_bus_notify(struct notifier_block *nb, unsigned long action, void *data, bool enable) { struct device *dev = data; struct pm_runtime_data *prd; dev_dbg(dev, "%s() %ld !\n", __func__, action); if (action == BUS_NOTIFY_BIND_DRIVER) { prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL); if (prd) { devres_add(dev, prd); platform_pm_runtime_init(dev, prd); if (enable) ux500_pd_enable(prd); } else dev_err(dev, "unable to alloc memory for runtime pm\n"); } return 0; }
/* Register CAN LED triggers for a CAN device * * This is normally called from a driver's probe function */ void devm_can_led_init(struct net_device *netdev) { struct can_priv *priv = netdev_priv(netdev); void *res; res = devres_alloc(can_led_release, 0, GFP_KERNEL); if (!res) { netdev_err(netdev, "cannot register LED triggers\n"); return; } snprintf(priv->tx_led_trig_name, sizeof(priv->tx_led_trig_name), "%s-tx", netdev->name); snprintf(priv->rx_led_trig_name, sizeof(priv->rx_led_trig_name), "%s-rx", netdev->name); led_trigger_register_simple(priv->tx_led_trig_name, &priv->tx_led_trig); led_trigger_register_simple(priv->rx_led_trig_name, &priv->rx_led_trig); devres_add(&netdev->dev, res); }
/** * devm_gpiod_get_array - Resource-managed gpiod_get_array() * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @flags: optional GPIO initialization flags * * Managed gpiod_get_array(). GPIO descriptors returned from this function are * automatically disposed on driver detach. See gpiod_get_array() for detailed * information about behavior and return values. */ struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, const char *con_id, enum gpiod_flags flags) { struct gpio_descs **dr; struct gpio_descs *descs; dr = devres_alloc(devm_gpiod_release_array, sizeof(struct gpio_descs *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); descs = gpiod_get_array(dev, con_id, flags); if (IS_ERR(descs)) { devres_free(dr); return descs; } *dr = descs; devres_add(dev, dr); return descs; }
/** * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @child: firmware node (child of @dev) * * GPIO descriptors returned from this function are automatically disposed on * driver detach. */ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, struct fwnode_handle *child) { static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ struct gpio_desc **dr; struct gpio_desc *desc; unsigned int i; dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); for (i = 0; i < ARRAY_SIZE(suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, suffixes[i]); else snprintf(prop_name, sizeof(prop_name), "%s", suffixes[i]); desc = fwnode_get_named_gpiod(child, prop_name); if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER)) break; } if (IS_ERR(desc)) { devres_free(dr); return desc; } *dr = desc; devres_add(dev, dr); return desc; }
/** * devm_input_allocate_polled_device - allocate managed polled device * @dev: device owning the polled device being created * * Returns prepared &struct input_polled_dev or %NULL. * * Managed polled input devices do not need to be explicitly unregistered * or freed as it will be done automatically when owner device unbinds * from * its driver (or binding fails). Once such managed polled device * is allocated, it is ready to be set up and registered in the same * fashion as regular polled input devices (using * input_register_polled_device() function). * * If you want to manually unregister and free such managed polled devices, * it can be still done by calling input_unregister_polled_device() and * input_free_polled_device(), although it is rarely needed. * * NOTE: the owner device is set up as parent of input device and users * should not override it. */ struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev) { struct input_polled_dev *polldev; struct input_polled_devres *devres; devres = devres_alloc(devm_input_polldev_release, sizeof(*devres), GFP_KERNEL); if (!devres) return NULL; polldev = input_allocate_polled_device(); if (!polldev) { devres_free(devres); return NULL; } polldev->input->dev.parent = dev; polldev->devres_managed = true; devres->polldev = polldev; devres_add(dev, devres); return polldev; }
void *devm_memremap_pages(struct device *dev, struct resource *res) { int is_ram = region_intersects(res->start, resource_size(res), "System RAM"); struct page_map *page_map; int error, nid; if (is_ram == REGION_MIXED) { WARN_ONCE(1, "%s attempted on mixed region %pr\n", __func__, res); return ERR_PTR(-ENXIO); } if (is_ram == REGION_INTERSECTS) return __va(res->start); page_map = devres_alloc(devm_memremap_pages_release, sizeof(*page_map), GFP_KERNEL); if (!page_map) return ERR_PTR(-ENOMEM); memcpy(&page_map->res, res, sizeof(*res)); nid = dev_to_node(dev); if (nid < 0) nid = 0; error = arch_add_memory(nid, res->start, resource_size(res), true); if (error) { devres_free(page_map); return ERR_PTR(error); } devres_add(dev, page_map); return __va(res->start); }
/** * devm_gpiod_get_index - Resource-managed gpiod_get_index() * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @idx: index of the GPIO to obtain in the consumer * @flags: optional GPIO initialization flags * * Managed gpiod_get_index(). GPIO descriptors returned from this function are * automatically disposed on driver detach. See gpiod_get_index() for detailed * information about behavior and return values. */ struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev, const char *con_id, unsigned int idx, enum gpiod_flags flags) { struct gpio_desc **dr; struct gpio_desc *desc; dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), GFP_KERNEL); if (!dr) return ERR_PTR(-ENOMEM); desc = gpiod_get_index(dev, con_id, idx, flags); if (IS_ERR(desc)) { devres_free(dr); return desc; } *dr = desc; devres_add(dev, dr); return desc; }
/** * snd_hdac_acomp_init - Initialize audio component * @bus: HDA core bus * @match_master: match function for finding components * @extra_size: Extra bytes to allocate * * This function is supposed to be used only by a HD-audio controller * driver that needs the interaction with graphics driver. * * This function initializes and sets up the audio component to communicate * with graphics driver. * * Unlike snd_hdac_i915_init(), this function doesn't synchronize with the * binding with the DRM component. Each caller needs to sync via master_bind * audio_ops. * * Returns zero for success or a negative error code. */ int snd_hdac_acomp_init(struct hdac_bus *bus, const struct drm_audio_component_audio_ops *aops, int (*match_master)(struct device *, void *), size_t extra_size) { struct component_match *match = NULL; struct device *dev = bus->dev; struct drm_audio_component *acomp; int ret; if (WARN_ON(hdac_get_acomp(dev))) return -EBUSY; acomp = devres_alloc(hdac_acomp_release, sizeof(*acomp) + extra_size, GFP_KERNEL); if (!acomp) return -ENOMEM; acomp->audio_ops = aops; bus->audio_component = acomp; devres_add(dev, acomp); component_match_add(dev, &match, match_master, bus); ret = component_master_add_with_match(dev, &hdac_component_master_ops, match); if (ret < 0) goto out_err; return 0; out_err: bus->audio_component = NULL; devres_destroy(dev, hdac_acomp_release, NULL, NULL); dev_info(dev, "failed to add audio component master (%d)\n", ret); return ret; }