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.
热卖云产品新年特惠,2核2G轻量应用服务器9元/月起,更多上云必备产品助力您轻松上云
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
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
. */ 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
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(
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
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将获取到的寄存器地址转化为虚拟地址。
//引用 6 ... 7 }; 驱动代码: 1 struct pinctrl *pinctrl = devm_pinctrl_get pinctrl_select_state(pinctrl, pinctrl_state); //设置pinctrl的状态为'gpio_active 4 devm_pinctrl_put
irq = platform_get_irq(pdev, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource (&pdev->dev, res); phy_addr = (dma_addr_t)res->start; i2c_imx = devm_kzalloc(&pdev->dev, sizeof(*i2c_imx adapter.dev.of_node = pdev->dev.of_node; i2c_imx->base = base; /* Get I2C clock */ i2c_imx->clk = devm_clk_get (&pdev->dev, NULL); ret = clk_prepare_enable(i2c_imx->clk); /* Request IRQ */ ret = devm_request_irq
pinctrl_state的settings链表 2. client节点的pinctrl构造过程 2.1 函数调用 really_probe pinctrl_bind_pins dev->pins = devm_kzalloc (dev, sizeof(*(dev->pins)), GFP_KERNEL); dev->pins->p = devm_pinctrl_get(dev); pinctrl_get
使用devm_extcon_register_notifier来注册监听usb状态变化的回调函数。 otg_work工作队列执行 (4)异步执行dwc3_rockchip_async_probe函数,主要注册通知回调、设置电源等工作 dwc3_rockchip_probe devm_kzalloc (..., &rockchip->device_nb) // 注册设备的extcon通知回调函数 devm_extcon_register_notifier(..., &rockchip 核心初始化和USB模式初始化,后面详细分析 (5)初始化调试文件,具体如下图所示,用户可以在用户空间获取USB控制器信息和控制USB控制器 dwc3_probe mem = devm_kzalloc / 分配事件缓冲区,长度为DWC3_EVENT_BUFFERS_SIZE=4096 dwc3_alloc_one_event_buffer devm_kzalloc
if (desc->hw_blink) led->cdev.blink_set = sso_led_blink_set; sso_led_hw_cfg(priv, led); err = devm_led_classdev_register_ext const char *tmp; u32 prop; int ret; fwnode_for_each_child_node(fw_ssoled, fwnode_child) { led = devm_kzalloc platform_device *pdev) { struct device *dev = &pdev->dev; struct sso_led_priv *priv; int ret; priv = devm_kzalloc gate clock */ priv->clocks[0].id = "sso"; /* fpid clock */ priv->clocks[1].id = "fpid"; ret = devm_clk_bulk_get \n"); return ret; } ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv); if
unsigned int clk_src_in_hz; struct resource *res; const struct of_device_id *of_id; //申请内存 i2c = devm_kzalloc res = platform_get_resource(pdev, IORESOURCE_MEM, 0); //进行内存映射,得到 Linux 内核使用的虚拟地址 i2c->base = devm_ioremap_resource = platform_get_irq(pdev, 0); init_waitqueue_head(&i2c->wait); //请求中断,中断服务函数为 mt_i2c_irq ret = devm_request_irq 控制器支持是否支持标准 I2C 协议 r = i2c_check_functionality(client->adapter,I2C_FUNC_I2C); /* 板级信息分配内存 */ ts_bdata = devm_kzalloc (&client->dev,sizeof(struct goodix_ts_board_data), GFP_KERNEL); ts_device = devm_kzalloc(&client->dev
使用pinctrl_desc注册得到pinctrl_dev 调用devm_pinctrl_register或pinctrl_register,就可以根据pinctrl_desc构造出pinctrl_dev ,并且把pinctrl_dev放入链表: devm_pinctrl_register pinctrl_register struct pinctrl_dev *pctldev; pctldev
扫码关注腾讯云开发者
领取腾讯云代金券