/**************************************************************************        OK335xS CAN device register and deiver match hacking* 声明:*     本文主要是跟踪CAN设备的注册、和驱动的匹配方式,了解CAN的注册流程。**                                  2015-9-7 晴 深圳 南山平山村 曾剑锋        ************************************************************************/
MACHINE_START(AM335XEVM, "am335xevm")/* Maintainer: Texas Instruments */.atag_offset    = 0x100,.map_io         = am335x_evm_map_io,.init_early     = am33xx_init_early,.init_irq       = ti81xx_init_irq,.handle_irq     = omap3_intc_handle_irq,.timer          = &omap3_am33xx_timer,.init_machine   = am335x_evm_init,            ------+
MACHINE_END                                             ||
MACHINE_START(AM335XIAEVM, "am335xiaevm")               |/* Maintainer: Texas Instruments */                 |.atag_offset    = 0x100,                            |.map_io         = am335x_evm_map_io,                |.init_irq       = ti81xx_init_irq,                  |.init_early     = am33xx_init_early,                |.timer          = &omap3_am33xx_timer,              |.init_machine   = am335x_evm_init,            ------+
MACHINE_END                                             ||
static void __init am335x_evm_init(void)          <-----+
{setup_ok335xs();                              ------+
}                                                       ||
static void setup_ok335xs(void)                   <-----+
{pr_info("The board is a ok335xs.\n");/* Starter Kit has Micro-SD slot which doesn't have Write Protect pin */am335x_mmc[0].gpio_wp = -EINVAL;_configure_device(EVM_SK, ok335xs_dev_cfg, PROFILE_NONE);^------------------------------------+am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, NULL, NULL);                  |/* Atheros Tx Clk delay Phy fixup */                                   |phy_register_fixup_for_uid(AM335X_EVM_PHY_ID, AM335X_EVM_PHY_MASK,     |am33xx_evm_tx_clk_dly_phy_fixup);                       |
}                                                                          ||
/*ok335xs*/                                                                |
static struct evm_dev_cfg ok335xs_dev_cfg[] = {          <-----------------+{mmc0_init,     DEV_ON_BASEBOARD, PROFILE_ALL},//fixed#if defined(CONFIG_ANDROID){mfd_tscadc_init,         DEV_ON_BASEBOARD, PROFILE_ALL},#endif{rgmii1_init,    DEV_ON_BASEBOARD, PROFILE_ALL},{rgmii2_init,    DEV_ON_BASEBOARD, PROFILE_ALL},{lcdc_init,     DEV_ON_BASEBOARD, PROFILE_ALL},//fixed
    {i2c1_init,     DEV_ON_BASEBOARD, PROFILE_ALL},{buzzer_init,     DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{enable_ecap2,     DEV_ON_BASEBOARD, PROFILE_ALL},//fixed
    {usb0_init,     DEV_ON_BASEBOARD, PROFILE_ALL},{usb1_init,     DEV_ON_BASEBOARD, PROFILE_ALL},{evm_nand_init,DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{mcasp1_init,   DEV_ON_BASEBOARD, PROFILE_NONE},//fixed{gpio_keys_init_forlinx_s,  DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{gpio_led_init_s,  DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{uart2_init_s,  DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{spi1_init_s,           DEV_ON_BASEBOARD, PROFILE_ALL},//fixed{d_can_init, DEV_ON_BASEBOARD, PROFILE_ALL},//fixed    ------+{sgx_init,       DEV_ON_BASEBOARD, PROFILE_ALL},             |{NULL, 0, 0},                                                |
};                                                               ||
static void d_can_init(int evm_id, int profile)      <-----------+
{//setup_pin_mux(d_can0_pin_mux);setup_pin_mux(d_can_gp_pin_mux);   ---------------------------------+am33xx_d_can_init(1);       |      ---------------------------------*-+
}                               |                                       | |V                                       | |
static struct pinmux_config d_can_gp_pin_mux[] = {                      | |{"uart0_ctsn.d_can1_tx", OMAP_MUX_MODE2 | AM33XX_PULL_ENBL},        | |{"uart0_rtsn.d_can1_rx", OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP}, | |{NULL, 0},                                                          | |
};                                                                      | || |
static void setup_pin_mux(struct pinmux_config *pin_mux)    <-----------+ |
{                                                                         |int i;                                                                ||for (i = 0; pin_mux->string_name != NULL; pin_mux++)                  |omap_mux_init_signal(pin_mux->string_name, pin_mux->val); ------+ || |
}                                                                       | || |
int __init omap_mux_init_signal(const char *muxname, int val)     <-----+ |
{                                                                         |struct omap_mux_partition *partition = NULL;                          |struct omap_mux *mux = NULL;                                          |u16 old_mode;                                                         |int mux_mode;                                                         ||mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);           |if (mux_mode < 0)                                                     |return mux_mode;                                                  ||old_mode = omap_mux_read(partition, mux->reg_offset);                 |mux_mode |= val;                                                      |pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",                  |__func__, muxname, old_mode, mux_mode);                      |omap_mux_write(partition, mux_mode, mux->reg_offset);                 ||return 0;                                                             |
}                                                                         ||
void am33xx_d_can_init(unsigned int instance)        <--------------------+
{struct omap_hwmod *oh;struct platform_device *pdev;char oh_name[L3_MODULES_MAX_LEN];/* Copy string name to oh_name buffer */snprintf(oh_name, L3_MODULES_MAX_LEN, "d_can%d", instance);oh = omap_hwmod_lookup(oh_name);if (!oh) {pr_err("could not find %s hwmod data\n", oh_name);return;}pdev = omap_device_build("d_can", instance, oh, &am33xx_dcan_info,  ----------+sizeof(am33xx_dcan_info), NULL, 0, 0);                                |if (IS_ERR(pdev))                                                             |pr_err("could not build omap_device for %s\n", oh_name);                  |
}                                                                                 ||
struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, <---+struct omap_hwmod *oh, void *pdata,int pdata_len,struct omap_device_pm_latency *pm_lats,int pm_lats_cnt, int is_early_device)
{struct omap_hwmod *ohs[] = { oh };if (!oh)return ERR_PTR(-EINVAL);return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,        ----------+pdata_len, pm_lats, pm_lats_cnt,                                |is_early_device);                                               |
}                                                                                   ||
struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, <--+struct omap_hwmod **ohs, int oh_cnt,void *pdata, int pdata_len,struct omap_device_pm_latency *pm_lats,int pm_lats_cnt, int is_early_device)
{int ret = -ENOMEM;struct platform_device *pdev;struct omap_device *od;if (!ohs || oh_cnt == 0 || !pdev_name)return ERR_PTR(-EINVAL);if (!pdata && pdata_len > 0)return ERR_PTR(-EINVAL);pdev = platform_device_alloc(pdev_name, pdev_id);if (!pdev) {ret = -ENOMEM;goto odbs_exit;}/* Set the dev_name early to allow dev_xxx in omap_device_alloc */if (pdev->id != -1)dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);elsedev_set_name(&pdev->dev, "%s", pdev->name);od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);if (!od)goto odbs_exit1;ret = platform_device_add_data(pdev, pdata, pdata_len);if (ret)goto odbs_exit2;if (is_early_device)ret = omap_early_device_register(pdev);elseret = omap_device_register(pdev);           -------------------+if (ret)                                                           |goto odbs_exit2;                                               ||return pdev;                                                       ||
odbs_exit2:                                                            |omap_device_delete(od);                                            |
odbs_exit1:                                                            |platform_device_put(pdev);                                         |
odbs_exit:                                                             ||pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);    ||return ERR_PTR(ret);                                               |
}                                                                      ||
int omap_device_register(struct platform_device *pdev)     <-----------+
{pr_debug("omap_device: %s: registering\n", pdev->name);printk("omap_device: %s: registering\n", pdev->name);pdev->dev.parent = &omap_device_parent;pdev->dev.pm_domain = &omap_device_pm_domain;return platform_device_add(pdev);                      ------------+
}                                                                      ||
int platform_device_add(struct platform_device *pdev)      <-----------+
{int i, ret = 0;if (!pdev)return -EINVAL;if (!pdev->dev.parent)pdev->dev.parent = &platform_bus;pdev->dev.bus = &platform_bus_type;          -------------------+|if (pdev->id != -1)                                             |dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);   |else                                                            |dev_set_name(&pdev->dev, "%s", pdev->name);                 ||for (i = 0; i < pdev->num_resources; i++) {                     |struct resource *p, *r = &pdev->resource[i];                ||if (r->name == NULL)                                        |r->name = dev_name(&pdev->dev);                         ||p = r->parent;                                              |if (!p) {                                                   |if (resource_type(r) == IORESOURCE_MEM)                 |p = &iomem_resource;                                |else if (resource_type(r) == IORESOURCE_IO)             |p = &ioport_resource;                               |}                                                           ||if (p && insert_resource(p, r)) {                           |printk(KERN_ERR                                         |"%s: failed to claim resource %d\n",             |dev_name(&pdev->dev), i);                        |ret = -EBUSY;                                           |goto failed;                                            |}                                                           |}                                                               ||pr_debug("Registering platform device '%s'. Parent at %s\n",    |dev_name(&pdev->dev), dev_name(pdev->dev.parent));         ||ret = device_add(&pdev->dev);                                   |if (ret == 0)                                                   |return ret;                                                 ||failed:                                                            |while (--i >= 0) {                                              |struct resource *r = &pdev->resource[i];                    |unsigned long type = resource_type(r);                      ||if (type == IORESOURCE_MEM || type == IORESOURCE_IO)        |release_resource(r);                                    |}                                                               ||return ret;                                                     |
}                                                                   |
EXPORT_SYMBOL_GPL(platform_device_add);                             ||
struct bus_type platform_bus_type = {        <----------------------+.name        = "platform",.dev_attrs    = platform_dev_attrs,.match        = platform_match,          -------------------------------+.uevent        = platform_uevent,                                       |.pm        = &platform_dev_pm_ops,                                      |
};                                                                          |
EXPORT_SYMBOL_GPL(platform_bus_type);                                       ||
static int platform_match(struct device *dev, struct device_driver *drv) <--+
{struct platform_device *pdev = to_platform_device(dev);struct platform_driver *pdrv = to_platform_driver(drv);/* Attempt an OF style match first */if (of_driver_match_device(dev, drv))           -------------+return 1;                                                ||/* Then try to match against the id table */                 |if (pdrv->id_table)                                          |return platform_match_id(pdrv->id_table, pdev) != NULL;  |^------------------------------------------|-+/* fall-back to driver name match */                         | |// canbus use this for match                                 | |return (strcmp(pdev->name, drv->name) == 0);                 | |
}                                                                | || |
static inline int of_driver_match_device(struct device *dev, <---+ |const struct device_driver *drv)              |
{                                                                  |return of_match_device(drv->of_match_table, dev) != NULL;      |
}                                                                  ||
static const struct platform_device_id *platform_match_id(   <-----+const struct platform_device_id *id,struct platform_device *pdev)
{while (id->name[0]) {if (strcmp(pdev->name, id->name) == 0) {pdev->id_entry = id;return id;}id++;}return NULL;
}cat drivers/net/can/d_can/d_can_platform.c
static struct platform_driver d_can_plat_driver = {   <-----+.driver = {                                             |.name   = D_CAN_DRV_NAME,            ---------------*-+.owner  = THIS_MODULE,                              | |},                                                      | |.probe      = d_can_plat_probe,          ---------------*-*-----+.remove     = __devexit_p(d_can_plat_remove),           | |     |.suspend    = d_can_suspend,                            | |     |.resume     = d_can_resume,                             | |     |
};                                                          | |     || |     |
static int __init d_can_plat_init(void)      <------------+ | |     |
{                                                         | | |     |printk(KERN_INFO D_CAN_DRV_DESC "\n");                | | |     |return platform_driver_register(&d_can_plat_driver);--*-- |     |
}                                                         |   |     |
module_init(d_can_plat_init); ----------------------------+   |     ||     |
static void __exit d_can_plat_exit(void)                      |     |
{                                                             |     |printk(KERN_INFO D_CAN_DRV_DESC " unloaded\n");           |     |platform_driver_unregister(&d_can_plat_driver);           |     |
}                                                             |     |
module_exit(d_can_plat_exit);                                 |     ||     |
MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");             |     |
MODULE_LICENSE("GPL v2");                                     |     |
MODULE_VERSION(D_CAN_VERSION);                                |     |
MODULE_DESCRIPTION(D_CAN_DRV_DESC);                           |     ||     |
#define D_CAN_DRV_NAME    "d_can"            <----------------+     |v-------------------------------------+
static int __devinit d_can_plat_probe(struct platform_device *pdev)
{int ret = 0;void __iomem *addr;struct net_device *ndev;struct d_can_priv *priv;struct resource *mem;struct d_can_platform_data *pdata;struct clk *fck;printk("zengjf check can plat probed.\n");pdata = pdev->dev.platform_data;if (!pdata) {dev_err(&pdev->dev, "No platform data\n");goto exit;}/* allocate the d_can device */ndev = alloc_d_can_dev(pdata->num_of_msg_objs);if (!ndev) {ret = -ENOMEM;dev_err(&pdev->dev, "alloc_d_can_dev failed\n");goto exit;}priv = netdev_priv(ndev);fck = clk_get(&pdev->dev, "fck");if (IS_ERR(fck)) {dev_err(&pdev->dev, "fck is not found\n");ret = -ENODEV;goto exit_free_ndev;}/* get the platform data */mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (!mem) {ret = -ENODEV;dev_err(&pdev->dev, "No mem resource\n");goto exit_clk_put;}if (!request_mem_region(mem->start, resource_size(mem),D_CAN_DRV_NAME)) {dev_err(&pdev->dev, "resource unavailable\n");ret = -EBUSY;goto exit_clk_put;}addr = ioremap(mem->start, resource_size(mem));if (!addr) {dev_err(&pdev->dev, "ioremap failed\n");ret = -ENOMEM;goto exit_release_mem;}/* IRQ specific to Error and status & can be used for Message Object */ndev->irq = platform_get_irq_byname(pdev, "d_can_ms");if (!ndev->irq) {dev_err(&pdev->dev, "No irq0 resource\n");goto exit_iounmap;}/* IRQ specific for Message Object */priv->irq_obj = platform_get_irq_byname(pdev, "d_can_mo");if (!priv->irq_obj) {dev_err(&pdev->dev, "No irq1 resource\n");goto exit_iounmap;}pm_runtime_enable(&pdev->dev);pm_runtime_get_sync(&pdev->dev);priv->pdev = pdev;priv->base = addr;priv->can.clock.freq = clk_get_rate(fck);priv->ram_init = pdata->ram_init;priv->opened = false;platform_set_drvdata(pdev, ndev);SET_NETDEV_DEV(ndev, &pdev->dev);ret = register_d_can_dev(ndev);if (ret) {dev_err(&pdev->dev, "registering %s failed (err=%d)\n",D_CAN_DRV_NAME, ret);goto exit_free_device;}/* Initialize DCAN RAM */d_can_reset_ram(priv, pdev->id, 1);dev_info(&pdev->dev, "device registered (irq=%d, irq_obj=%d)\n",ndev->irq, priv->irq_obj);return 0;exit_free_device:platform_set_drvdata(pdev, NULL);pm_runtime_disable(&pdev->dev);
exit_iounmap:iounmap(addr);
exit_release_mem:release_mem_region(mem->start, resource_size(mem));
exit_clk_put:clk_put(fck);
exit_free_ndev:free_d_can_dev(ndev);
exit:dev_err(&pdev->dev, "probe failed\n");return ret;
}

