From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751725AbdFEIX5 (ORCPT ); Mon, 5 Jun 2017 04:23:57 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:50068 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751664AbdFEIXz (ORCPT ); Mon, 5 Jun 2017 04:23:55 -0400 Date: Mon, 5 Jun 2017 10:23:48 +0200 (CEST) From: Thomas Gleixner To: Mason cc: Marc Zyngier , Jason Cooper , Mark Rutland , Arnd Bergmann , Linux ARM , LKML Subject: Re: Design of interrupt controller driver In-Reply-To: <6e4da485-42cc-9b70-1b4a-9729f646e014@free.fr> Message-ID: References: <8bce8bdd-5801-f0c3-ada3-e1c68acc8913@free.fr> <025780ef-06e6-1e85-58da-4ce8f6c93536@free.fr> <6e4da485-42cc-9b70-1b4a-9729f646e014@free.fr> User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 5 Jun 2017, Mason wrote: > On 04/06/2017 22:13, Thomas Gleixner wrote: > > When you configure the interrupt as edge then you cannot share it. No > > matter whether it stays high or not. > > Could you explain why? (I must be missing something.) Device A Device B Combined Output Edge detection Low Low 0 N Low -> High Low 1 Y -> Interrupt handled High Low -> High 1 N When the A line stays high, which it does, then the edge detector will not see a transition for B and you lose an interrupt. > > The only way to share it is, to configure it as level interrupt. But that > > requires that you can disable the interrupt at the DMA device level once it > > triggered. Otherwise you get an interrupt storm. > > I'm not sure what you mean with "disable the interrupt at the > DMA device level". The interrupt can be masked at the system > interrupt controller (i.e. before sharing the interrupt > signal). The DMA engine just outputs 0 when busy, 1 when idle. Sharing level interrupts requires a way to disable the device (in your case the DMA engine) interrupt output in order to prevent irq storms. Pseudo code (locking etc. omitted): irq_handler_devA() { if (!interrupt_active(devA)) return IRQ_NONE; handle_device_irq(); if (no_more_outstanding_requests(devA)) { reg = readl(devA->irq_control_reg); reg &= ~DEV_IRQ_ENABLE; writel(devA->irq_control_reg, reg); } return IRQ_HANDLED; } queue_reqeust_devA() { if (no_more_outstanding_requests(devA)) { queue_request(); start_engine(); /* Reenable interrupt at device level */ reg = readl(devA->irq_control_reg); reg |= DEV_IRQ_ENABLE; writel(devA->irq_control_reg, reg); } else { queue_request(); } } You get the idea. Thanks, tglx