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.

NMI working in the AM335x.

hi 

   I am using NMI intrrrupt line.But the problem is that the interrupt occurs constantly when the pin is low.and interrupt

handler does not return.

 please help me to resolve this issue. how can i make use of this line so that  it fire interrupt only once

 

  • Hi Shammi,

    The NMI pin is level sensitive. There is no way to configure it to edge sensitive, if that's what you want.

  • actually i am trying to send signal to user space when interrupt comes on this line i.e low. Is there any way in which i can disable it after firing interrupt once and enable it again. 

  • Yes, it can be masked and then unmasked in the INTC. See AM335X TRM Rev. K section 6.1.1.2 for details.

  • what i want to do is when  interrupt comes on this line ISR  will  send the signal to userspace but as you told it is level sensitive so it is continuously  calling my ISR. here i used  IRQF_ONESHOT but is disabling the interrupt line but i am able to send signal to user space  once. please give me some solution so that i can send signal to userspace whenever interrupt comes on this line. 

      

  • Sorry, I cannot help with software. Please post what software you are using and I will ask somebody from the SW team to look at this.

  • i am working on linux-3.2 kernel with customized am335x based board.

  • Hi,

    Your sequences have to be:
    1. read from MPU_INTC.INTC_ITRn
    2. mask NMI IRQ MPU_INTC.INTC_MIRn - you have to know that there are: MPU_INTC.INTC_MIR_SETn and MPU_INTC.INTC_MIR_CLEARn registers to facilitate the masking
    3. check masking from MPU_INTC.INTC_PENDING_IRQn

    You have to know that masking has to do 10-cycle window after the interrupt assertion to changed have effect.

    Also you can read 6.2.1 Initialization Sequence and 6.1.1.3 Priority Sorting

    BR
    Ivan

  • Can be mask NMI because this is non maskable interrupt. actually what i am doing is inside interrupt handler i am masking this NMI. but still interrupt is coming

    continuously on the NMI pin.

    I have registred interrput handler for this line. when interrupt is coming it is executing ISR and inside ISR i am masking this NMI pin. 

  • Hi,

    Please see from the TRM following paragraph:
    Silicon Revision Functional Differences and Enhancements
    Table 6-1. ARM Cortex-A8 Interrupts

    and Advisory 1.0.6 from the Sitara™ AM335x ARM® Cortex™ -A8 Microprocessors (MPUs) Silicon Revisions 2.1, 2.0, 1.0 Silicon Errata

    BR
    Ivan
  • it there way so that i can use this pin as interrupt line.i task is to send signal once interrupt comes on this line everytime. But it keeps calling my ISR once interrupt comes i used IRQF_ONESHOT what it is disabling the interrupt line.Please suggest some way to proceed with this.
  • What is it that you've connected externally, i.e. what is driving the NMI line? At what point does the external device stop asserting the line? Can you signal the external device from within your ISR to stop driving the line? If so you could spin until that occurs (not ideal) and that way you would not keep getting interrupts over and over.

    Is this some kind of emergency event, i.e. in response to the event are you shutting down the system or some other drastic action? About the only other possible thing that I can think of would be to modify the conf_nmi register inside the ISR, e.g. set RXACTIVE=0. Even in that case I'm not sure if it will work as I'm not sure what level is seen by the Cortex A8 when you disable RXACTIVE for that pin.
  • NMI pin is connected to LTC3226EUD 2-Cell Supercap Charger With
    Backup PowerPath Controller. when power goes it will drive the nmi pin low i.e activate the interrupt.So in this case i need to send signal to userspace to do some backup stuff inside my application. but interrupt line is always high and ISR handler does not return. I tried IRQF_ONESHOT working only once but it is disabling the line.

    request_threaded_irq(7 , power_isr ,NULL, IRQF_TRIGGER_LOW|IRQF_ONESHOT,
    "power fail" ,NULL);

    this is how i am registering the interrupt handler. with IRQF_ONESHOT it is working only once. it is disabling the interrupt line.
    please give some solution.
  • shammi kaplesh said:
    please give some solution.

    Did you try my previous suggestion?  To recap, I suggested that inside the ISR you try setting conf_nmi[rxactive]=0.

  • Ivan Matrakov said:
    You have to know that masking has to do 10-cycle window after the interrupt assertion to changed have effect.

    Only if priority sorting is already in progress, which is never the case inside an interrupt handler. I've tested this: masking an irq handling and immediately writing to CONTROL to signal eoi (and start priority sorting if any irq is asserted) will not result in a duplicate or spurious irq.  Writing to CONTROL and then masking the irq will however result in a duplicate irq.  I actually initially expected I'd get a spurious irq instead, but the docs do mention that a read of the SIR_IRQ register during sorting is stalled until sorting is complete, perhaps that actually extends to all register accesses.

    (The alternative explanation would be that the two writes somehow manage to get spaced more than 10 INTC cycles (= 20 CPU cycles) apart, but I don't see how that could be given that they are writes to device (not strongly-ordered) memory.)

  • i set REACTIVE =0  in  9C0h conf_nnmi.,but still interrupt line is not disabled continuously interrupt is coming on this line and continuosly calling my ISR so handler

    is not getting returned.

    I mapped the register using ioremap ,read the current value and after writing REACTIVE=0 using iowrite32 again i read the value ,Value is geeting changed but interrupt is continuously coming on line.

  • shammi kaplesh said:
    request_threaded_irq(7 , power_isr ,NULL, IRQF_TRIGGER_LOW|IRQF_ONESHOT,
    "power fail" ,NULL);

    this is how i am registering the interrupt handler. with IRQF_ONESHOT it is working only once. it is disabling the interrupt line.

    Isn't that your goal, i.e. to have it run only once instead of constantly?  Please clarify.

  • once power will go then i have to send signal to userspace i have to do some backup stuff in application with 10 sec power backup and do systematic poweroff.if power comes back in between i have to abort the poweroff. But with IRQF_ONESHOT interrupt line is disabled.
    so i need some way to enable it.
  • with this
    request_threaded_irq(7 , power_isr ,NULL, IRQF_TRIGGER_LOW|IRQF_ONESHOT,
    "power fail" ,NULL);
    interrupt line is disabled it will fire interrupt only once. But in between if power back i will abort poweroff but NMI interrupt line is not enabled so it will not work again. Please give some solution to this problem.
  • Good news!  Looking into this a bit deeper, I see the "NMI" name given to this internal signal is deceptive.  I think the external pin name "EXTINTn" is more appropriate.  This signal is routed to the ARM Interrupt Controller (AINTC), same as any other interrupt.  So it is maskable just like any other interrupt...  This is shown in the TRM in Table 6-1 "ARM Cortex-A8 Interrupts" which shows this NMI signal hooked up to interrupt #7 of the Interrupt Controller.

    I've been digging around to find the API to unmask the interrupt though so far haven't found it.  Maybe someone else on this thread can answer or perhaps you might even consider starting a new thread without all the confusion relating to NMI.  It sounds like you are just trying to implement a threaded IRQ.

  • No actually I want to create IRQ that will send signal to userspace when interrupt will come on this line. So i used IRQF_ONESHOT to fire
    interrupt only once,without this my ISR is getting called again and again as it is low level signal. i tried to set the register to disable this line inside ISR.(INTC_MIR_SET0 Register) but still interrupt is coming on this line. Even i tried to unmask this line using  INTC_MIR_CLEAR0 Register.

    This is how i am registering my handler.

    ret = request_irq(7, power_isr,  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                  "Power fail", NULL);

    IRQF_ONESHOT--- disabling the interrupt line.

    INTC_MIR_CLEAR0 -- Enabled the interrupt line in  bottom half.

    But after doing INTC_MIR_CLEAR0 my handler is getting called again and again.