我们还是先看看platform device是如何define的

platform device 是如何定义的

  • example1

在板级驱动中定义, 通过platform_add_devices()函数将这个platform device注册进系统.

arch\arm\plat-samsung\devs.c

struct platform_device s3c_device_hsmmc0 = {
.name = "s3c-sdhci",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
.resource = s3c_hsmmc_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &s3c_hsmmc0_def_platdata,
},
};

arch\arm\mach-s3c24xx\mach-smdk2416.c

static struct platform_device *smdk2416_devices[] __initdata = {
&s3c_device_fb,
&s3c_device_wdt,
&s3c_device_ohci,
&s3c_device_i2c0,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_usb_hsudc,
&s3c2443_device_dma,
};

并最终通过platform_add_devices()函数将这个platform device注册进系统。

arch\arm\mach-s3c24xx\mach-smdk2416.c

static void __init smdk2416_machine_init(void)
{
//... platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices)); //...
}
  • example2

在在板级驱动中定义,通过platform_device_register()函数将这个platform device注册进系统.

arch\arm\mach-imx\mach-imx6sx.c

platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);

arch\arm\mach-imx\mach-imx6q.c

static struct platform_device imx6q_cpufreq_pdev = {
.name = "imx6q-cpufreq",
}; static void __init imx6q_init_late(void)
{
//...
platform_device_register(&imx6q_cpufreq_pdev);
// ...
}
  • example3

通过设备树定义.

在早期的ARM Linux Kernel中,板级细节使用代码形式,存放在arch/arm/目录。名字通常为:plat-xxxx或者mach-xxxx,内容多为特定板上细节信息,如platform, i2c_board_info, spi_board_info和各类资源数据。

但这类目录对Linux Kernel来说,意义非常有限,因为板级代码只对相应开发板有用。使用这种方法显然不是一个好办法。与此同时PowerPC等其它架构已经在使用一种新的方法:Flattened Device Tree(FDT)。Device Tree是一种描述硬件的数据结构。它包含板级硬件细节信息,这样,通过Device Tree,就可以把硬件信息传递给Kernel,而不需要再硬编码了。

arch\arm\boot\dts\bcm2710-rpi-3-b.dts

&leds {
act_led: act {
label = "led0";
linux,default-trigger = "mmc0";
gpios = <&virtgpio 0 0>;
}; pwr_led: pwr {
label = "led1";
linux,default-trigger = "input";
gpios = <&expgpio 7 0>;
};
};

至于设备树中定义的platform_device是如何被kernel解析并定义的, 参考

Device Tree(三):代码分析

machine初始化的代码可以沿着start_kernel->rest_init->kernel_init->kernel_init_freeable->do_basic_setup->do_initcalls路径寻找。在do_initcalls函数中,kernel会依次执行各个initcall函数,在这个过程中,会调用customize_machine,

在这个函数中,一般会调用machine描述符中的init_machine callback函数来把各种Device Tree中定义的platform device设备节点加入到系统(即platform bus的所有的子节点,对于device tree中其他的设备节点,需要在各自bus controller初始化的时候自行处理)。如果machine描述符中没有定义init_machine函数,那么直接调用of_platform_populate把所有的platform device加入到kernel中。

不过这里好像和arch\arm\mach-bcm\board_bcm2835.c对应不上

但是内核中处理解析dts的机制是一样的

of_platform_default_populate_init

of_platform_device_create

of_platform_device_create_pdata

of_device_add

static int __init of_platform_default_populate_init(void)
{
struct device_node *node;
if (!of_have_populated_dt())
return -ENODEV;
/*
* Handle certain compatibles explicitly, since we don't want to create
* platform_devices for every node in /reserved-memory with a
* "compatible",
*/
for_each_matching_node(node, reserved_mem_matches)
of_platform_device_create(node, NULL, NULL);
node = of_find_node_by_path("/firmware");
if (node) {
of_platform_populate(node, NULL, NULL, NULL);
of_node_put(node);
}
/* Populate everything else. */
of_platform_default_populate(NULL, NULL, NULL);
return 0;
}

leds-gpio driver的更多相关文章

  1. 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之二

    /** ****************************************************************************** * @author    暴走的小 ...

  2. 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之一

    /** ****************************************************************************** * @author    暴走的小 ...

  3. 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之三

    /** ****************************************************************************** * @author    暴走的小 ...

  4. Davinci DM6446开发攻略——LINUX GPIO驱动源码移植

    一.             DM6446 GPIO的介绍      说到LINUX 驱动移植,没有移植过的朋友,或刚刚进入LINUX领域的朋友,最好去看看<LINUX 设备驱动程序>第三 ...

  5. am335x system upgrade kernel gpio(九)

    1      Hardware Overview gpio interface,pin map: AM335X_I2C0_W_C----------------------MCASP0_AXR1 /* ...

  6. ok6410 android driver(9)

    In this essay, I will write the JNI to test our leds device. If you don't know how to create a jni p ...

  7. linux内核中的GPIO系统之(2):pin control subsystem

    一.前言 在linux2.6内核上工作的嵌入式软件工程师在pin control上都会遇到这样的状况: (1)启动一个新的项目后,需要根据硬件平台的设定进行pin control相关的编码.例如:在b ...

  8. linux内核中的GPIO系统之(1):软件框架

    一.前言 作为一个工作多年的系统工程师,免不了做两件事情:培训新员工和给新员工分配任务.对于那些刚刚从学校出来的学生,一般在开始的时候总是分配一些非常简单的任务,例如GPIO driver.LED d ...

  9. 转字符驱动实例gpio

    概述: 字符设备驱动程序: 是按照字符设备要求完成的由操作系统调用的代码. 重点理解以下内容:  1. 驱动是写给操作系统的代码,它不是直接给用户层程序调用的,而是给系统调用的  2. 所以驱动要向系 ...

  10. 转:全志A20 GPIO 总结文档

    链接: http://blog.csdn.net/chwenj/article/details/42190745 /* * author:          chwenj@gmail.com. * A ...

随机推荐

  1. E20180218-hm-xa

    更新: 2019/02/19 原来忘记分类,把此博文归入单词类 vocabulary  n. (某一语言的) 词汇; (尤指外语教科书中附有释义的) 词汇表; grammar  n. 语法; 语法书; ...

  2. bzoj 1927 [Sdoi2010]星际竞速【最小费用最大流】

    果然还是不会建图- 设\( i \)到\( j \)有通路,代价为\( w[i][j] \),瞬移到i代价为\( a[i] \),瞬移到i代价为\( a[j] \),逗号前是流量. 因为每个点只能经过 ...

  3. Word Cloud (词云) - Python

    >>What's Word Cloud 词云 (Word Cloud)是对文本中出现频率较高的词语给予视觉化展示的图形, 是一种常见的文本挖掘的方法.目前已有多种数据分析工具支持这种图形, ...

  4. 三分钟掌握docker基本指令

    一下内容是我用markdown编辑的,所以排版不是太ok~ # Docker ## 1.核心概念 docker主机(Host):安装了docker程序的机器.docker直接安装再操作系统上. doc ...

  5. Selenium定位多个iframe嵌套中的元素

    在公司boss系统中,经常会遇到多层iframe嵌套的情况,导致无法定位最里面那层iframe的元素. 其实很简单,只要一层层定位iframe,定位到你想要的那层iframe即可: 如果操作完需要返回 ...

  6. C#中的预编译指令介绍[转]

    原文链接 1.#define和#undef 用法: #define DEBUG #undef DEBUG #define告诉编译器,我定义了一个DEBUG的一个符号,他类似一个变量,但是它没有具体的值 ...

  7. java中什么包不需要导入

    java中Math.random()*10;在math包中不需要导入: 即import java.lang.Math; 即lang下的所有包都不需要导入.

  8. ambari集群里如何正确删除历史修改记录(图文详解)

    不多说,直接上干货! 答:这些你想删除的话得得去数据库里删除,最好别删除 .  现在默认就是使用好的配置               欢迎大家,加入我的微信公众号:大数据躺过的坑        人工智 ...

  9. form表单ajaxSubmit提交并验证

    html: <form class="register-form" action="{:U('')}" method="post"&g ...

  10. 解决webstromm标签高亮问题

      2017/2016版