imx.536(cotex-a8核)的CAN驱动理解一(probe)
static int flexcan_device_attach(struct flexcan_device *flexcan){int ret;struct resource *res;struct platform_device *pdev = flexcan->dev;struct flexcan_platform_data *plat_data = (pdev->dev).platform_data;struct clk *can_root_clk;//看到了熟悉的身影了res = platform_get_resource(flexcan->dev, IORESOURCE_MEM, 0);if (!res)return -ENODEV;//内存映射flexcan->io_base = ioremap(res->start, res->end - res->start + 1);if (!flexcan->io_base)return -ENOMEM;//咋没直接注册中断?flexcan->irq = platform_get_irq(flexcan->dev, 0);if (!flexcan->irq) {ret = -ENODEV;goto no_irq_err;}ret = -EINVAL;if (plat_data) {if (plat_data->core_reg) {flexcan->core_reg = regulator_get(&pdev->dev, plat_data->core_reg);if (!flexcan->core_reg)goto plat_err;}if (plat_data->io_reg) {flexcan->io_reg = regulator_get(&pdev->dev,plat_data->io_reg);if (!flexcan->io_reg)goto plat_err;}}flexcan->clk = clk_get(&(flexcan->dev)->dev, "can_clk");//如果板级配置文件中root_clk_id被配置了,can时钟源变成了root_clk_idif (plat_data->root_clk_id) {can_root_clk = clk_get(NULL, plat_data->root_clk_id);clk_set_parent(flexcan->clk, can_root_clk);}flexcan->hwmb = (struct can_hw_mb *)(flexcan->io_base + CAN_MB_BASE);flexcan->rx_mask = (unsigned int *)(flexcan->io_base + CAN_RXMASK_BASE);return 0;//以后得多学学内核纠错处理了 plat_err:if (flexcan->core_reg) {regulator_put(flexcan->core_reg);flexcan->core_reg = NULL;} no_irq_err:if (flexcan->io_base)iounmap(flexcan->io_base);return ret;}