devres使用 不同的内核模块提供了对应的devm_xxx接口,如下(不仅仅这些): MEM devm_kmalloc() devm_kzalloc() devm_kcalloc(...) devm_kmalloc_array() devm_kstrdup() devm_kfree() IIO devm_iio_device_alloc() devm_iio_device_free...() devm_iio_trigger_alloc() devm_iio_trigger_free() devm_iio_device_register() devm_iio_device_unregister...() devm_ioport_unmap() devm_ioremap() devm_ioremap_nocache() devm_iounmap() devm_ioremap_resource...() devm_clk_put() PINCTRL devm_pinctrl_get() devm_pinctrl_put() PWM devm_pwm_get() devm_pwm_put
descriptor-based legacy 说明 获得GPIO gpiod_get gpio_request gpiod_get_index gpiod_get_array gpio_request_array devm_gpiod_get...devm_gpiod_get_index devm_gpiod_get_array 设置方向 gpiod_direction_input gpio_direction_input gpiod_direction_output...gpiod_set_value gpio_set_value 释放GPIO gpio_free gpio_free gpiod_put gpio_free_array gpiod_put_array devm_gpiod_put...devm_gpiod_put_array 1.3 GPIOLIB向下提供的接口 2.
3)提供regulator的注册接口(regulator_register/devm_regulator_register),该接口接受描述该regulator的两个变量的指针:struct regulator_desc...const char *id); 3: struct regulator *__must_check devm_regulator_get...regulator *regulator); 根据是否独占regulator、是否可以多次get,regulator get接口分为三类: 正常的get,非独占、可以重复get,regulator_get/devm_regulator_get...; 独占性质的get,独占、不可重复get,regulator_get_exclusive/devm_regulator_get_exclusive; optional的get,非独占、不可重复get...,regulator_get_optional/devm_regulator_get_optional。
descriptor-based legacy 说明 获得GPIO gpiod_get gpio_request gpiod_get_index gpiod_get_array gpio_request_array devm_gpiod_get...devm_gpiod_get_index devm_gpiod_get_array 设置方向 gpiod_direction_input gpio_direction_input gpiod_direction_output...gpiod_set_value gpio_set_value 释放GPIO gpio_free gpio_free gpiod_put gpio_free_array gpiod_put_array devm_gpiod_put...devm_gpiod_put_array 有前缀“devm_”的含义是“设备资源管理”(Managed Device Resource),这是一种自动释放资源的机制。...如果使用devm的相关函数,在内存申请失败时可以直接返回:设备的销毁函数会自动地释放已经申请了的GPIO资源。 建议使用“devm_”版本的相关函数。
NULL regmap for charge 2721\n", __func__); return -EINVAL; } sprd_2721 = devm_kzalloc...>dev; platform_set_drvdata(pdev, sprd_2721); if (pdata->gpio_chg_cv_state) { ret = devm_gpio_request...gpio_chg_cv_state); irq_set_status_flags(pdata->irq_chg_cv_state, IRQ_NOAUTOEN); ret = devm_request_threaded_irq...%d\n", ret); return ret; } } if (pdata->gpio_vchg_ovi) { ret = devm_gpio_request...sprdchg_cccv_cal_get(); //注册回调函数 sprdbat_register_ext_ops(&sprd_2721_op); charger_desc = devm_kzalloc
4.1.4 devm_pinctrl_put 4.1.5 pinctrl_lookup_state 4.1.6 pinctrl_select_state 4.1.7 devm_pinctrl_get_select...4.1.3 devm_pinctrl_get • 函数原型:struct pinctrl *devm_pinctrl_get(struct device *dev) • 作用:根据设备获取 pin 操作句柄...4.1.4 devm_pinctrl_put • 函数原型:void devm_pinctrl_put(struct pinctrl *p) • 作用:释放 pinctrl 句柄,必须与 devm_pinctrl_get...4.1.7 devm_pinctrl_get_select • 函数原型:struct pinctrl *devm_pinctrl_get_select(struct device *dev, const...4.1.8 devm_pinctrl_get_select_default • 函数原型:struct pinctrl *devm_pinctrl_get_select_default(struct device
mxc_gpio_port *port; struct resource *iores; int irq_base = 0; int err; mxc_gpio_get_hw(pdev); port = devm_kzalloc...port) return -ENOMEM; 2.2 设置gpio_chip 2.3 注册gpio_chip err = devm_gpiochip_add_data(&pdev->dev, &port...->gc, port); if (err) goto out_bgio; err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); if
\n"); fmc = devm_kzalloc(dev, sizeof(*fmc), GFP_KERNEL); if (!...ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); fmc->regbase = devm_ioremap_resource...regbase); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); fmc->iobase = devm_ioremap_resource...(dev, res); if (IS_ERR(fmc->iobase)) return PTR_ERR(fmc->iobase); fmc->clk = devm_clk_get
ret = devm_snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); if...(ret) { pr_err("failed to register the dai\n"); return ret; } 通过devm_snd_soc_register_component注册一个...const struct snd_soc_component_driver s3c24xx_i2s_component = { .name = "s3c24xx-i2s", }; 根据传入参数,进入到devm_snd_soc_register_component...其中devm是一种资源管理的方式,不用考虑资源释放,内核会内部做好资源回收。然后进入snd_soc_register_component函数。...int samsung_asoc_dma_platform_register(struct device *dev) { return devm_snd_dmaengine_pcm_register(
. */ msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus"); // 获取bus时钟 /* Setup main peripheral...bus clock */ msm_host->pclk = devm_clk_get(&pdev->dev, "iface"); // 获取iface时钟到msm_host->...) ret = clk_prepare_enable(msm_host->pclk); /* Setup SDC MMC clock */ msm_host->clk = devm_clk_get...AHB_CLK) core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); msm_host->core_mem = devm_ioremap_resource
2、pinctrl 子系统 API pinctrl 子系统的 API 有很多,对于驱动工程师来说,pinctrl 操作一个 GPIO 只需要三步: 1、devm_pinctrl_get 2、pinctrl_lookup_state...3、pinctrl_select_state 在 Linux 中,加 devm_ 开头的函数,代表这个函数支持资源管理。...后来 Linux 开发出了很多 devm_ 开头的函数,代表这个函数有支持资源管理的版本,不管哪一步出错,只要错误退出,就会自动释放所申请的资源。...1)devm_pinctrl_get:用于获取设备树中自己用 pinctrl 建立的节点的句柄; 2) pinctrl_lookup_state:用于选择其中一个 pinctrl 的状态,同一个 pinctrl...(&pdev->dev); if(IS_ERR(pctrl)){ ret = PTR_ERR(pctrl); printk("devm_pinctrl_get error\n"); return
8192 of_syscon_register+0xa4/0x240 phys=7001000 ioremap 0xffffff8008017000-0xffffff8008019000 8192 devm_ioremap...0xffffff800805a000 266240 atomic_pool_init+0x0/0x20c user 0xffffff800805a000-0xffffff800805c000 8192 devm_ioremap...+0x5c/0xc8 phys=7022000 ioremap 0xffffff800805c000-0xffffff800805e000 8192 devm_ioremap+0x5c/0xc8...+0x5c/0xc8 phys=7020000 ioremap 0xffffff8008c46000-0xffffff8008c48000 8192 devm_ioremap+0x5c/0xc8...+0x5c/0xc8 phys=3006000 ioremap 0xffffff8008c56000-0xffffff8008c58000 8192 devm_ioremap+0x5c/0xc8
pdev) { struct rkxx_remotectl_drvdata *ddata; struct device_node *np = pdev->dev.of_node; ddata = devm_kzalloc...rkxx_remotectl_drvdata),GFP_KERNEL); ddata->state = RMC_PRELOAD; ddata->temp_period = 0; ddata->base = devm_ioremap_resource...\n"); ...... } ddata->maxkeybdnum = num; remotectl_button = devm_kzalloc(&pdev->dev,num*sizeof(struct...remotectl_button) { pr_err("failed to malloc remote button memory\n"); ...... } input = devm_input_allocate_device...cpumask_clear(&cpumask); cpumask_set_cpu(cpu_id, &cpumask); irq_set_affinity(irq, &cpumask); ret = devm_request_irq
struct qpnp_bms_chip *chip; struct device_node *revid_dev_node; int rc, vbatt = 0; chip = devm_kzalloc...batt_data->ibat_acc_lut) { pr_err("battery data load failed\n"); devm_kfree(chip->dev..., batt_data->fcc_temp_lut); devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut); devm_kfree...->fcc_temp_lut); devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut); devm_kfree(chip->...dev, batt_data->rbatt_sf_lut); devm_kfree(chip->dev, batt_data->ibat_acc_lut); devm_kfree
; int i, ret = 0; if (pdata && pdata->num_leds) { // 判断平台数据LED数量 priv = devm_kzalloc...实现思路: 通过dev_get_platdata检索设备的平台数据,如果平台数据中的LED数量大于零,则使用devm_kzalloc为其分配内存空间,并且使用create_gpio_led进行初始化 如果平台数据不存在或...count) return ERR_PTR(-ENODEV); priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL...} if (template->active_low) flags |= GPIOF_ACTIVE_LOW; ret = devm_gpio_request_one...ret = gpiod_direction_output(led_dat->gpiod, state); if (ret < 0) return ret; return devm_of_led_classdev_register
cur_led) return -ENOMEM; led_hwinfo = devm_kzalloc(&pdev->dev, sizeof(unsigned int)*2, GFP_KERNEL...(&pdev->dev, mem_dr->start, resource_size(mem_dr)); cur_led->va_gdir = devm_ioremap(&pdev->dev..., mem_gdir->start, resource_size(mem_gdir)); cur_led->va_iomuxc_mux = devm_ioremap(&pdev->dev...void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size)...devm_ioremap将获取到的寄存器地址转化为虚拟地址。
(dev, res); dsi->irq = platform_get_irq(pdev, 0); dsi->pclk = devm_clk_get(dev, "pclk"); dsi->regmap...= devm_regmap_init_mmio(dev, regs,&dw_mipi_dsi_regmap_config); if (dsi->pdata->soc_type == RK3126)...{ dsi->h2p_clk = devm_clk_get(dev, "h2p"); } } dsi->grf = syscon_regmap_lookup_by_phandle(np,..."rockchip,grf"); dsi->rst = devm_reset_control_get(dev, "apb"); ret = mipi_dphy_attach(dsi); ret...= devm_request_irq(dev, dsi->irq, dw_mipi_dsi_irq_handler,IRQF_SHARED, dev_name(dev), dsi); dsi->dsi_host.ops
、代码框架分析 led-class.c (led 子系统框架的入口) 维护 LED 子系统的所有 LED 设备,为 LED 设备提供注册操作函数: led_classdev_register() devm_led_classdev_register...() 注销操作函数: led_classdev_unregister() devm_led_classdev_unregister(); 电源管理的休眠和恢复操作函数: led_classdev_suspend...链表; leds_list_lock : leds链表锁 led-triggers.c 维护 LED 子系统的所有触发器,为触发器提供注册操作函数: led_trigger_register() devm_led_trigger_register...、leds-xxx.c : 以 leds-gpio.c 为例 在通过设备树或者其它途径匹配到设备信息后,将调用 probe() 函数, 然后再根据设备信息设置 led_classdev, 最后调用 devm_led_classdev_register
struct clk指针,获取的接口如下: 1: struct clk *clk_get(struct device *dev, const char *id); 2: struct clk *devm_clk_get...(struct device *dev, const char *id); 3: void clk_put(struct clk *clk); 4: void devm_clk_put(struct...b)devm_clk_get,和clk_get一样,只是使用了device resource management,可以自动释放。...c)clk_put、devm_clk_put,get的反向操作,一般和对应的get API成对调用。...3: { 4: struct clk *baud_clk; 5: int ret; 6: 7: baud_clk = devm_clk_get
//引用 6 ... 7 }; 驱动代码: 1 struct pinctrl *pinctrl = devm_pinctrl_get...pinctrl_select_state(pinctrl, pinctrl_state); //设置pinctrl的状态为'gpio_active 4 devm_pinctrl_put
领取专属 10元无门槛券
手把手带您无忧上云