Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp9569961ybi; Wed, 24 Jul 2019 06:24:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqyAoKIr0CKobzBh7XLCU43pyjeh5oI3rKLUwITHC8ZIG0hcNR32lZuSmBqvqHZfmrlkpvD4 X-Received: by 2002:a63:f443:: with SMTP id p3mr37533495pgk.345.1563974687068; Wed, 24 Jul 2019 06:24:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563974687; cv=none; d=google.com; s=arc-20160816; b=Tx/HAshf5XjJ5QcniX1PBmbHtFWBk4eNa3HAAWEvCuVmNC/yRQBlzkIsRHnFnhvRYU 6IxnW4idnZbr/VMHOPUDsFImi2OdXzvWRWRwwosALgLo7dTMl0X438s6JcLbEhmPQ9ff jI0e60sRuBzA7Q/MXw4UO0oFlJJwVhovBYT7ZZXh6Aldfeh5VYglOKOJGMp6v+dshZ4F OB0bhMJq9FFA1OFzrm7gTflvDoWVqeIjepWQW8wZYG3C4vOtCfm14//q6JaQGxp1ZxiC i3dJBcme4/zqTGbm4698Vm8l6Wj684qLlMY8Ii75kp+WB8oV9H5ddfp4ScvOUIRC7NQD ni+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=P9wP60zN8BM9Yp21iOc5XzWcymu3WcdIWgRU47EmTq0=; b=VlzkvchrwAi5P/5PDOOIK9meOpLgkKJkXA9sN/WBeeIBcOMdH1DhsL2E5N1KkSfjFd zMiZINCx53y8qvPnMziC8Ov5PSIiTt4PEMu3E2pRT0AbbPRx4RPMAxfnSnMKiNDEFc74 OnVxMAa0SJPdOloXGfthwuhbqt+AMv7d3UnuL7HVjtuElbnHmn9S7dVKlNtgAEpaI1L4 m7BeyqouguqG3wTQ/ywo/G13oTOpbU1ZoX104x0d/BLAChDv4oKfpi8HQbMG/DsFhFQB D2xHVOnmGaD7Cf1jvRIsfgu52e1a3r4GkRuHyciihFXTthvSmuS4j3hOdNTM7D7Otbkq n0Rw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b="DYgW/+PG"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v14si14108605pgb.375.2019.07.24.06.24.32; Wed, 24 Jul 2019 06:24:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@synopsys.com header.s=mail header.b="DYgW/+PG"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727885AbfGXMG4 (ORCPT + 99 others); Wed, 24 Jul 2019 08:06:56 -0400 Received: from smtprelay-out1.synopsys.com ([198.182.61.142]:47258 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726256AbfGXMG4 (ORCPT ); Wed, 24 Jul 2019 08:06:56 -0400 Received: from mailhost.synopsys.com (mdc-mailhost1.synopsys.com [10.225.0.209]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 22468C0BBF; Wed, 24 Jul 2019 12:06:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1563970015; bh=Ig0atlwmgsMQV1c6ZCNpQe54UzgoUiNk3gRiTOLNySk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DYgW/+PGir4wJeVTED6d027cLJNBKFHIMUF4s8zDniqkNqSyPmFcL6k+fw57rUPKC edLvbWoqSYg0fZO2wnoNAGKs3GUGeLjoPx41H5PcIohEE7jSCZkRJUjW/yC4hsfK68 8K/r4C6c7hJamRGl6iV7kb4coTTHC/zG8ZhNAEIQZBJPuJG0kO2P2DvJX6VSzjdJlt 42l6VHwIACoIZ3eYBWwjcWp2E2yRY/K7ArMxYVHuaGgyJ5QlJnYMfh0LMPN8b3fsNr lDbempoY48jJCR8I/vZCXU6F1kTpgNjXfx2jQXfPXNyb8Z3+67g+KsCiZxaxkt28XJ EWBBJUlkUls2A== Received: from de02arcdev1.internal.synopsys.com (de02arcdev1.internal.synopsys.com [10.225.22.192]) by mailhost.synopsys.com (Postfix) with ESMTP id F3EDFA0057; Wed, 24 Jul 2019 12:06:51 +0000 (UTC) From: Mischa Jonker To: Alexey.Brodkin@synopsys.com, Vineet.Gupta1@synopsys.com, kstewart@linuxfoundation.org, tglx@linutronix.de, robh+dt@kernel.org, linux-snps-arc@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: Mischa Jonker Subject: [PATCH v2 1/3] ARCv2: IDU-intc: Add support for edge-triggered interrupts Date: Wed, 24 Jul 2019 14:04:34 +0200 Message-Id: <20190724120436.8537-1-mischa.jonker@synopsys.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This adds support for an optional extra interrupt cell to specify edge vs level triggered. It is backward compatible with dts files with only one cell, and will default to level-triggered in such a case. Note that I had to make a change to idu_irq_set_affinity as well, as this function was setting the interrupt type to "level" unconditionally, since this was the only type supported previously. Signed-off-by: Mischa Jonker --- arch/arc/kernel/mcip.c | 60 +++++++++++++++++++++++++++++++++++++++++++++----- include/soc/arc/mcip.h | 11 +++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 18b493d..abf9398 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -202,8 +202,8 @@ static void idu_set_dest(unsigned int cmn_irq, unsigned int cpu_mask) __mcip_cmd_data(CMD_IDU_SET_DEST, cmn_irq, cpu_mask); } -static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl, - unsigned int distr) +static void idu_set_mode(unsigned int cmn_irq, bool set_lvl, unsigned int lvl, + bool set_distr, unsigned int distr) { union { unsigned int word; @@ -212,8 +212,11 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl, }; } data; - data.distr = distr; - data.lvl = lvl; + data.word = __mcip_cmd_read(CMD_IDU_READ_MODE, cmn_irq); + if (set_distr) + data.distr = distr; + if (set_lvl) + data.lvl = lvl; __mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word); } @@ -240,6 +243,25 @@ static void idu_irq_unmask(struct irq_data *data) raw_spin_unlock_irqrestore(&mcip_lock, flags); } +static void idu_irq_ack(struct irq_data *data) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&mcip_lock, flags); + __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq); + raw_spin_unlock_irqrestore(&mcip_lock, flags); +} + +static void idu_irq_mask_ack(struct irq_data *data) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&mcip_lock, flags); + __mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1); + __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq); + raw_spin_unlock_irqrestore(&mcip_lock, flags); +} + static int idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, bool force) @@ -263,13 +285,36 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, else distribution_mode = IDU_M_DISTRI_RR; - idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode); + idu_set_mode(data->hwirq, false, 0, true, distribution_mode); raw_spin_unlock_irqrestore(&mcip_lock, flags); return IRQ_SET_MASK_OK; } +static int idu_irq_set_type(struct irq_data *data, u32 type) +{ + unsigned long flags; + + /* + * ARCv2 IDU HW does not support inverse polarity, so these are the + * only interrupt types supported. + */ + if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) + return -EINVAL; + + raw_spin_lock_irqsave(&mcip_lock, flags); + + idu_set_mode(data->hwirq, true, + type & IRQ_TYPE_EDGE_RISING ? IDU_M_TRIG_EDGE : + IDU_M_TRIG_LEVEL, + false, 0); + + raw_spin_unlock_irqrestore(&mcip_lock, flags); + + return 0; +} + static void idu_irq_enable(struct irq_data *data) { /* @@ -289,7 +334,10 @@ static struct irq_chip idu_irq_chip = { .name = "MCIP IDU Intc", .irq_mask = idu_irq_mask, .irq_unmask = idu_irq_unmask, + .irq_ack = idu_irq_ack, + .irq_mask_ack = idu_irq_mask_ack, .irq_enable = idu_irq_enable, + .irq_set_type = idu_irq_set_type, #ifdef CONFIG_SMP .irq_set_affinity = idu_irq_set_affinity, #endif @@ -317,7 +365,7 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t } static const struct irq_domain_ops idu_irq_ops = { - .xlate = irq_domain_xlate_onecell, + .xlate = irq_domain_xlate_onetwocell, .map = idu_irq_map, }; diff --git a/include/soc/arc/mcip.h b/include/soc/arc/mcip.h index 50f49e0..d1a93c7 100644 --- a/include/soc/arc/mcip.h +++ b/include/soc/arc/mcip.h @@ -46,7 +46,9 @@ struct mcip_cmd { #define CMD_IDU_ENABLE 0x71 #define CMD_IDU_DISABLE 0x72 #define CMD_IDU_SET_MODE 0x74 +#define CMD_IDU_READ_MODE 0x75 #define CMD_IDU_SET_DEST 0x76 +#define CMD_IDU_ACK_CIRQ 0x79 #define CMD_IDU_SET_MASK 0x7C #define IDU_M_TRIG_LEVEL 0x0 @@ -119,4 +121,13 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param, __mcip_cmd(cmd, param); } +/* + * Read MCIP register + */ +static inline unsigned int __mcip_cmd_read(unsigned int cmd, unsigned int param) +{ + __mcip_cmd(cmd, param); + return read_aux_reg(ARC_REG_MCIP_READBACK); +} + #endif -- 2.8.3