社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 1534|回复: 4

[求助] linux驱动入门

[复制链接]

17

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2017-2-21 11:18:27 | 显示全部楼层 |阅读模式
今天写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;
}




回复

使用道具 举报

1227

TA的帖子

4

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2017-2-21 14:50:19 | 显示全部楼层
probe函数 是当你的设备与驱动匹配上了之后就会执行的一个函数

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

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

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

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

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

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


回复

使用道具 举报

17

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

 楼主| 发表于 2017-2-21 18:01:06 | 显示全部楼层
ywlzh 发表于 2017-2-21 14:50
probe函数 是当你的设备与驱动匹配上了之后就会执行的一个函数

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

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


回复

使用道具 举报

232

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-3-9 08:18:07 | 显示全部楼层
我也在学习AM3352的驱动,也要上linux
专注智能产品的研究与开发,专注于电子电路的生产与制造……QQ:2912615383,电子爱好者群: 422240210


回复

使用道具 举报

17

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

 楼主| 发表于 2017-3-13 09:50:38 | 显示全部楼层
懒猫爱飞 发表于 2017-3-9 08:18
我也在学习AM3352的驱动,也要上linux

相互学习啦


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-11-24 15:54 , Processed in 0.338890 second(s), 15 queries , Redis On.

快速回复 返回顶部 返回列表