5998|4

13

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

linux驱动入门 [复制链接]

今天写AM3352的GPIO驱动,那个probe函数不知道怎么写,看了linux的GPIO源码,不知道每个操作都有什么作用,求指教啊!static int omap_gpio_probe(struct platform_device *pdev)

{
        struct device *dev = &pdev->dev;
        struct device_node *node = dev->of_node;
        const struct of_device_id *match;
        const struct omap_gpio_platform_data *pdata;
        struct resource *res;
        struct gpio_bank *bank;
        struct irq_chip *irqc;
#ifdef CONFIG_ARCH_OMAP1
        int irq_base;
#endif

        match = of_match_device(of_match_ptr(omap_gpio_match), dev);

        pdata = match ? match->data : dev_get_platdata(dev);
        if (!pdata)
                return -EINVAL;

        bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL);
        if (!bank) {
                dev_err(dev, "Memory alloc failed\n");
                return -ENOMEM;
        }

        irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
        if (!irqc)
                return -ENOMEM;

        irqc->irq_shutdown = gpio_irq_shutdown,
        irqc->irq_ack = gpio_ack_irq,
        irqc->irq_mask = gpio_mask_irq,
        irqc->irq_unmask = gpio_unmask_irq,
        irqc->irq_set_type = gpio_irq_type,
        irqc->irq_set_wake = gpio_wake_enable,
        irqc->name = dev_name(&pdev->dev);

        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (unlikely(!res)) {
                dev_err(dev, "Invalid IRQ resource\n");
                return -ENODEV;
        }

        bank->irq = res->start;
        bank->dev = dev;
        bank->dbck_flag = pdata->dbck_flag;
        bank->stride = pdata->bank_stride;
        bank->width = pdata->bank_width;
        bank->is_mpuio = pdata->is_mpuio;
        bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
        bank->regs = pdata->regs;
#ifdef CONFIG_OF_GPIO
        bank->chip.of_node = of_node_get(node);
#endif
        if (!node) {
                bank->get_context_loss_count =
                        pdata->get_context_loss_count;
        }

#ifdef CONFIG_ARCH_OMAP1
        /*
         * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
         * irq_alloc_descs() and irq_domain_add_legacy() and just use a
         * linear IRQ domain mapping for all OMAP platforms.
         */
        irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
        if (irq_base < 0) {
                dev_err(dev, "Couldn't allocate IRQ numbers\n");
                return -ENODEV;
        }

        bank->domain = irq_domain_add_legacy(node, bank->width, irq_base,
                                             0, &irq_domain_simple_ops, NULL);
#else
        bank->domain = irq_domain_add_linear(node, bank->width,
                                             &irq_domain_simple_ops, NULL);
#endif
        if (!bank->domain) {
                dev_err(dev, "Couldn't register an IRQ domain\n");
                return -ENODEV;
        }

        if (bank->regs->set_dataout && bank->regs->clr_dataout)
                bank->set_dataout = _set_gpio_dataout_reg;
        else
                bank->set_dataout = _set_gpio_dataout_mask;

        spin_lock_init(&bank->lock);

        /* Static mapping, never released */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (unlikely(!res)) {
                dev_err(dev, "Invalid mem resource\n");
                irq_domain_remove(bank->domain);
                return -ENODEV;
        }

        if (!devm_request_mem_region(dev, res->start, resource_size(res),
                                     pdev->name)) {
                dev_err(dev, "Region already claimed\n");
                irq_domain_remove(bank->domain);
                return -EBUSY;
        }

        bank->base = devm_ioremap(dev, res->start, resource_size(res));
        if (!bank->base) {
                dev_err(dev, "Could not ioremap\n");
                irq_domain_remove(bank->domain);
                return -ENOMEM;
        }

        platform_set_drvdata(pdev, bank);

        pm_runtime_enable(bank->dev);
        pm_runtime_irq_safe(bank->dev);
        pm_runtime_get_sync(bank->dev);

        if (bank->is_mpuio)
                mpuio_init(bank);

        omap_gpio_mod_init(bank);
        omap_gpio_chip_init(bank, irqc);
        omap_gpio_show_rev(bank);

        pm_runtime_put(bank->dev);

        list_add_tail(&bank->node, &omap_gpio_list);

        return 0;
}


最新回复

我也在学习AM3352的驱动,也要上linux  详情 回复 发表于 2017-3-9 08:18
点赞 关注

回复
举报

1234

帖子

4

TA的资源

纯净的硅(高级)

沙发
 
probe函数 是当你的设备与驱动匹配上了之后就会执行的一个函数

当你的设备与驱动匹配上,驱动就需要获取设备上的资源,去做别的事情

比如你的GPIO口,有引脚号,中断......  

如果还不理解 我就只有丢给你几个链接了

http://www.wowotech.net/sort/device_model

http://www.cnblogs.com/helloworldtoyou/p/5448456.html

没个一两天是消化不了的 祝你好运
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
ywlzh 发表于 2017-2-21 14:50
probe函数 是当你的设备与驱动匹配上了之后就会执行的一个函数

当你的设备与驱动匹配上,驱动就需要获 ...

非常感谢,我去消化一下这俩个链接
 
 
 

回复

1368

帖子

6

TA的资源

版主

4
 
我也在学习AM3352的驱动,也要上linux
 
个人签名专注智能产品的研究与开发,专注于电子电路的生产与制造……QQ:2912615383,电子爱好者群: void
 
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

5
 
懒猫爱飞 发表于 2017-3-9 08:18
我也在学习AM3352的驱动,也要上linux

相互学习啦
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表