Loongarch ACPI 设备例子,以i2c为例,龙芯的i2c控制器与OpenCores I2C控制器兼容,即内核的i2c-ocores.c驱动。
下面是bootloader的.asl文件描述的clok设备和i2c0设备:
Device (CLK1) {
Name (_HID, "PRP0001")
Name (_DDN, "Loongson 7A Bus Clock")
Name (_DSD, Package (0x02) {
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package (0x04) {
Package (0x02) {"compatible", "fixed-clock"},
Package (0x02) {"clock-cells", 0},
Package (0x02) {"clock-frequency", 100000000},
Package (0x02) {"clock-output-names", "boot-clk"}
}
})
}
Device (I2C0)
{
Name (_HID, "PRP0001")
Name (_UID, 0x0)
Name (_CRS, ResourceTemplate ()
{
QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x0000000000000000, // Granularity
0x0000000010090000, // Range Minimum
0x0000000010090007, // Range Maximum
0x0000000000000000, // Translation Offset
0x0000000000000008, // Length
,, , AddressRangeMemory, TypeStatic)
Interrupt (ResourceConsumer, Level, ActiveHigh, Shared, ,, )
{
73,
}
})
Name (_DSD, Package (0x02)
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package (0x03) {
Package (0x02) {"compatible", "opencores,i2c-ocores"},
Package (0x02) {"clock-frequency", 100000},
Package (0x02) {"clocks", Package (0x01) {"\\_SB.CLK1"}}
}
})
}
Name (_HID, “PRP0001”) 用于设备和驱动匹配,与内核驱动中的struct acpi_device_id匹配即进行驱动注册,有点类似于struct of_device_id
"PRP0001"这个值比较特殊,在Linux内核中属于generic_device,在内核启动过程中进行了注册,并不需要在特定的驱动中添加struct acpi_device_id与其进行匹配。
注册过程参考内核源码/drivers/acpi/scan.c
使用"PRP0001"这个值后,设备的驱动注册方式有点类似内核的设备树。
Package (0x02) {“compatible”, “opencores,i2c-ocores”} 这个用于与驱动源码struct of_device_id中的compatible进行匹配,如果字段值相同(即"opencores,i2c-ocores"),
设备就与驱动匹配上,执行probe函数注册。
Package (0x02) {“clocks”, Package (0x01) {“\_SB.CLK1”}} 这个指向时钟CLK1,但是经过验证i2c驱动好像并没有与这个clocks关联上,执行devm_clk_gets函数时获取时钟源失败,即使CLK1驱动已经成功注册进内核。这个clocks好像跟嵌入式常用的设备树的并不一样。
内核的i2c-ocores.c驱动也要做点修改,这样就可以兼容ACPI的注册方式。