From patchwork Tue May 2 13:55:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98443 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885192qgf; Tue, 2 May 2017 06:56:15 -0700 (PDT) X-Received: by 10.84.224.10 with SMTP id r10mr17854027plj.25.1493733375718; Tue, 02 May 2017 06:56:15 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e1si16905527pld.32.2017.05.02.06.56.15; Tue, 02 May 2017 06:56:15 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751438AbdEBN4E (ORCPT + 25 others); Tue, 2 May 2017 09:56:04 -0400 Received: from foss.arm.com ([217.140.101.70]:44776 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751247AbdEBN4B (ORCPT ); Tue, 2 May 2017 09:56:01 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5271015A1; Tue, 2 May 2017 06:56:01 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 6F7203F23B; Tue, 2 May 2017 06:56:00 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar Subject: [PATCH 1/6] mailbox: arm_mhu: reorder header inclusion and drop unneeded ones Date: Tue, 2 May 2017 14:55:48 +0100 Message-Id: <1493733353-25812-2-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch just re-orders some of the headers includes and also drop the ones that are unnecessary. Cc: Alexey Klimov Cc: Jassi Brar Signed-off-by: Sudeep Holla --- drivers/mailbox/arm_mhu.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) -- 2.7.4 diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c index 99befa76e37c..be0f293a9457 100644 --- a/drivers/mailbox/arm_mhu.c +++ b/drivers/mailbox/arm_mhu.c @@ -13,16 +13,13 @@ * GNU General Public License for more details. */ -#include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include #include +#include #define INTR_STAT_OFS 0x0 #define INTR_SET_OFS 0x8 From patchwork Tue May 2 13:55:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98448 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885643qgf; Tue, 2 May 2017 06:57:30 -0700 (PDT) X-Received: by 10.84.222.129 with SMTP id x1mr41951235pls.44.1493733450148; Tue, 02 May 2017 06:57:30 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x3si3551261pls.24.2017.05.02.06.57.27; Tue, 02 May 2017 06:57:30 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751758AbdEBN5E (ORCPT + 25 others); Tue, 2 May 2017 09:57:04 -0400 Received: from foss.arm.com ([217.140.101.70]:44788 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751022AbdEBN4D (ORCPT ); Tue, 2 May 2017 09:56:03 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B60EB2B; Tue, 2 May 2017 06:56:02 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8E1EF3F23B; Tue, 2 May 2017 06:56:01 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar , Rob Herring , devicetree@vger.kernel.org Subject: [PATCH 2/6] Documentation: devicetree: add bindings to support ARM MHU subchannels Date: Tue, 2 May 2017 14:55:49 +0100 Message-Id: <1493733353-25812-3-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ARM MHU has mechanism to assert interrupt signals to facilitate inter-processor message based communication. It drives the signal using a 32-bit register, with all 32-bits logically ORed together. It also enables software to set, clear and check the status of each of the bits of this register independently. Each bit of the register can be associated with a type of event that can contribute to raising the interrupt thereby allowing it to be used as independent subchannels. Since the first version of this binding can't support sub-channels, this patch extends the existing binding to support them. Cc: Alexey Klimov Cc: Jassi Brar Cc: Rob Herring Cc: devicetree@vger.kernel.org Signed-off-by: Sudeep Holla --- .../devicetree/bindings/mailbox/arm-mhu.txt | 44 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) -- 2.7.4 diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt index 4971f03f0b33..86a66f7918e2 100644 --- a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt +++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt @@ -10,21 +10,40 @@ STAT register and the remote clears it after having read the data. The last channel is specified to be a 'Secure' resource, hence can't be used by Linux running NS. +The MHU drives the interrupt signal using a 32-bit register, with all +32-bits logically ORed together. It provides a set of registers to +enable software to set, clear and check the status of each of the bits +of this register independently. The use of 32 bits per interrupt line +enables software to provide more information about the source of the +interrupt. For example, each bit of the register can be associated with +a type of event that can contribute to raising the interrupt. + Mailbox Device Node: ==================== Required properties: -------------------- -- compatible: Shall be "arm,mhu" & "arm,primecell" +- compatible: Shall be "arm,primecell" and one of the below: + "arm,mhu" - if the controller doesn't support + subchannels + "arm,mhu-v2" - if the controller supports subchannels - reg: Contains the mailbox register address range (base address and length) -- #mbox-cells Shall be 1 - the index of the channel needed. +- #mbox-cells Shall be 1 - the index of the channel needed when + compatible is "arm,mhu" + Shall be 2 - the index of the channel needed, and + the index of the subchannel with the channel when + compatible is "arm,mhu-v2" - interrupts: Contains the interrupt information corresponding to - each of the 3 links of MHU. + each of the 3 physical channels of MHU namely low + priority non-secure, high priority non-secure and + secure channels. Example: -------- +1. Controller which doesn't support subchannels + mhu: mailbox@2b1f0000 { #mbox-cells = <1>; compatible = "arm,mhu", "arm,primecell"; @@ -41,3 +60,22 @@ used by Linux running NS. reg = <0 0x2e000000 0x4000>; mboxes = <&mhu 1>; /* HP-NonSecure */ }; + +2. Controller which supports subchannels + + mhu: mailbox@2b1f0000 { + #mbox-cells = <2>; + compatible = "arm,mhu-v2", "arm,primecell"; + reg = <0 0x2b1f0000 0x1000>; + interrupts = <0 36 4>, /* LP-NonSecure */ + <0 35 4>, /* HP-NonSecure */ + <0 37 4>; /* Secure */ + clocks = <&clock 0 2 1>; + clock-names = "apb_pclk"; + }; + + mhu_client: scb@2e000000 { + compatible = "arm,scpi"; + reg = <0 0x2e000000 0x200>; + mboxes = <&mhu 1 4>; /* HP-NonSecure 5th sub-channel */ + }; From patchwork Tue May 2 13:55:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98446 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885289qgf; Tue, 2 May 2017 06:56:31 -0700 (PDT) X-Received: by 10.98.131.197 with SMTP id h188mr31705752pfe.99.1493733391085; Tue, 02 May 2017 06:56:31 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 33si6180111plv.44.2017.05.02.06.56.30; Tue, 02 May 2017 06:56:31 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751607AbdEBN4L (ORCPT + 25 others); Tue, 2 May 2017 09:56:11 -0400 Received: from foss.arm.com ([217.140.101.70]:44798 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751425AbdEBN4E (ORCPT ); Tue, 2 May 2017 09:56:04 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D564615A2; Tue, 2 May 2017 06:56:03 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F1F153F23B; Tue, 2 May 2017 06:56:02 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar Subject: [PATCH 3/6] mailbox: arm_mhu: migrate to threaded irq handler Date: Tue, 2 May 2017 14:55:50 +0100 Message-Id: <1493733353-25812-4-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In preparation to introduce support for subchannels which require the interrupt handlers to be threaded, this patch moves the existing interrupt handler to threaded handler. Also it moves out the registering and freeing of the handlers from the mailbox startup and shutdown methods. This also is required to support sub-channels. Cc: Alexey Klimov Cc: Jassi Brar Signed-off-by: Sudeep Holla --- drivers/mailbox/arm_mhu.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) -- 2.7.4 diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c index be0f293a9457..ebe17c097f43 100644 --- a/drivers/mailbox/arm_mhu.c +++ b/drivers/mailbox/arm_mhu.c @@ -84,27 +84,15 @@ static int mhu_startup(struct mbox_chan *chan) { struct mhu_link *mlink = chan->con_priv; u32 val; - int ret; val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS); writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS); - ret = request_irq(mlink->irq, mhu_rx_interrupt, - IRQF_SHARED, "mhu_link", chan); - if (ret) { - dev_err(chan->mbox->dev, - "Unable to acquire IRQ %d\n", mlink->irq); - return ret; - } - return 0; } static void mhu_shutdown(struct mbox_chan *chan) { - struct mhu_link *mlink = chan->con_priv; - - free_irq(mlink->irq, chan); } static const struct mbox_chan_ops mhu_ops = { @@ -132,13 +120,6 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(mhu->base); } - for (i = 0; i < MHU_CHANS; i++) { - mhu->chan[i].con_priv = &mhu->mlink[i]; - mhu->mlink[i].irq = adev->irq[i]; - mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i]; - mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET; - } - mhu->mbox.dev = dev; mhu->mbox.chans = &mhu->chan[0]; mhu->mbox.num_chans = MHU_CHANS; @@ -155,6 +136,28 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) return err; } + for (i = 0; i < MHU_CHANS; i++) { + int irq = mhu->mlink[i].irq = adev->irq[i]; + + if (irq <= 0) { + dev_dbg(dev, "No IRQ found for Channel %d\n", i); + continue; + } + + mhu->chan[i].con_priv = &mhu->mlink[i]; + mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i]; + mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET; + + err = devm_request_threaded_irq(dev, irq, NULL, + mhu_rx_interrupt, IRQF_ONESHOT, + "mhu_link", &mhu->chan[i]); + if (err) { + dev_err(dev, "Can't claim IRQ %d\n", irq); + mbox_controller_unregister(&mhu->mbox); + return err; + } + } + dev_info(dev, "ARM MHU Mailbox registered\n"); return 0; } From patchwork Tue May 2 13:55:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98444 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885196qgf; Tue, 2 May 2017 06:56:16 -0700 (PDT) X-Received: by 10.98.59.2 with SMTP id i2mr1631914pfa.50.1493733376114; Tue, 02 May 2017 06:56:16 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e1si16905527pld.32.2017.05.02.06.56.15; Tue, 02 May 2017 06:56:16 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751565AbdEBN4H (ORCPT + 25 others); Tue, 2 May 2017 09:56:07 -0400 Received: from foss.arm.com ([217.140.101.70]:44802 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751176AbdEBN4F (ORCPT ); Tue, 2 May 2017 09:56:05 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0147115A1; Tue, 2 May 2017 06:56:05 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1CFAF3F23B; Tue, 2 May 2017 06:56:03 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar Subject: [PATCH 4/6] mailbox: arm_mhu: re-factor data structure to add subchannel support Date: Tue, 2 May 2017 14:55:51 +0100 Message-Id: <1493733353-25812-5-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to support subchannels, we need a bit of reword around data structures that are per-channel. Since the number of subchannels are not fixed though restricted to maximum of 20, the channel assignment and initialization is move to xlate function. This patch also adds the platform data for the existing support of one channel per physical channel. Cc: Alexey Klimov Cc: Jassi Brar Signed-off-by: Sudeep Holla --- drivers/mailbox/arm_mhu.c | 208 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 186 insertions(+), 22 deletions(-) -- 2.7.4 diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c index ebe17c097f43..4e0f690b97fd 100644 --- a/drivers/mailbox/arm_mhu.c +++ b/drivers/mailbox/arm_mhu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #define INTR_STAT_OFS 0x0 #define INTR_SET_OFS 0x8 @@ -30,7 +32,8 @@ #define MHU_SEC_OFFSET 0x200 #define TX_REG_OFFSET 0x100 -#define MHU_CHANS 3 +#define MHU_NUM_PCHANS 3 /* Secure, Non-Secure High and Low Priority */ +#define MHU_CHAN_MAX 20 /* Max channels to save on unused RAM */ struct mhu_link { unsigned irq; @@ -40,53 +43,175 @@ struct mhu_link { struct arm_mhu { void __iomem *base; - struct mhu_link mlink[MHU_CHANS]; - struct mbox_chan chan[MHU_CHANS]; + struct mhu_link mlink[MHU_NUM_PCHANS]; struct mbox_controller mbox; + struct device *dev; }; +/** + * ARM MHU Mailbox platform specific configuration + * + * @num_pchans: Maximum number of physical channels + * @num_subchans: Maximum number of sub-channels per physical channel + */ +struct mhu_mbox_pdata { + unsigned int num_pchans; + unsigned int num_subchans; + bool support_subchans; +}; + +/** + * ARM MHU Mailbox allocated channel information + * + * @mhu: Pointer to parent mailbox device + * @pchan: Physical channel within which this sub-channel resides in + * @channel: Sub-channel number pertaining to this container + */ +struct mhu_channel { + struct arm_mhu *mhu; + unsigned int pchan; + unsigned int subchan; +}; + +static inline struct mbox_chan * +mhu_mbox_to_channel(struct mbox_controller *mbox, + unsigned int pchan, unsigned int subchan) +{ + int i; + struct mhu_channel *chan_info; + + for (i = 0; i < mbox->num_chans; i++) { + chan_info = mbox->chans[i].con_priv; + if (chan_info && chan_info->pchan == pchan && + chan_info->subchan == subchan) + return &mbox->chans[i]; + } + + dev_err(mbox->dev, + "Channel not registered: physical channel: %d subchan: %d\n", + pchan, subchan); + + return NULL; +} + +static unsigned int mhu_mbox_irq_to_pchan_num(struct arm_mhu *mhu, int irq) +{ + unsigned int pchan; + struct mhu_mbox_pdata *pdata = dev_get_platdata(mhu->dev); + + for (pchan = 0; pchan < pdata->num_pchans; pchan++) + if (mhu->mlink[pchan].irq == irq) + break; + return pchan; +} + +static struct mbox_chan *mhu_mbox_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *spec) +{ + struct arm_mhu *mhu = dev_get_drvdata(mbox->dev); + struct mhu_mbox_pdata *pdata = dev_get_platdata(mhu->dev); + struct mhu_channel *chan_info; + struct mbox_chan *chan = NULL; + unsigned int pchan = spec->args[0]; + unsigned int subchan = pdata->support_subchans ? spec->args[1] : 0; + int i; + + /* Bounds checking */ + if (pchan >= pdata->num_pchans || subchan >= pdata->num_subchans) { + dev_err(mbox->dev, + "Invalid channel requested pchan: %d subchan: %d\n", + pchan, subchan); + return ERR_PTR(-EINVAL); + } + + for (i = 0; i < mbox->num_chans; i++) { + chan_info = mbox->chans[i].con_priv; + + /* Is requested channel free? */ + if (chan_info && + mbox->dev == chan_info->mhu->dev && + pchan == chan_info->pchan && + subchan == chan_info->subchan) { + dev_err(mbox->dev, "Channel in use\n"); + return ERR_PTR(-EBUSY); + } + + /* + * Find the first free slot, then continue checking + * to see if requested channel is in use + */ + if (!chan && !chan_info) + chan = &mbox->chans[i]; + } + + if (!chan) { + dev_err(mbox->dev, "No free channels left\n"); + return ERR_PTR(-EBUSY); + } + + chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL); + if (!chan_info) + return ERR_PTR(-ENOMEM); + + chan_info->mhu = mhu; + chan_info->pchan = pchan; + chan_info->subchan = subchan; + + chan->con_priv = chan_info; + + dev_dbg(mbox->dev, "mbox: created channel - physical: %d sub: %d\n", + pchan, subchan); + + return chan; +} + static irqreturn_t mhu_rx_interrupt(int irq, void *p) { - struct mbox_chan *chan = p; - struct mhu_link *mlink = chan->con_priv; + struct arm_mhu *mhu = p; + unsigned int pchan = mhu_mbox_irq_to_pchan_num(mhu, irq); + struct mbox_chan *chan = mhu_mbox_to_channel(&mhu->mbox, pchan, 0); + void __iomem *base = mhu->mlink[pchan].rx_reg; u32 val; - val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS); + val = readl_relaxed(base + INTR_STAT_OFS); if (!val) return IRQ_NONE; mbox_chan_received_data(chan, (void *)&val); - writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS); + writel_relaxed(val, base + INTR_CLR_OFS); return IRQ_HANDLED; } static bool mhu_last_tx_done(struct mbox_chan *chan) { - struct mhu_link *mlink = chan->con_priv; - u32 val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS); + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg; + u32 val = readl_relaxed(base + INTR_STAT_OFS); return (val == 0); } static int mhu_send_data(struct mbox_chan *chan, void *data) { - struct mhu_link *mlink = chan->con_priv; + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg; u32 *arg = data; - writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS); + writel_relaxed(*arg, base + INTR_SET_OFS); return 0; } static int mhu_startup(struct mbox_chan *chan) { - struct mhu_link *mlink = chan->con_priv; + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg; u32 val; - val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS); - writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS); + val = readl_relaxed(base + INTR_STAT_OFS); + writel_relaxed(val, base + INTR_CLR_OFS); return 0; } @@ -102,14 +227,46 @@ static const struct mbox_chan_ops mhu_ops = { .last_tx_done = mhu_last_tx_done, }; +static const struct mhu_mbox_pdata arm_mhu_pdata = { + .num_pchans = 3, + .num_subchans = 1, + .support_subchans = false, +}; + +static const struct of_device_id mhu_mbox_match[] = { + { .compatible = "arm,mhu", .data = (void *)&arm_mhu_pdata }, + {} +}; + +MODULE_DEVICE_TABLE(of, mhu_mbox_match); + static int mhu_probe(struct amba_device *adev, const struct amba_id *id) { - int i, err; + int i, err, max_chans; struct arm_mhu *mhu; + struct mbox_chan *chans; + struct mhu_mbox_pdata *pdata; + const struct of_device_id *match; struct device *dev = &adev->dev; - int mhu_reg[MHU_CHANS] = {MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET}; + int mhu_reg[MHU_NUM_PCHANS] = { + MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET, + }; + + match = of_match_device(mhu_mbox_match, dev); + if (!match) { + dev_err(dev, "No configuration found\n"); + return -ENODEV; + } + pdata = (struct mhu_mbox_pdata *)match->data; + + if (pdata->num_pchans > MHU_NUM_PCHANS) { + dev_err(dev, "Number of physical channel can't exceed %d\n", + MHU_NUM_PCHANS); + return -EINVAL; + } + + max_chans = pdata->support_subchans ? MHU_CHAN_MAX : MHU_NUM_PCHANS; - /* Allocate memory for device */ mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL); if (!mhu) return -ENOMEM; @@ -120,14 +277,22 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(mhu->base); } + chans = devm_kcalloc(dev, max_chans, sizeof(*chans), GFP_KERNEL); + if (!chans) + return -ENOMEM; + + dev->platform_data = pdata; + + mhu->dev = dev; mhu->mbox.dev = dev; - mhu->mbox.chans = &mhu->chan[0]; - mhu->mbox.num_chans = MHU_CHANS; + mhu->mbox.chans = chans; + mhu->mbox.num_chans = max_chans; mhu->mbox.ops = &mhu_ops; mhu->mbox.txdone_irq = false; mhu->mbox.txdone_poll = true; mhu->mbox.txpoll_period = 1; + mhu->mbox.of_xlate = mhu_mbox_xlate; amba_set_drvdata(adev, mhu); err = mbox_controller_register(&mhu->mbox); @@ -136,7 +301,7 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) return err; } - for (i = 0; i < MHU_CHANS; i++) { + for (i = 0; i < pdata->num_pchans; i++) { int irq = mhu->mlink[i].irq = adev->irq[i]; if (irq <= 0) { @@ -144,13 +309,12 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) continue; } - mhu->chan[i].con_priv = &mhu->mlink[i]; mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i]; mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET; err = devm_request_threaded_irq(dev, irq, NULL, mhu_rx_interrupt, IRQF_ONESHOT, - "mhu_link", &mhu->chan[i]); + "mhu_link", mhu); if (err) { dev_err(dev, "Can't claim IRQ %d\n", irq); mbox_controller_unregister(&mhu->mbox); From patchwork Tue May 2 13:55:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98447 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885456qgf; Tue, 2 May 2017 06:56:59 -0700 (PDT) X-Received: by 10.99.104.9 with SMTP id d9mr33493308pgc.27.1493733419098; Tue, 02 May 2017 06:56:59 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l2si5406930pln.183.2017.05.02.06.56.58; Tue, 02 May 2017 06:56:59 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751697AbdEBN4q (ORCPT + 25 others); Tue, 2 May 2017 09:56:46 -0400 Received: from foss.arm.com ([217.140.101.70]:44806 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751442AbdEBN4G (ORCPT ); Tue, 2 May 2017 09:56:06 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 20CDD2B; Tue, 2 May 2017 06:56:06 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3CDBF3F23B; Tue, 2 May 2017 06:56:05 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar Subject: [PATCH 5/6] mailbox: arm_mhu: add full support for sub-channels Date: Tue, 2 May 2017 14:55:52 +0100 Message-Id: <1493733353-25812-6-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We now have the basic infrastructure and binding to support subchannels on ARM MHU controller. This patch adds all the necessary mailbox operations to add support for the sub-channels. Maximum of 32 subchannels are supported on each physical channel, however the total number of subchannels is restricted to 20 in order to save memory. It can increased if required in future. Cc: Alexey Klimov Cc: Jassi Brar Signed-off-by: Sudeep Holla --- drivers/mailbox/arm_mhu.c | 127 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 4 deletions(-) -- 2.7.4 diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c index 4e0f690b97fd..0f5ab2204649 100644 --- a/drivers/mailbox/arm_mhu.c +++ b/drivers/mailbox/arm_mhu.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,14 @@ mhu_mbox_to_channel(struct mbox_controller *mbox, return NULL; } +static void mhu_mbox_clear_irq(struct mbox_chan *chan) +{ + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].rx_reg; + + writel_relaxed(BIT(chan_info->subchan), base + INTR_CLR_OFS); +} + static unsigned int mhu_mbox_irq_to_pchan_num(struct arm_mhu *mhu, int irq) { unsigned int pchan; @@ -105,6 +114,95 @@ static unsigned int mhu_mbox_irq_to_pchan_num(struct arm_mhu *mhu, int irq) return pchan; } +static struct mbox_chan *mhu_mbox_irq_to_channel(struct arm_mhu *mhu, + unsigned int pchan) +{ + unsigned long bits; + unsigned int subchan; + struct mbox_chan *chan = NULL; + struct mbox_controller *mbox = &mhu->mbox; + void __iomem *base = mhu->mlink[pchan].rx_reg; + + bits = readl_relaxed(base + INTR_STAT_OFS); + if (!bits) + /* No IRQs fired in specified physical channel */ + return NULL; + + /* An IRQ has fired, find the associated channel */ + for (subchan = 0; bits; subchan++) { + if (!test_and_clear_bit(subchan, &bits)) + continue; + + chan = mhu_mbox_to_channel(mbox, pchan, subchan); + if (chan) + break; + } + + return chan; +} + +static irqreturn_t mhu_mbox_thread_handler(int irq, void *data) +{ + struct mbox_chan *chan; + struct arm_mhu *mhu = data; + unsigned int pchan = mhu_mbox_irq_to_pchan_num(mhu, irq); + + while (NULL != (chan = mhu_mbox_irq_to_channel(mhu, pchan))) { + mbox_chan_received_data(chan, NULL); + mhu_mbox_clear_irq(chan); + } + + return IRQ_HANDLED; +} + +static bool mhu_subchan_last_tx_done(struct mbox_chan *chan) +{ + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg; + + if (readl_relaxed(base + INTR_STAT_OFS) & BIT(chan_info->subchan)) + return false; + + return true; +} + +static int mhu_subchan_send_data(struct mbox_chan *chan, void *data) +{ + struct mhu_channel *chan_info = chan->con_priv; + void __iomem *base = chan_info->mhu->mlink[chan_info->pchan].tx_reg; + + /* Send event to co-processor */ + writel_relaxed(BIT(chan_info->subchan), base + INTR_SET_OFS); + + return 0; +} + +static int mhu_subchan_startup(struct mbox_chan *chan) +{ + mhu_mbox_clear_irq(chan); + return 0; +} + +static void mhu_subchan_shutdown(struct mbox_chan *chan) +{ + struct mhu_channel *chan_info = chan->con_priv; + struct mbox_controller *mbox = &chan_info->mhu->mbox; + int i; + + for (i = 0; i < mbox->num_chans; i++) + if (chan == &mbox->chans[i]) + break; + + if (mbox->num_chans == i) { + dev_warn(mbox->dev, "Request to free non-existent channel\n"); + return; + } + + /* Reset channel */ + mhu_mbox_clear_irq(chan); + chan->con_priv = NULL; +} + static struct mbox_chan *mhu_mbox_xlate(struct mbox_controller *mbox, const struct of_phandle_args *spec) { @@ -227,14 +325,28 @@ static const struct mbox_chan_ops mhu_ops = { .last_tx_done = mhu_last_tx_done, }; +static const struct mbox_chan_ops mhu_subchan_ops = { + .send_data = mhu_subchan_send_data, + .startup = mhu_subchan_startup, + .shutdown = mhu_subchan_shutdown, + .last_tx_done = mhu_subchan_last_tx_done, +}; + static const struct mhu_mbox_pdata arm_mhu_pdata = { .num_pchans = 3, .num_subchans = 1, .support_subchans = false, }; +static const struct mhu_mbox_pdata arm_mhu_v2_pdata = { + .num_pchans = 2, /* Secure can't be used */ + .num_subchans = 32, + .support_subchans = true, +}; + static const struct of_device_id mhu_mbox_match[] = { { .compatible = "arm,mhu", .data = (void *)&arm_mhu_pdata }, + { .compatible = "arm,mhu-v2", .data = (void *)&arm_mhu_v2_pdata }, {} }; @@ -243,6 +355,7 @@ MODULE_DEVICE_TABLE(of, mhu_mbox_match); static int mhu_probe(struct amba_device *adev, const struct amba_id *id) { int i, err, max_chans; + irq_handler_t handler; struct arm_mhu *mhu; struct mbox_chan *chans; struct mhu_mbox_pdata *pdata; @@ -287,7 +400,6 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) mhu->mbox.dev = dev; mhu->mbox.chans = chans; mhu->mbox.num_chans = max_chans; - mhu->mbox.ops = &mhu_ops; mhu->mbox.txdone_irq = false; mhu->mbox.txdone_poll = true; mhu->mbox.txpoll_period = 1; @@ -295,6 +407,14 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) mhu->mbox.of_xlate = mhu_mbox_xlate; amba_set_drvdata(adev, mhu); + if (pdata->support_subchans) { + mhu->mbox.ops = &mhu_subchan_ops; + handler = mhu_mbox_thread_handler; + } else { + mhu->mbox.ops = &mhu_ops; + handler = mhu_rx_interrupt; + } + err = mbox_controller_register(&mhu->mbox); if (err) { dev_err(dev, "Failed to register mailboxes %d\n", err); @@ -312,9 +432,8 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i]; mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET; - err = devm_request_threaded_irq(dev, irq, NULL, - mhu_rx_interrupt, IRQF_ONESHOT, - "mhu_link", mhu); + err = devm_request_threaded_irq(dev, irq, NULL, handler, + IRQF_ONESHOT, "mhu_link", mhu); if (err) { dev_err(dev, "Can't claim IRQ %d\n", irq); mbox_controller_unregister(&mhu->mbox); From patchwork Tue May 2 13:55:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 98445 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1885280qgf; Tue, 2 May 2017 06:56:30 -0700 (PDT) X-Received: by 10.98.211.27 with SMTP id q27mr32752726pfg.126.1493733390639; Tue, 02 May 2017 06:56:30 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 33si6180111plv.44.2017.05.02.06.56.29; Tue, 02 May 2017 06:56:30 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751637AbdEBN4P (ORCPT + 25 others); Tue, 2 May 2017 09:56:15 -0400 Received: from foss.arm.com ([217.140.101.70]:44808 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751526AbdEBN4H (ORCPT ); Tue, 2 May 2017 09:56:07 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4100415A2; Tue, 2 May 2017 06:56:07 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5D18C3F23B; Tue, 2 May 2017 06:56:06 -0700 (PDT) From: Sudeep Holla To: linux-kernel@vger.kernel.org, Jassi Brar Cc: Sudeep Holla , Alexey Klimov , Jassi Brar Subject: [PATCH 6/6] mailbox: arm_mhu: add name support to record mbox-name Date: Tue, 2 May 2017 14:55:53 +0100 Message-Id: <1493733353-25812-7-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> References: <1493733353-25812-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It's sometimes useful to identify the mailbox controller with the name as specified in the devicetree via mbox-name property especially in a system with multiple controllers. This patch adds support to read and record the mailbox controller name. Cc: Alexey Klimov Cc: Jassi Brar Signed-off-by: Sudeep Holla --- drivers/mailbox/arm_mhu.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) -- 2.7.4 diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c index 0f5ab2204649..9aa623a3aa9a 100644 --- a/drivers/mailbox/arm_mhu.c +++ b/drivers/mailbox/arm_mhu.c @@ -47,6 +47,7 @@ struct arm_mhu { struct mhu_link mlink[MHU_NUM_PCHANS]; struct mbox_controller mbox; struct device *dev; + const char *name; }; /** @@ -257,8 +258,8 @@ static struct mbox_chan *mhu_mbox_xlate(struct mbox_controller *mbox, chan->con_priv = chan_info; - dev_dbg(mbox->dev, "mbox: created channel - physical: %d sub: %d\n", - pchan, subchan); + dev_dbg(mbox->dev, "mbox: %s, created channel - physical: %d sub: %d\n", + mhu->name, pchan, subchan); return chan; } @@ -361,6 +362,7 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) struct mhu_mbox_pdata *pdata; const struct of_device_id *match; struct device *dev = &adev->dev; + struct device_node *np = dev->of_node; int mhu_reg[MHU_NUM_PCHANS] = { MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET, }; @@ -390,6 +392,10 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(mhu->base); } + err = of_property_read_string(np, "mbox-name", &mhu->name); + if (err) + mhu->name = np->full_name; + chans = devm_kcalloc(dev, max_chans, sizeof(*chans), GFP_KERNEL); if (!chans) return -ENOMEM; @@ -441,7 +447,7 @@ static int mhu_probe(struct amba_device *adev, const struct amba_id *id) } } - dev_info(dev, "ARM MHU Mailbox registered\n"); + dev_info(dev, "%s mailbox registered\n", mhu->name); return 0; }