在devicetree节点中通过加status来方便的使能或者disable driver

本文介绍如何在Devicetree中通过status属性控制驱动的启用或禁用状态。当status设置为'okay'或'ok'时,驱动可用;设置为其他值则禁用驱动。通过of_device_is_available函数可在驱动probe阶段检查此状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在devicetree的节点下面可以方便的通过status这个变量来使能或者disable driver的probe
例如如果要使能driver的话,可以将status设为okay反之就是disable
dts/mediatek/mt8173-evb.dts:405:    status = "okay";
dts/mediatek/mt8173.dtsi:306:            status = "disabled";
这样在driver的probe函数中可以通过of_device_is_available 来判断probe函数是否要继续下去
    if (!of_device_is_available(mii_np)) {
        ret = -ENODEV;
        goto err_put_node;
    }

static bool __of_device_is_available(const struct device_node *device)
{
    const char *status;
    int statlen;

    if (!device)
        return false;

    status = __of_get_property(device, "status", &statlen);
    if (status == NULL)
        return true;

    if (statlen > 0) {
        if (!strcmp(status, "okay") || !strcmp(status, "ok"))
            return true;
    }

    return false;
}

/**
 *  of_device_is_available - check if a device is available for use
 *
 *  @device: Node to check for availability
 *
 *  Returns true if the status property is absent or set to "okay" or "ok",
 *  false otherwise
 */
bool of_device_is_available(const struct device_node *device)
{
    unsigned long flags;
    bool res;

    raw_spin_lock_irqsave(&devtree_lock, flags);
    res = __of_device_is_available(device);
    raw_spin_unlock_irqrestore(&devtree_lock, flags);
    return res;

}
可见设置ok或者okay 都行,反之只要不是这两个字串,of_device_is_available就返回false,这样probe函数就停止了
因此可以在devicetree节点中通过加status来方便的使能或者disable driver
<think>好的,用户的问题是关于在已知pwm0端口的情况下,如何使用pwm_request函数使能PWM端口的内核驱动开发。需要结合之前的对话和提供的引用内容来回答。 首先回顾用户之前的提问,他们想知道是否可以直接在驱动中使用echo命令使能PWM,而我之前的回答已经解释了用户空间和内核空间的区别,以及如何在内核中使用API函数。现在用户进一步询问具体如何使用pwm_request函数来使能pwm0端口,所以需要详细说明内核驱动的开发步骤。 根据用户提供的引用内容,特别是引用[1]和[3],里面提到了pwm_request、pwm_config、pwm_enable等函数的使用,以及设备树节点的配置。需要整合这些信息,给出具体的代码示例和步骤。 用户可能的问题点在于如何正确申请PWM资源,配置参数,并使能端口。需要确保步骤清晰,包括设备树配置、函数调用顺序、错误处理等。同时,要注意内核版本差异,比如pwm_request可能已经被pwm_get替代,需要指出这一点,避免用户混淆。 另外,用户可能在实际操作中遇到问题,比如无法找到PWM设备或配置失败,因此需要强调错误处理的重要性,并说明常见问题如设备树配置是否正确,时钟是否启用等。 还要考虑用户的应用场景,可能是在嵌入式设备如IMX6或RK3399上开发驱动,所以需要提到不同平台的具体实现位置,如引用[1]中的IMX6和引用[4]中的RK3399设备树配置示例。 最后,确保回答结构清晰,分步骤说明,并包含示例代码和注意事项,帮助用户正确实现功能。同时,生成的相关问题要针对可能遇到的后续疑问,如设备树配置、调试方法、替代函数等。</think>### 基于Linux内核的PWM驱动开发指南(以pwm0端口为例) --- #### 一、驱动开发核心步骤 1. **设备树配置**(必需前置条件) 需在设备树中明确定义PWM控制器节点,以RK3399平台为例[^4]: ```dts pwm0: pwm@ff420000 { compatible = "rockchip,rk3399-pwm"; reg = <0x0 0xff420000 0x0 0x10>; #pwm-cells = <3>; clocks = <&pmucru PCLK_RKPWM_PMU>; clock-names = "pwm"; status = "okay"; }; ``` 关键参数说明: - `#pwm-cells = 3` 表示每个PWM通道需要3个参数配置 - 时钟配置确保PWM控制器正常工作[^3] 2. **PWM资源申请与初始化** ```c #include <linux/pwm.h> struct pwm_device *pwm0_dev; // 申请pwm0资源(内核版本<4.4) pwm0_dev = pwm_request(0, "my-pwm-driver"); if (IS_ERR(pwm0_dev)) { pr_err("Failed to request PWM0: %ld\n", PTR_ERR(pwm0_dev)); return PTR_ERR(pwm0_dev); } // 新版本建议使用pwm_get()替代 pwm0_dev = pwm_get(&pdev->dev, NULL); // 通过设备树自动匹配 ``` 3. **参数配置与使能** ```c // 配置PWM参数(周期10ms,占空比30%) int ret = pwm_config(pwm0_dev, 3000000, // duty_ns(3ms) 10000000); // period_ns(10ms) if (ret) { pr_err("PWM config failed: %d\n", ret); pwm_free(pwm0_dev); return ret; } // 使能PWM输出(对应寄存器使能操作) pwm_enable(pwm0_dev); ``` --- #### 二、完整驱动代码框架示例 ```c #include <linux/module.h> #include <linux/pwm.h> static struct pwm_device *pwm0; static int __init pwm_drv_init(void) { // 申请PWM资源 pwm0 = pwm_request(0, "pwm0-driver"); if (IS_ERR(pwm0)) { printk(KERN_ERR "Cannot request PWM0\n"); return PTR_ERR(pwm0); } // 配置参数(周期20ms,占空比50%) if (pwm_config(pwm0, 10000000, 20000000)) { printk(KERN_ERR "PWM config failed\n"); pwm_free(pwm0); return -EINVAL; } // 使能输出 pwm_enable(pwm0); return 0; } static void __exit pwm_drv_exit(void) { pwm_disable(pwm0); pwm_free(pwm0); } module_init(pwm_drv_init); module_exit(pwm_drv_exit); MODULE_LICENSE("GPL"); ``` --- #### 三、关键问题排查点 1. **资源申请失败** - 检查`/sys/class/pwm`是否存在pwmchip0接口 - 确认设备树`status = "okay"`已启用控制器[^4] - 验证时钟配置是否生效:`dmesg | grep pwm` 2. **参数配置异常** - 确保`duty_ns ≤ period_ns` - 检查PWM控制器支持的频率范围(如i.MX6最大支持6.5MHz[^1]) 3. **输出无信号** ```bash # 使用示波器测量物理引脚 # 或通过sysfs调试 echo 0 > /sys/class/pwm/pwmchip0/export echo 1000000 > pwm0/period echo 500000 > pwm0/duty_cycle echo 1 > pwm0/enable ``` --- #### 四、平台差异说明 | 平台 | 实现文件 | 设备树绑定要求 | |-------|-------------------------|---------------------| | i.MX6 | arch/arm/plat-mxc/pwm.c | fsl,pwm 属性 | | RK3399| drivers/pwm/pwm-rockchip.c | rockchip,pwm 属性 | | 通用 | drivers/pwm/core.c | 标准pwm-cells定义 | [^1]: IMX6平台PWM实现位于arch/arm/plat-mxc/pwm.c [^3]: 新版内核推荐使用pwm_get()替代pwm_request() [^4]: 设备树配置是PWM功能正常工作的必要前提
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值