- 由 b178903294创建, 最后修改于9月 19, 2019 版权所有,谢绝转载
此看门狗相关寄存器位于PMC设备中,用于监控系统电源状态的。PMC (Power Management Controller) 是一个PCI device, pci地址为B/D/F=0/13/1,这个地址是IPC1/GCR/ACPI块的基地址。 关于pci地址如何计算出16进制物理地址请参照:PCI/PCIe基础——配置空间
近日接到需求,在系统log中看到iTCO_wdt在probe的过程中失败:
> [ 9.377211] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11 > [ 9.377407] iTCO_wdt: probe of iTCO_wdt failed with error -16 |
所以第一时间就去看了是哪里打印出了这一条错误的log,后来经过测试发现是在iTCO_wdt probe的过程中申请相关寄存器没有成功,所以返回错误,具体是下面这段报错:
iTCO_wdt_probe
if (iTCO_wdt_private.iTCO_version >= 2) {
iTCO_wdt_private.gcs_pmc_res = platform_get_resource(dev, IORESOURCE_MEM, ICH_RES_MEM_GCS_PMC); if (!iTCO_wdt_private.gcs_pmc_res) goto out; if (!request_mem_region(iTCO_wdt_private.gcs_pmc_res->start, //这句由于申请没有被批准所以报错返回了 resource_size(iTCO_wdt_private.gcs_pmc_res), dev->name)) {
ret = -EBUSY; goto out; } iTCO_wdt_private.gcs_pmc = ioremap(iTCO_wdt_private.gcs_pmc_res->start, resource_size(iTCO_wdt_private.gcs_pmc_res)); if (!iTCO_wdt_private.gcs_pmc) {
ret = -EIO; goto unreg_gcs_pmc; } } |
request_mem_region的时候直接报错返回。那么肯定是这块内存申请不下来,那么这时候就去查了一下内存和谁冲突了??? 通过cat /proc/iomem 发现:
fe042000-fe043fff : INT34D2:00 fe043000-fe043fff : iTCO_wdt |
原来是这两个内存段冲突了。那么问题来了我们的内存段是从哪里申请过来的???platform_get_resource这句函数就是申请相关资源用的,但是哪里定义了这些资源呢???经过艰苦卓绝的寻找,发现再intel_pmc_ipc.c中定义了相关资源:
static struct resource tco_res[] = {
/* ACPI - TCO */ {
.flags = IORESOURCE_IO, }, /* ACPI - SMI */ {
.flags = IORESOURCE_IO, }, /* GCS */ {
.flags = IORESOURCE_MEM, }, }; |
与iTCO_wdt相关的io和内存资源都在这里面定义了,具体是由下面这段代码添加的资源:
static int ipc_create_tco_device( void ) {
struct platform_device *pdev; struct resource *res; int ret; pdev = platform_device_alloc(TCO_DEVICE_NAME, -1); if (!pdev) {
dev_err(ipcdev.dev, "Failed to alloc tco platform device\n" ); return -ENOMEM; } pdev->dev.parent = ipcdev.dev;
|