转载于:https://www.cnblogs.com/zengjfgit/p/4788923.html

OK335xS CAN device register and deiver match hacking相关推荐

  1. 内核添加dts后,device和device_driver的match匹配的变动:通过compatible属性进行匹配【转】...

    本文转载自:http://blog.csdn.net/ruanjianruanjianruan/article/details/61622053 内核添加dts后,device和device_driv ...

  2. linux设备驱动归纳总结(八):2.match.probe.remove

    CU首页 ┊ fh265>>博客 微博 相册 个人中心 好友 消息 [退出] ┊ 随便看看 公告:缅怀Dennis Ritchie活动开赛啦! 小白的博客--提升自已,分享别人 xiaob ...

  3. Linux usb 4. Device 详解

    文章目录 1. 简介 2. Platform Layer 2.1 Platform Device 2.2 Platform Driver 3. UDC/Gadget Layer 3.1 Gadget ...

  4. Linux Driver 和Device匹配过程分析

    Linux Driver 和Device匹配过程分析 1,总线注册匹配过程 1.1 struct platform_driver 1.2 struct device_driver 1.3 PCIe总线 ...

  5. Linux设备模型(4) — bus 与 device 和 driver

    前面说了 device 和 device_driver,这两者是通过一个叫 bus 的东西联系在一起,不管这个 bus 是否是真实的存在(虚拟的也算). 1.Bus Linux 中,对 bus 是由一 ...

  6. linux驱动开发音频设备驱动,linux驱动开发—基于Device tree机制的驱动编写

    摘要:媒介 Device Tree是一种用去描绘硬件的数据布局,类似板级描绘说话,发源于OpenFirmware(OF).正在现在遍及应用的kernel 2.6.x版本中,对分歧仄台.分歧硬件,往] ...

  7. Android 驱动(12)---Linux DTS(Device Tree Source)设备树详解

    Linux DTS(Device Tree Source)设备树详解 Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) Linux DTS(Device Tr ...

  8. LINUX IIO子系统分析之六 iio device的驱动开发流程说明

    前面五章我们基本上把IIO 子系统的内部设计实现均作了说明,本章我们将说明iio device的驱动开发流程,本章的主要内容大致安排如下: 一.IIO子系统的关键技术点总结 二.IIO DEVICE的 ...

  9. 高通平台msm8953 Linux DTS(Device Tree Source)设备树详解之二(DTS设备树匹配过程)

    本系列导航: 高通平台8953  Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) 高通平台8953 Linux DTS(Device Tree Source ...

最新文章

  1. 莱芜市公安局交警支队智能交通项目集成及容灾公开招标公告
  2. java word模板占位符_word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)...
  3. python3--装饰器
  4. 数据库acid简介(一)
  5. MIT自然语言处理第一讲:简介和概述(第三部分)
  6. 理解Floyd-Warshall算法
  7. .Net高级技术——对象序列化
  8. web.py开发web 第一章 Hello World
  9. 基于matlab的prony方法实现,基于MATLAB的Prony方法实现
  10. 【推荐实践】Bandit算法在携程推荐系统中的应用与实践
  11. ----------------------------------------spring 整合jdbc---------------------
  12. python编程语言_Python编程语言的历史
  13. 目前流行的源程序版本管理软件和项目管理的软件优缺点
  14. SQL Server高可用——日志传送(4-3)——使用
  15. python自动登录网银_网银自动充值-登陆联通网站沃支付
  16. 计算机网络实验指导书 pdf,计算机网络实验指导书(新版).pdf
  17. codevs 5294 挖地雷
  18. 为什么不要用苹果的@icloud.com邮箱申请你的APP ID
  19. kafka集群开启sasl认证
  20. 计算机系学生thinkbook,设计师笔记本电脑推荐 ThinkBook 15p视觉系创造本你值得拥有...

热门文章

  1. pku 1486 求出二分匹配图中的必须边
  2. head first html with css with xhtml 学习小笔记
  3. spring+hibernate的配置
  4. Windows核心编程 第25章 未处理异常和C ++异常(下)
  5. 【Linux 内核】编译 Linux 内核 ⑤ ( 查看 .config 编译配置文件 | 正式编译内核 )
  6. 【EventBus】事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )
  7. 【Java 并发编程】线程简介 ( 原子操作 | volatile 关键字使用场景 )
  8. Sun公司的产品AnswerBook存在多种漏洞
  9. 网页瀑布流效果实现的几种方式
  10. Prism框架研究(一)