简体   繁体   English

Linux驱动程序insmod中的PWM

[英]PWM in Linux driver insmod

I am trying to insmod a pwm triple timer counter(TTC) driver for Zynq PS. 我正在尝试为Zynq PS安装pwm三重计时器计数器(TTC)驱动程序。 The dmesg log is: dmesg日志为:

TTC: Inside probe function
pwm-cadence f8001000.timer: PWM 0 has clock source 0 at 108333336 Hz
pwm-cadence f8001000.timer: PWM 1 has clock source 0 at 108333336 Hz
pwm-cadence f8001000.timer: PWM 2 has clock source 0 at 108333336 Hz
pwm-cadence f8001000.timer: cannot add pwm chip (error -22)

Does the EINVAL (error -22) function occur when certain fields in struct cpwm->chip are uninitialised? 当结构cpwm-> chip中的某些字段未初始化时,是否会发生EINVAL(错误-22)功能? I am a newbie in this field. 我是这个领域的新手。 So any tips would be appreciated. 因此,任何提示将不胜感激。

static int cadence_pwm_probe(struct platform_device *pdev)
{
    struct cadence_pwm_chip *cpwm;
    struct resource *r_mem;
    int ret;
    struct device_node *node = pdev->dev.of_node;
    const __be32 *value;
    int rlen;
    char propname[24];
    int i;
    struct cadence_pwm_pwm *pwm;
    printk(KERN_DEBUG "TTC: Inside probe function\n");
    cpwm = devm_kzalloc(&pdev->dev, sizeof(*cpwm), GFP_KERNEL);
    if (!cpwm)
        return -ENOMEM;

    r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    cpwm->base = devm_ioremap_resource(&pdev->dev, r_mem);
    if (IS_ERR(cpwm->base))
       return PTR_ERR(cpwm->base);

    for (i = 0; i < CPWM_NUM_PWM; i ++) {
       pwm = cpwm->pwms + i;

    snprintf(propname, sizeof(propname), "xlnx,ttc-clk%d-freq-hz", i);

    value = of_get_property(node, propname, &rlen);
    if (value)
       pwm->clk_hz = be32_to_cpup(value);
    else {
       dev_err(&pdev->dev, "missing %s property1", propname);
       return -ENODEV;
    }

    snprintf(propname, sizeof(propname), "xlnx,ttc-clk%d-clksrc", i);

    value = of_get_property(node, propname, &rlen);
    if (value)
       pwm->source = be32_to_cpup(value);
    else {
       dev_err(&pdev->dev, "missing %s property2", propname);
       return -ENODEV;
    }

    dev_info(&pdev->dev, "PWM %d has clock source %d at %d Hz", i, pwm->source, pwm->clk_hz);

}

cpwm->chip.dev = &pdev->dev;
cpwm->chip.ops = &cadence_pwm_ops;
cpwm->chip.npwm = CPWM_NUM_PWM;
cpwm->chip.base = -1;

ret = pwmchip_add(&cpwm->chip);
if (ret < 0) {
    dev_err(&pdev->dev, "cannot add pwm chip (error %d)", ret);
    return ret;
}

Well, the code looks decent. 好吧,代码看起来不错。 This means that adding PWM chip must not fail - all fields required are set and they are fine. 这意味着添加PWM芯片一定不会失败-设置了所有必填字段,并且它们很好。

However, EINVAL could still be returned as per the only remaining reason, namely, because support for PWM ( CONFIG_PWM ) has been disabled in the kernel build config. 但是,仍然可以根据剩下的唯一原因返回EINVAL ,即,因为内核构建配置中已禁用了对PWM( CONFIG_PWM )的支持。 This follows from include/linux/pwm.h file where conditional compilation is used. 这来自使用条件编译的include/linux/pwm.h文件。 So, if CONFIG_PWM option has been enabled, then a proper symbol exists. 因此,如果已启用CONFIG_PWM选项,则存在正确的符号。 And, when you build your driver, this function prototype will be used from the header. 并且,当您构建驱动程序时,将从头使用函数原型。 But if the kernel has been built without PWM support, then inline function will be used during driver compilation, which is a simple stub to return EINVAL in any case. 但是,如果内核是在没有PWM支持的情况下构建的,则在驱动程序编译期间将使用内联函数 ,这是在任何情况下都返回EINVAL的简单存根。

All in all, you need to check your build configuration properly. 总而言之,您需要正确检查构建配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM