《设备树 — device node到platform device的转换(四)》

1.哪些device node可以转换成platform device

  首先,要说明的是设备树最初是为了解决大量重复的platform_device在mach-xx目录下,但在实现的过程中,设备树体现的是一个电路板的信息,添加了bootargs,memory,clock,interrupt等非platform_device的节点,这样就不能对所有的device_node转换成platform_device。(memory,interrupt等虽然是硬件,但是不是platform_device)

  Platform device包括:基于端口的设备(已不推荐使用,保留下来只为兼容旧设备,legacy);连接物理总线的桥设备;集成在SOC平台上面的控制器;连接在其它bus上的设备(很少见)。等等。 

  这些设备有一个基本的特征:可以通过CPU bus直接寻址(例如在嵌入式系统常见的“寄存器”)。因此,由于这个共性,内核在设备模型的基础上(device和device_driver),对这些设备进行了更进一步的封装,抽象出paltform bus、platform device和platform driver,以便驱动开发人员可以方便的开发这类设备的驱动。

/{
	compatible = "nvidia,harmony", "nvidia,tegra20";
	#address-cells = <1>;
	#size-cells = <1>;
	interrupt-parent = <&intc>;
 
	chosen { };
	aliases { };
 
	memory {
		device_type = "memory";
		reg = <0x00000000 0x40000000>;
	};
 
	soc {
		compatible = "nvidia,tegra20-soc", "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
 
		intc: interrupt-controller@50041000 {
			compatible = "nvidia,tegra20-gic";
			interrupt-controller;
			#interrupt-cells = <1>;
			reg = <0x50041000 0x1000>, < 0x50040100 0x0100 >;
		};
 
		serial@70006300 {
			compatible = "nvidia,tegra20-uart";
			reg = <0x70006300 0x100>;
			interrupts = <122>;
		};
 
		i2s1: i2s@70002800 {
			compatible = "nvidia,tegra20-i2s";
			reg = <0x70002800 0x100>;
			interrupts = <77>;
			codec = <&wm8903>;
		};
 
		i2c@7000c000 {
			compatible = "nvidia,tegra20-i2c";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0x7000c000 0x100>;
			interrupts = <70>;
 
			wm8903: codec@1a {
				compatible = "wlf,wm8903";
				reg = <0x1a>;
				interrupts = <347>;
			};
		};
	};
 
	sound {
		compatible = "nvidia,harmony-sound";
		i2s-controller = <&i2s1>;
		i2s-codec = <&wm8903>;
	};
};

  基本的我们看到,根节点肯定不是一个设备。

  aliases,aliases ,memory 也都不是一个platform_device。

  以上面的i2c控制器的节点为例,一般来说i2c控制器下的子节点都是外设,但例子中的i2c节点不是根节点子节点。而是跟节点的子子节点。这样就不复合根节点下的有compatible 属性的节点,一般是子节点的特点了吗?

  这里要说的是,对于这种情况,设备树做了特殊处理。

  即一般在一个节点的compatible 属性中函数一下的几个bus标识的话,它的子节点都会转换成平台设备platform_device。

const struct of_device_id of_default_bus_match_table[] = {
	{ .compatible = "simple-bus", },
	{ .compatible = "simple-mfd", },
	{ .compatible = "isa", },
#ifdef CONFIG_ARM_AMBA
	{ .compatible = "arm,amba-bus", },
#endif /* CONFIG_ARM_AMBA */
	{} /* Empty terminated list */

  既然i2c控制器被注册为了一个子节点,那么挂在i2c下面的设备呢?

  通用行为是由父设备驱动程序在驱动程序.probe()时注册子设备。因此,i2c总线设备驱动程序将为每个子节点注册i2c_client,SPI总线驱动程序将注册其spi_device子节点,对于其他bus_types也是如此。

总结: 

  • 除根节点以外,要能能被转换为platform_device,节点必须有compatible 属性。
  • 根节点下含有compatible 属性的子节点,一般被转换成platform_device 。
  • 函有compatible 属性的节点属性中函有基本的bus,其子节点中若也函有compatible 属性也会被转换成platform_device 。
原文地址:https://www.cnblogs.com/zhuangquan/p/12877093.html