This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Testing of am335x IRQs from Linux user space

Other Parts Discussed in Thread: TLV320AIC3106

Hi,


I want to test the gpio based interrupts from an Linux application for am335x platform.
The operations to test are enable/disable/read IRQs for RTC, PMIC, ARCNET, FASTE, GIGE peripherals.
After enable the irq, the app shall need to trigger the particular interrupt somehow, and be able to verify that interrupt is generated.

Is there any common way/solution to enable/disable particular IRQ from the Linux user space for the above peripherals on am335x platform?
Such that the app can send down an IOCTL (with GPIO number argument) to a pseudo driver which shall handle the enable/disable/read IRQ requests.

So I would like to know whether there exist any generic solution/interface available to enable/disable IRQs, of peripherals mentioned above, from a kernel driver level?
Or what are all the possible ways/methods that this can be achieved?

The kernel version I am using is 3.12.10. (SDK version 7)

Kindly let me know if further details are required regarding this.

  • Hi,

    I will forward this to the SW team.
  • Hi,

    You could enable/and see if interrupts are enabled/ the interrupts by writing/reading/ to the IRQ_ENABLE & IRQ_STATUS registers of the corresponding modules. You should mmap() the physical addresses of the IP registers & then perform reading or writing. For reference see the implementation of devmem2: free-electrons.com/.../devmem2.c

    So enabling/disabling interrupts by writing/reading to IRQ_ENABLE/IRQ_STATUS registers is achievable.

    However I am not sure about handling the generated interrupts from user space, since doing this from user space generally narrows down to working with files (/proc/interrupts/) and this is quite slower compared to using a kernel irq handler.

    Best Regards,
    Yordan
  • Hi Yordan,

    Thanks for the suggestion.

    Today, actually I have tried by compiling this sample app for the am335x, and tried to use the memory address as mentioned in page.183 of the document in the link (www.ti.com/.../spruh73l.pdf) for GPIO3 (0x4814E000).
    But it was not working, getting error as “Memory mapped at address 0xb6f61[ 9482.306766] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f61000”.

    I didn't change the sample program, just passed the GPIO memory address 0x4814E000 in the argument.

    Can you suggest what may be the problem?

    Thanks & Regards,
    Sivaraj
  • Hi Sivaraj,

    Sivaraj Sivalingam said:
    But it was not working, getting error as “Memory mapped at address 0xb6f61[ 9482.306766] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f61000”.

    This means that you are trying to access memory that is not properly mapped to the kernel's virtual address space. 

    Can you verify the address? As I see from AM335x TRM Table 2-3. L4_PER Peripheral Memory Map (continued), p.183, GPIO3 address is 0x481AE000, not 0x4814E0000

    Best Regards, 

    Yordan

  • Hi Yordan,

    Thanks for pointing that, that one was my bad :-( The address 0x481AE000 works fine for GPIO3.

    BTW, if I try to mmap() memory for i2c device, for example, EEPROM, I still get the same error I mentioned earlier, which suggests that the address is wrong.

    But can you suggest how to get the correct address for devices, like those on the bus like i2c devices.

    I have also tried to map the UART3 memory at 0x481A6000, but same error.

    What is the difference here in accessing the GPIO memory and device modules memory? Could you please help me understand it?

    Thanks a lot for the help.

    Best Regards,

    Sivaraj

  • Hi Sivaraj,

    The access to some IPs is restricted from user space. I.e. EEPROM is connected to I2C0, and so are the PMIC, sometimes lcd & codec, so it may have restrictions to access it from user space.

    Can you provide the output of devmem2 0x481A6000?

    Also can you try accessing it from kernel, with __raw_readl() or __raw_writel()?

    Best Regards,
    Yordan
  • Hi Yordan,

    The output of devmem2 for 0x481A6000 is given below:
    #devmem2 0x481A6000
    /dev/mem opened.
    Memory mapped at address 0xb6f70[13401.706525] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f70000
    000.
    Bus error

    BTW, I am yet to try accessing using __raw_readl() or __raw_writel() as you have suggested, will try and let you know.
    I can directly use this address with these routines?

    Also do I need to consider any offset or so for the peripherals like EEPROM, RTC, PMIC, etc, which are on I2C bus. Or can directly use the i2c base address for mapping?

    Thanks & Regards,
    Sivaraj
  • Hi Sivaraj, 

    Sivaraj Sivalingam said:
    #devmem2 0x481A6000
    /dev/mem opened.
    Memory mapped at address 0xb6f70[13401.706525] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f70000
    000.
    Bus error

     

    This means that you haven't enabled the UART3 functional clocks, and this is why you cannot access its registers from user space. 

    Sivaraj Sivalingam said:
    Also do I need to consider any offset or so for the peripherals like EEPROM, RTC, PMIC, etc, which are on I2C bus. Or can directly use the i2c base address for mapping?

     

    They are located at different I2C addresses. Check your dts to see which i2c address corresponds to each device, i.e. in am335x-evmsk.dts: 
      tps: tps@2d -> pmic is at address 2d on I2C0 

      lis331dlh: lis331dlh@18 -> corresponds to address 18 on I2C0

       tlv320aic3106: tlv320aic3106@1b -> audio codec @ 1b on I2C0

    Those are the addresses you need to consider, when initiating I2C communication with the listed peripherals. 

    Best Regards, 

    Yordan