如何从linux内核模块访问共享寄存器?

时间:2017-04-28 09:41:09

标签: c linux-kernel linux-device-driver embedded-linux beagleboneblack

上下文

我正在开发一个用于与CPLD通信的LKM,它涉及访问GPIO。为了对此进行原型设计,我使用了配备TI处理器的beaglebone black,即Sitara AM3358(ARM Cortex-A8)。我使用buildroot构建了一个最小系统(Linux内核是4.6)。出于性能原因,我想直接访问GPIO寄存器而不是使用gpiolib。

注意:我是LKM开发的初学者,但我习惯为微控制器开发设备驱动程序

我做了什么

如本帖所示:What does request_mem_region() actually do and when it is needed?

在读取和写入寄存器之前,我尝试将request_mem_regionioremap一起使用。

代码如下所示:

if(request_mem_region(GPIO0_BASE_ADDR, GPIO_BLOCK_SIZE, DEVICE_NAME) == NULL)
{
    printk(KERN_ALERT
           "[%s] Unable to request mem region for GPIO0\n",
           DEVICE_NAME);

    status = -EBUSY;
    goto error;
}

gpio0 = ioremap(GPIO0_BASE_ADDR, GPIO_BLOCK_SIZE);

//Set somme pins as output
gpio_oe = ioread32(gpio0 + GPIO_OE);
gpio_oe &= ~GPIO0_PIN_MASK;
iowrite32(gpio_oe, gpio0 + GPIO_OE);

request_mem_region失败,因为某些其他驱动程序或“实体”已经保留了此区域。

/proc/iomem显示:

40300000-4030ffff : 40300000.ocmcram
44e07000-44e07fff : /ocp/gpio@44e07000
44e09000-44e0afff : /ocp/serial@44e09000
44e0b000-44e0bfff : /ocp/i2c@44e0b000
44e10650-44e10653 : gmii-sel
44e10800-44e10a37 : pinctrl-single
44e10f90-44e10fcf : /ocp/l4_wkup@44c00000/scm@210000/dma-router@f90
48042000-480423ff : /ocp/timer@48042000
48044000-480443ff : /ocp/timer@48044000
48046000-480463ff : /ocp/timer@48046000
48048000-480483ff : /ocp/timer@48048000
4804a000-4804a3ff : /ocp/timer@4804a000
4804c000-4804cfff : /ocp/gpio@4804c000
48060000-48060fff : /ocp/mmc@48060000
4819c000-4819cfff : /ocp/i2c@4819c000
481ac000-481acfff : /ocp/gpio@481ac000
481ae000-481aefff : /ocp/gpio@481ae000
481d8000-481d8fff : /ocp/mmc@481d8000
49000000-4900ffff : edma3_cc
4a100000-4a1007ff : /ocp/ethernet@4a100000
4a101000-4a1010ff : /ocp/ethernet@4a100000/mdio@4a101000
4a101200-4a1012ff : /ocp/ethernet@4a100000
80000000-9fdfffff : System RAM
  80008000-80a70ac7 : Kernel code
  80c00000-814b381f : Kernel data

此行44e07000-44e07fff : /ocp/gpio@44e07000是我要保留的内存区域。这里有点问题。

问题

这里有两种方法。

  1. 我的驱动程序是他世界上唯一一个访问GPIO0块的驱动程序(但只使用了几个引脚)
  2. 我必须找到哪个驱动程序保留了内存并将其删除。但是怎么样? 它是pinctrl-single吗? “ocp”出现在beaglebone的设备树中,但我不太清楚它与设备树中的内容和这个保留的内存区域之间的关系......

    1. 多个驱动程序可能正在访问GPIO0块
    2. 让我们设想一个用例,其中一些驱动程序想要访问GPIO0.1而另一个驱动程序想要访问GPIO0.2,它们都需要访问GPIO0寄存器。 这里不再提供独有的内存预留,如何妥善管理? 特别是在上面的情况下,我有somme序列的读 - 修改 - 写...

      TL; DR

      在linux内核模块中如何访问可以从其他驱动程序访问的寄存器?如何在访问期间管理锁定机制?

      由于

0 个答案:

没有答案