在前一节中,主要说明常用的devm驱动接口,这一节在基础上扩展提高,提供更复杂的devm接口。
//函数原型
struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv);
//参数
parent: 管理iio设备的父类设备结构
sizeof_priv: 私有数据长度,存储私有数据
返回: 申请的iio设备管理结构
//例程
struct hx711_data *chip;
struct iio_dev *indio_dev;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct hx711_data));
if (!indio_dev){
return -ENOMEM;
}
//函数原型
#define devm_iio_device_register(dev, indio_dev) \
__devm_iio_device_register((dev), (indio_dev), THIS_MODULE)
//参数
dev:管理iio设备的父类设备结构
indio_dev: 配置iio设备属性的结构体
返回: 0表示注册成功,其它则失败
//例程
indio_dev->dev.parent = &pdev->dev;
indio_dev->info = &hx711_info;
indio_dev->name = DEVICE_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = hx711_channels;
indio_dev->num_channels = ARRAY_SIZE(hx711_channels);
ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0) {
dev_err(&pdev->dev, "iio_device_register failed\n");
return -EIO;
}
//函数原型
static inline void *iio_priv(const struct iio_dev *indio_dev)
{
return indio_dev->priv;
}
//参数:
indio_dev: iio设备管理结构体
返回: iio设备的私有数据
//例程
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct hx711_data));
if (!indio_dev) {
return -ENOMEM;
}
chip = iio_priv(indio_dev);
//函数原型
struct input_dev *devm_input_allocate_device(struct device *dev)
//参数
dev:管理input设备的父类设备结构
返回: 申请的input设备结构体
//例程
chip->input_dev = devm_input_allocate_device(&pdev->dev);
//函数原型
void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
unsigned int index)
//参数
dev:reg属性对应的设备节点
index:资源的编号, 如果对于一个资源包含多个,按照编号访问
//例程
info->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->regs))
return PTR_ERR(info->regs);
hc_cfg = readl(info->regs + VF610_REG_ADC_HC0);
//函数原型
void __iomem *devm_platform_ioremap_resource_byname(struct platform_device *pdev,
const char *name)
//参数
dev:reg属性属于的设备节点
name:reg属性对应的名称
//例程
priv->reg_dram = devm_platform_ioremap_resource_byname(pdev, "dram");
if (IS_ERR(priv->reg_dram))
return PTR_ERR(priv->reg_dram);
pwrctl = readl_relaxed(priv->reg_dram + DRAM_PWRCTL) &
~DRAM_PWRCTL_SELFREF_EN;
//函数原型
int devm_pwmchip_add(struct device *dev, struct pwm_chip *chip)
//参数
dev: 需要注册的pwm的设备节点
chip: pwm节点设备信息
返回: 0表示成功,其它表示失败
//例程
devm_pwmchip_add(&pdev->dev, &info->chip)
//函数原型
int regulator_enable(struct regulator *regulator)
//参数
regulator:已经获取的稳压器管理结构
返回:0表示请求使能成功,1表示失败
//例程
int err;
err = regulator_enable(regulator);
//函数原型
int regulator_disable(struct regulator *regulator)
//参数
regulator:已经获取的稳压器管理结构
返回:0表示请求关闭成功,1表示失败
//例程
int err;
err = regulator_disable(regulator);
//函数原型
int regulator_get_voltage(struct regulator *regulator)
//参数
regulator:已经获取的稳压器管理结构
返回:函数返回一个整数,表示获取到的电压值(单位为微伏,即uV)。如果函数执行失败,返回负值。
//例程
int voltage;
voltage = regulator_get_voltage(regulator);
dev_info(&pdev->dev, "regulator voltage: %d mV\n", voltage/1000);
//函数原型
struct regulator *devm_regulator_get_optional(struct device *dev,
const char *id)
//参数
dev: 设备结构体指针,表示要获取电压的设备。
id: 稳压器的ID字符串,表示要获取的稳压器的名称。
返回:函数返回一个指向regulator结构体的指针,表示获取到的稳压器。如果函数执行失败,返回NULL。
//例程
struct regulator *reg_xceiver;
reg_xceiver = devm_regulator_get_optional(&pdev->dev, "xceiver");
关于hwmon可以看Linux内核文档说明:Documentation/hwmon/hwmon-kernel-api.rst
//函数原型
int devm_watchdog_register_device(struct device *dev,
struct watchdog_device *wdd)
//参数
dev: 指向看门狗对应的设备树节点的device资源结构体
wdd: 指向看门狗配置的watchdog_device结构体
返回:0表示注册成功,其它则注册失败,返回对应错误码
//例程
wdog = &wdev->wdog;
wdog->info = &imx2_wdt_info;
wdog->ops = &imx2_wdt_ops;
wdog->min_timeout = 1;
wdog->timeout = IMX2_WDT_DEFAULT_TIME;
wdog->max_hw_heartbeat_ms = IMX2_WDT_MAX_TIME * 1000;
wdog->parent = dev;
return devm_watchdog_register_device(dev, wdog);
//函数原型
static inline void watchdog_set_drvdata(struct watchdog_device *wdd, void *data)
//参数
wdd: 指向看门狗配置的watchdog_device结构体
data: 设置的看门狗私有数据的指针
//例程
watchdog_set_drvdata(wdog, wdev);
//函数原型
static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
{
return wdd->driver_data;
}
//参数
wdd: 指向看门狗配置的watchdog_device结构体
返回: 看门狗私有数据的指针
//例程
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
//函数原型
static inline void watchdog_set_nowayout(struct watchdog_device *wdd, int nowayout)
//参数
wdd: 指向看门狗配置的watchdog_device结构体
nowayout: 设置看门狗的nowayout属性,0表示不设置,1表示设置
//例程
watchdog_set_nowayout(wdog, 1);
//函数原型
static inline void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority)
//参数
wdd: 指向看门狗配置的watchdog_device结构体
priority: 一个整数,表示要设置的重启优先级。优先级的值通常是一个非负整数,数值越大表示优先级越高。
//例程
watchdog_set_restart_priority(wdog, 1);
//函数原型
int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout,
struct device *dev);
//参数
wdd: 指向看门狗配置的watchdog_device结构体
timeout: 一个整数,表示要设置的超时时间。单位为秒。
dev: 指向 device 结构体的指针,表示与看门狗设备相关联的设备
//例程
int ret = watchdog_init_timeout(my_watchdog, 30, NULL);
//函数原型
static inline void watchdog_stop_ping_on_suspend(struct watchdog_device *wdd)
//参数
wdd: 指向看门狗配置的watchdog_device结构体
//例程
watchdog_stop_ping_on_suspend(wdog);
直接开始下一节说明: 驱动并发接口