[技术问答] NUC972 linux 内核nuc970-sc 驱动程序bug

[复制链接]
1769|11
 楼主| dubilu 发表于 2019-9-4 11:01 | 显示全部楼层 |阅读模式
drivers/misc/nuc970-sc.c文件

  1. static int sc_open(struct inode *inode, struct file *filp)
  2. {

  3.         int ret, intf;

  4.         for(intf = 0; intf < SC_INTF; intf++)
  5.                 if(MINOR(inode->i_rdev) == sc[intf].minor) {
  6.                         break;
  7.                 }
  8.         mutex_lock(&sc[intf].lock);
  9.         if(sc->open == 1) {
  10.                 mutex_unlock(&sc[intf].lock);
  11.                 return -EBUSY;
  12.         }
  13.         filp->private_data = (void *)&sc[intf];

  14.         if(intf == 0) {
  15.                 sc[intf].clk = clk_get(NULL, "smc0");
  16.                 sc[intf].eclk = clk_get(NULL, "smc0_eclk");
  17.         } else {
  18.                 sc[intf].clk = clk_get(NULL, "smc1");
  19.                 sc[intf].eclk = clk_get(NULL, "smc1_eclk");
  20.         }


  21.         if (IS_ERR(sc[intf].clk)) {
  22.                 printk("failed to get sc clock\n");
  23.                 ret = PTR_ERR(sc[intf].clk);
  24.                 goto out2;
  25.         }
  26.         if (IS_ERR(sc[intf].eclk)) {
  27.                 printk("failed to get sc eclock\n");
  28.                 ret = PTR_ERR(sc[intf].eclk);
  29.                 goto out2;
  30.         }
  31.         clk_prepare(sc[intf].clk);
  32.         clk_enable(sc[intf].clk);
  33.         clk_prepare(sc[intf].eclk);
  34.         clk_enable(sc[intf].eclk);
  35.         clk_set_rate(sc[intf].eclk, 4000000);        // Set SC clock to 4MHz

  36.         if(sc[intf].pwrinv) {
  37.                 __raw_writel(__raw_readl(sc[intf].base + REG_SC_PINCTL) | SC_PINCTL_PWRINV, sc[intf].base + REG_SC_PINCTL);
  38.         }
  39.         if(sc[intf].cdlvl == 0) {
  40.                 __raw_writel(__raw_readl(sc[intf].base + REG_SC_CTL) | SC_CTL_CDLV, sc[intf].base + REG_SC_CTL);
  41.         }

  42.         // enable SC engine
  43.         __raw_writel(__raw_readl(sc[intf].base + REG_SC_CTL) | SC_CTL_SCEN, sc[intf].base + REG_SC_CTL);
  44.         if (request_irq(sc[intf].irq, nuc970_sc_interrupt,
  45.                                                 0x0, "nuc970-sc", (void *)&sc[intf])) {
  46.                 printk("register irq failed %d\n", sc[intf].irq);
  47.                 ret = -EAGAIN;
  48.                 goto out1;
  49.         }
  50.         sc[intf].open = 1;
  51.         mutex_unlock(&sc[intf].lock);
  52.         return 0;


  53. out1:

  54.         free_irq(sc[intf].irq, (void *)&sc[intf]);
  55. out2:
  56.         mutex_unlock(&sc[intf].lock);
  57.         return ret;

  58. }
if(sc->open == 1) //会导致SC0 open时 SC1 open 错误,修改为 if(sc[intf].open == 1) 即可



antusheng 发表于 2019-9-4 20:59 | 显示全部楼层
果然有道理。
643757107 发表于 2019-9-4 22:55 | 显示全部楼层
果然是高人
21mengnan 发表于 2019-9-4 23:06 | 显示全部楼层
看了一下代码,还真是。
734774645 发表于 2019-9-4 23:07 | 显示全部楼层
楼主对内核了解的深入啊
734774645 发表于 2019-9-4 23:08 | 显示全部楼层
包括串行通信接口模块SC_INTF
dongnanxibei 发表于 2019-9-4 23:09 | 显示全部楼层
这个驱动是Linux提供的还是新唐提供的,其他厂家的是怎么做大
heisexingqisi 发表于 2019-9-4 23:43 | 显示全部楼层
不错,牛。
heisexingqisi 发表于 2019-9-4 23:50 | 显示全部楼层
这要对源码很了解啊。
sklar 发表于 2019-9-7 12:10 | 显示全部楼层
厉害哦
fangdichan 发表于 2019-10-3 21:50 | 显示全部楼层
厉害,我看一下我的代码有没有这个问题
coshi 发表于 2019-10-13 11:57 | 显示全部楼层
非常感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部