From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B683FC433EF for ; Mon, 28 Feb 2022 12:44:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236621AbiB1Mo4 (ORCPT ); Mon, 28 Feb 2022 07:44:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236599AbiB1Mom (ORCPT ); Mon, 28 Feb 2022 07:44:42 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04AF847548 for ; Mon, 28 Feb 2022 04:44:02 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id g1so11066455pfv.1 for ; Mon, 28 Feb 2022 04:44:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LWisg6Oh4GHR/KswpTeQPwr12khSI6Ztj7YPF2Wfszg=; b=qDj++Gwu/eEmp4bsP/+3bcnFlobpxn6RDmubKL2qGHAOl6r/F2Pkd/2ynCN7nKVazW UyKF2hUaVknYV8Y/e5JVOXyGgVnOa5+YwUu6qpLHuuuaHlQmo3701W9NuNMJbPoW+ojj Wu8k/aJuc0HKP0C16YHrOFE9qsdBKXiEj+Jb1ihpYbI/+r9/bJE4ENH7O7p2yt8bkqNB p38oINaJc6rqfFbqi2Ta4zAiZ7L8h6aNnqf6ra0kXVPAhsWVyJRJWj0h/1Aiv3ysi/4m PtH03h9MOqq3BYmv0hiNGTWcGj3taADffjbJ+QUklZ90ClyyRzIVNPloYhRpTSA/Njkx kSrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LWisg6Oh4GHR/KswpTeQPwr12khSI6Ztj7YPF2Wfszg=; b=cVFQiAP0BGcTz6hg4d0OTDR+VK4HSr2y2PsF8rIYS+gCNiVN/cwB/8Wpbdtami0r59 p0xps/F/W6jtN4EDwGn3STU9T7v5abyyie2oMZwVxCroIA0BYKNOjOyihpBfMv2BI1mD qN/sfDjlXfZxbo4mV2HxAlfy4fJV2EldEBTiXwjtLT3OFHiJEEICDtsI2895NXpbKM0b gv3WfkkcEqWBNeINeYvrKsqTq3OE/IDs1tmaI5vWKA3nvvlzP9UNYyDsTdtgqlTXA/9q z9o6iJ3iU3flYCXbcArF0A8OWPXYXYmq86hosvwA72aFWDABGeBTUYkyzrnONVWGini/ TgQw== X-Gm-Message-State: AOAM533Fl2LL63zomm2PztqJHEPjikme+vEEp8Ct4AY2pedXSD+/5JRM gJ6ufMVOCKlewuk1lO2xJsFr X-Google-Smtp-Source: ABdhPJzKALtNtDDKSCZIDUXyMPg2/CMPUVBFtex+Uxa8tG1IHypCujeOrqq3UuuIi/ORjx7A14s2jQ== X-Received: by 2002:a62:ab09:0:b0:4e0:d967:318f with SMTP id p9-20020a62ab09000000b004e0d967318fmr21755203pff.86.1646052242367; Mon, 28 Feb 2022 04:44:02 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.43.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:02 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Paul Davey , Manivannan Sadhasivam , Hemant Kumar , stable@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH v4 01/27] bus: mhi: Fix pm_state conversion to string Date: Mon, 28 Feb 2022 18:13:18 +0530 Message-Id: <20220228124344.77359-2-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Paul Davey On big endian architectures the mhi debugfs files which report pm state give "Invalid State" for all states. This is caused by using find_last_bit which takes an unsigned long* while the state is passed in as an enum mhi_pm_state which will be of int size. Fix by using __fls to pass the value of state instead of find_last_bit. Also the current API expects "mhi_pm_state" enumerator as the function argument but the function only works with bitmasks. So as Alex suggested, let's change the argument to u32 to avoid confusion. Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") Signed-off-by: Paul Davey Reviewed-by: Manivannan Sadhasivam Reviewed-by: Hemant Kumar Cc: stable@vger.kernel.org [mani: changed the function argument to u32] Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/core/init.c | 10 ++++++---- drivers/bus/mhi/core/internal.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 046f407dc5d6..09394a1c29ec 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -77,12 +77,14 @@ static const char * const mhi_pm_state_str[] =3D { [MHI_PM_STATE_LD_ERR_FATAL_DETECT] =3D "Linkdown or Error Fatal Detect", }; =20 -const char *to_mhi_pm_state_str(enum mhi_pm_state state) +const char *to_mhi_pm_state_str(u32 state) { - unsigned long pm_state =3D state; - int index =3D find_last_bit(&pm_state, 32); + int index; =20 - if (index >=3D ARRAY_SIZE(mhi_pm_state_str)) + if (state) + index =3D __fls(state); + + if (!state || index >=3D ARRAY_SIZE(mhi_pm_state_str)) return "Invalid State"; =20 return mhi_pm_state_str[index]; diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/interna= l.h index e2e10474a9d9..3508cbbf555d 100644 --- a/drivers/bus/mhi/core/internal.h +++ b/drivers/bus/mhi/core/internal.h @@ -622,7 +622,7 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cnt= rl, enum mhi_pm_state __must_check mhi_tryset_pm_state( struct mhi_controller *mhi_cntrl, enum mhi_pm_state state); -const char *to_mhi_pm_state_str(enum mhi_pm_state state); +const char *to_mhi_pm_state_str(u32 state); int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum dev_st_transition state); void mhi_pm_st_worker(struct work_struct *work); --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 360A3C433EF for ; Mon, 28 Feb 2022 12:44:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236658AbiB1MpJ (ORCPT ); Mon, 28 Feb 2022 07:45:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236635AbiB1Mo7 (ORCPT ); Mon, 28 Feb 2022 07:44:59 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D615A49C9C for ; Mon, 28 Feb 2022 04:44:08 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id 12so11303938pgd.0 for ; Mon, 28 Feb 2022 04:44:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PJx9hB0kIbIWLZyy32lbZetHXaTeepDKevo5MNeCdbQ=; b=ATVanXHAyWTE6Hp8QDPLyorWVuI3LgVlec5Rs1y75UAQCLO/uvlMaXCmx+zwteqqfr +ZcRlNfMU3u+YyMyA6Bx1WgNfcsOFpsnSnBgUNm2HH3ymXZkWKSNZGQl4+MhyhEhEf8k JMPP1XsiKIApMd4iVMEx0oWiQvZ7nEHluuW0G+B7EYw7n36RH1rroTdqE1dubZW88DtN OX38uwBBH43LsqY4uoqh0jiTu+/m4sit7O6z36mus2xKxly2ZdqS7AoJT4OIxUr85mAL xTQ2zkWby5GlpEKI2KjV+yyzRqaYJWFDsNnTXyir6/paDAiIXmYh61uXDiZZIBYb+OfO sS8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PJx9hB0kIbIWLZyy32lbZetHXaTeepDKevo5MNeCdbQ=; b=aodeaFDRF9RRUCUIuafXjjWbwuMzpLYiAZwt8NIX+3TM0/D5ikG8tV9U2VnsWEix+d Ce4Ui3xMHUCNRVyUqrL66+vnbhmUltFIA4c3ql6bx/XuGu+B44jseJGJdNj50yCcJPU5 LQtIfrZoeKZMKe7fZiZTturjfOsMZ30JebOOzpudZgrjZcmx9rwcmisd9MZXZXLnz0G7 W3lmWXZ/NNX5nOXlZnFLk2WkGd8ikff/4kI+q7WPK0laGh5qxOjIaeDl77BECir7B4SW 2zceUwQ+Hf98Jg1ydCLtvNX0h57f3HQo7avzqH4qEfq8R5KYyaafYWK1fTg4lOVoAX5g cZOQ== X-Gm-Message-State: AOAM531yvK1DX+aLPXyam85mrkAlQfVAusR9Ihaocrxg9JYCUOWTaNCY SMDQbTAG6utEHqcuWAd8arX/ X-Google-Smtp-Source: ABdhPJyBJkrEYo7aIxzRsNICRwxIHQPJv91bPdKqywdn3PmxJP4oGVMv5t50r4Xn45abZ7KfMchQQw== X-Received: by 2002:a65:52cc:0:b0:374:3ee6:c632 with SMTP id z12-20020a6552cc000000b003743ee6c632mr16909938pgp.91.1646052248248; Mon, 28 Feb 2022 04:44:08 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:07 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Paul Davey , Manivannan Sadhasivam , stable@vger.kernel.org Subject: [PATCH v4 02/27] bus: mhi: Fix MHI DMA structure endianness Date: Mon, 28 Feb 2022 18:13:19 +0530 Message-Id: <20220228124344.77359-3-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Paul Davey The MHI driver does not work on big endian architectures. The controller never transitions into mission mode. This appears to be due to the modem device expecting the various contexts and transfer rings to have fields in little endian order in memory, but the driver constructs them in native endianness. Fix MHI event, channel and command contexts and TRE handling macros to use explicit conversion to little endian. Mark fields in relevant structures as little endian to document this requirement. Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event= ring doorbells") Reviewed-by: Manivannan Sadhasivam Signed-off-by: Paul Davey Cc: stable@vger.kernel.org Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/core/debugfs.c | 26 +++---- drivers/bus/mhi/core/init.c | 36 +++++----- drivers/bus/mhi/core/internal.h | 119 ++++++++++++++++---------------- drivers/bus/mhi/core/main.c | 22 +++--- drivers/bus/mhi/core/pm.c | 4 +- 5 files changed, 104 insertions(+), 103 deletions(-) diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/core/debugfs.c index 858d7516410b..d818586c229d 100644 --- a/drivers/bus/mhi/core/debugfs.c +++ b/drivers/bus/mhi/core/debugfs.c @@ -60,16 +60,16 @@ static int mhi_debugfs_events_show(struct seq_file *m, = void *d) } =20 seq_printf(m, "Index: %d intmod count: %lu time: %lu", - i, (er_ctxt->intmod & EV_CTX_INTMODC_MASK) >> + i, (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODC_MASK) >> EV_CTX_INTMODC_SHIFT, - (er_ctxt->intmod & EV_CTX_INTMODT_MASK) >> + (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODT_MASK) >> EV_CTX_INTMODT_SHIFT); =20 - seq_printf(m, " base: 0x%0llx len: 0x%llx", er_ctxt->rbase, - er_ctxt->rlen); + seq_printf(m, " base: 0x%0llx len: 0x%llx", le64_to_cpu(er_ctxt->rbase), + le64_to_cpu(er_ctxt->rlen)); =20 - seq_printf(m, " rp: 0x%llx wp: 0x%llx", er_ctxt->rp, - er_ctxt->wp); + seq_printf(m, " rp: 0x%llx wp: 0x%llx", le64_to_cpu(er_ctxt->rp), + le64_to_cpu(er_ctxt->wp)); =20 seq_printf(m, " local rp: 0x%pK db: 0x%pad\n", ring->rp, &mhi_event->db_cfg.db_val); @@ -106,18 +106,18 @@ static int mhi_debugfs_channels_show(struct seq_file = *m, void *d) =20 seq_printf(m, "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx", - mhi_chan->name, mhi_chan->chan, (chan_ctxt->chcfg & + mhi_chan->name, mhi_chan->chan, (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT, - (chan_ctxt->chcfg & CHAN_CTX_BRSTMODE_MASK) >> - CHAN_CTX_BRSTMODE_SHIFT, (chan_ctxt->chcfg & + (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_BRSTMODE_MASK) >> + CHAN_CTX_BRSTMODE_SHIFT, (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT); =20 - seq_printf(m, " type: 0x%x event ring: %u", chan_ctxt->chtype, - chan_ctxt->erindex); + seq_printf(m, " type: 0x%x event ring: %u", le32_to_cpu(chan_ctxt->chtyp= e), + le32_to_cpu(chan_ctxt->erindex)); =20 seq_printf(m, " base: 0x%llx len: 0x%llx rp: 0x%llx wp: 0x%llx", - chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->rp, - chan_ctxt->wp); + le64_to_cpu(chan_ctxt->rbase), le64_to_cpu(chan_ctxt->rlen), + le64_to_cpu(chan_ctxt->rp), le64_to_cpu(chan_ctxt->wp)); =20 seq_printf(m, " local rp: 0x%pK local wp: 0x%pK db: 0x%pad\n", ring->rp, ring->wp, diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 09394a1c29ec..d8787aaa176b 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -293,17 +293,17 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntr= l) if (mhi_chan->offload_ch) continue; =20 - tmp =3D chan_ctxt->chcfg; + tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; tmp |=3D (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); tmp &=3D ~CHAN_CTX_BRSTMODE_MASK; tmp |=3D (mhi_chan->db_cfg.brstmode << CHAN_CTX_BRSTMODE_SHIFT); tmp &=3D ~CHAN_CTX_POLLCFG_MASK; tmp |=3D (mhi_chan->db_cfg.pollcfg << CHAN_CTX_POLLCFG_SHIFT); - chan_ctxt->chcfg =3D tmp; + chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 - chan_ctxt->chtype =3D mhi_chan->type; - chan_ctxt->erindex =3D mhi_chan->er_index; + chan_ctxt->chtype =3D cpu_to_le32(mhi_chan->type); + chan_ctxt->erindex =3D cpu_to_le32(mhi_chan->er_index); =20 mhi_chan->ch_state =3D MHI_CH_STATE_DISABLED; mhi_chan->tre_ring.db_addr =3D (void __iomem *)&chan_ctxt->wp; @@ -328,14 +328,14 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntr= l) if (mhi_event->offload_ev) continue; =20 - tmp =3D er_ctxt->intmod; + tmp =3D le32_to_cpu(er_ctxt->intmod); tmp &=3D ~EV_CTX_INTMODC_MASK; tmp &=3D ~EV_CTX_INTMODT_MASK; tmp |=3D (mhi_event->intmod << EV_CTX_INTMODT_SHIFT); - er_ctxt->intmod =3D tmp; + er_ctxt->intmod =3D cpu_to_le32(tmp); =20 - er_ctxt->ertype =3D MHI_ER_TYPE_VALID; - er_ctxt->msivec =3D mhi_event->irq; + er_ctxt->ertype =3D cpu_to_le32(MHI_ER_TYPE_VALID); + er_ctxt->msivec =3D cpu_to_le32(mhi_event->irq); mhi_event->db_cfg.db_mode =3D true; =20 ring->el_size =3D sizeof(struct mhi_tre); @@ -349,9 +349,9 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) * ring is empty */ ring->rp =3D ring->wp =3D ring->base; - er_ctxt->rbase =3D ring->iommu_base; + er_ctxt->rbase =3D cpu_to_le64(ring->iommu_base); er_ctxt->rp =3D er_ctxt->wp =3D er_ctxt->rbase; - er_ctxt->rlen =3D ring->len; + er_ctxt->rlen =3D cpu_to_le64(ring->len); ring->ctxt_wp =3D &er_ctxt->wp; } =20 @@ -378,9 +378,9 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) goto error_alloc_cmd; =20 ring->rp =3D ring->wp =3D ring->base; - cmd_ctxt->rbase =3D ring->iommu_base; + cmd_ctxt->rbase =3D cpu_to_le64(ring->iommu_base); cmd_ctxt->rp =3D cmd_ctxt->wp =3D cmd_ctxt->rbase; - cmd_ctxt->rlen =3D ring->len; + cmd_ctxt->rlen =3D cpu_to_le64(ring->len); ring->ctxt_wp =3D &cmd_ctxt->wp; } =20 @@ -581,10 +581,10 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_= cntrl, chan_ctxt->rp =3D 0; chan_ctxt->wp =3D 0; =20 - tmp =3D chan_ctxt->chcfg; + tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; tmp |=3D (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); - chan_ctxt->chcfg =3D tmp; + chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 /* Update to all cores */ smp_wmb(); @@ -618,14 +618,14 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cnt= rl, return -ENOMEM; } =20 - tmp =3D chan_ctxt->chcfg; + tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; tmp |=3D (MHI_CH_STATE_ENABLED << CHAN_CTX_CHSTATE_SHIFT); - chan_ctxt->chcfg =3D tmp; + chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 - chan_ctxt->rbase =3D tre_ring->iommu_base; + chan_ctxt->rbase =3D cpu_to_le64(tre_ring->iommu_base); chan_ctxt->rp =3D chan_ctxt->wp =3D chan_ctxt->rbase; - chan_ctxt->rlen =3D tre_ring->len; + chan_ctxt->rlen =3D cpu_to_le64(tre_ring->len); tre_ring->ctxt_wp =3D &chan_ctxt->wp; =20 tre_ring->rp =3D tre_ring->wp =3D tre_ring->base; diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/interna= l.h index 3508cbbf555d..37c39bf1c7a9 100644 --- a/drivers/bus/mhi/core/internal.h +++ b/drivers/bus/mhi/core/internal.h @@ -209,14 +209,14 @@ extern struct bus_type mhi_bus_type; #define EV_CTX_INTMODT_MASK GENMASK(31, 16) #define EV_CTX_INTMODT_SHIFT 16 struct mhi_event_ctxt { - __u32 intmod; - __u32 ertype; - __u32 msivec; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 intmod; + __le32 ertype; + __le32 msivec; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; =20 #define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) @@ -227,25 +227,25 @@ struct mhi_event_ctxt { #define CHAN_CTX_POLLCFG_SHIFT 10 #define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) struct mhi_chan_ctxt { - __u32 chcfg; - __u32 chtype; - __u32 erindex; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 chcfg; + __le32 chtype; + __le32 erindex; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; =20 struct mhi_cmd_ctxt { - __u32 reserved0; - __u32 reserved1; - __u32 reserved2; - - __u64 rbase __packed __aligned(4); - __u64 rlen __packed __aligned(4); - __u64 rp __packed __aligned(4); - __u64 wp __packed __aligned(4); + __le32 reserved0; + __le32 reserved1; + __le32 reserved2; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); }; =20 struct mhi_ctxt { @@ -258,8 +258,8 @@ struct mhi_ctxt { }; =20 struct mhi_tre { - u64 ptr; - u32 dword[2]; + __le64 ptr; + __le32 dword[2]; }; =20 struct bhi_vec_entry { @@ -277,57 +277,58 @@ enum mhi_cmd_type { /* No operation command */ #define MHI_TRE_CMD_NOOP_PTR (0) #define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (MHI_CMD_NOP << 16) +#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) =20 /* Channel reset command */ #define MHI_TRE_CMD_RESET_PTR (0) #define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_RESET_CHAN << 16)) +#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_RESET_CHAN << 16))) =20 /* Channel stop command */ #define MHI_TRE_CMD_STOP_PTR (0) #define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_STOP_CHAN << 16)) +#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_STOP_CHAN << 16))) =20 /* Channel start command */ #define MHI_TRE_CMD_START_PTR (0) #define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) ((chid << 24) | \ - (MHI_CMD_START_CHAN << 16)) +#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ + (MHI_CMD_START_CHAN << 16))) =20 -#define MHI_TRE_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) +#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) +#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xF= F) +#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xF= F) =20 /* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) (ptr) -#define MHI_TRE_EV_DWORD0(code, len) ((code << 24) | len) -#define MHI_TRE_EV_DWORD1(chid, type) ((chid << 24) | (type << 16)) -#define MHI_TRE_GET_EV_PTR(tre) ((tre)->ptr) -#define MHI_TRE_GET_EV_CODE(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LEN(tre) ((tre)->dword[0] & 0xFFFF) -#define MHI_TRE_GET_EV_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) -#define MHI_TRE_GET_EV_STATE(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_EXECENV(tre) (((tre)->dword[0] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_SEQ(tre) ((tre)->dword[0]) -#define MHI_TRE_GET_EV_TIME(tre) ((tre)->ptr) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits((tre)->ptr) -#define MHI_TRE_GET_EV_VEID(tre) (((tre)->dword[0] >> 16) & 0xFF) -#define MHI_TRE_GET_EV_LINKSPEED(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) ((tre)->dword[0] & 0xFF) +#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) +#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type <<= 16))) +#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) +#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) +#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) +#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xF= F) +#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0= xFF) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) +#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) &= 0xFF) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) =20 /* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) (ptr) -#define MHI_TRE_DATA_DWORD0(len) (len & MHI_MAX_MTU) -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 1= 0) \ - | (ieot << 9) | (ieob << 8) | chain) +#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) +#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16)= | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain)) =20 /* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (((u64)len << 48) | ptr) -#define MHI_RSCTRE_DATA_DWORD0(cookie) (cookie) -#define MHI_RSCTRE_DATA_DWORD1 (MHI_PKT_TYPE_COALESCING << 16) +#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) +#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) +#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) =20 enum mhi_pkt_type { MHI_PKT_TYPE_INVALID =3D 0x0, @@ -500,7 +501,7 @@ struct state_transition { struct mhi_ring { dma_addr_t dma_handle; dma_addr_t iommu_base; - u64 *ctxt_wp; /* point to ctxt wp */ + __le64 *ctxt_wp; /* point to ctxt wp */ void *pre_aligned; void *base; void *rp; diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index ffde617f93a3..85f4f7c8d7c6 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -114,7 +114,7 @@ void mhi_ring_er_db(struct mhi_event *mhi_event) struct mhi_ring *ring =3D &mhi_event->ring; =20 mhi_event->db_cfg.process_db(mhi_event->mhi_cntrl, &mhi_event->db_cfg, - ring->db_addr, *ring->ctxt_wp); + ring->db_addr, le64_to_cpu(*ring->ctxt_wp)); } =20 void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi= _cmd) @@ -123,7 +123,7 @@ void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, = struct mhi_cmd *mhi_cmd) struct mhi_ring *ring =3D &mhi_cmd->ring; =20 db =3D ring->iommu_base + (ring->wp - ring->base); - *ring->ctxt_wp =3D db; + *ring->ctxt_wp =3D cpu_to_le64(db); mhi_write_db(mhi_cntrl, ring->db_addr, db); } =20 @@ -140,7 +140,7 @@ void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl, * before letting h/w know there is new element to fetch. */ dma_wmb(); - *ring->ctxt_wp =3D db; + *ring->ctxt_wp =3D cpu_to_le64(db); =20 mhi_chan->db_cfg.process_db(mhi_cntrl, &mhi_chan->db_cfg, ring->db_addr, db); @@ -432,7 +432,7 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev) struct mhi_event_ctxt *er_ctxt =3D &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring =3D &mhi_event->ring; - dma_addr_t ptr =3D er_ctxt->rp; + dma_addr_t ptr =3D le64_to_cpu(er_ctxt->rp); void *dev_rp; =20 if (!is_valid_ring_ptr(ev_ring, ptr)) { @@ -537,14 +537,14 @@ static void mhi_recycle_ev_ring_element(struct mhi_co= ntroller *mhi_cntrl, =20 /* Update the WP */ ring->wp +=3D ring->el_size; - ctxt_wp =3D *ring->ctxt_wp + ring->el_size; + ctxt_wp =3D le64_to_cpu(*ring->ctxt_wp) + ring->el_size; =20 if (ring->wp >=3D (ring->base + ring->len)) { ring->wp =3D ring->base; ctxt_wp =3D ring->iommu_base; } =20 - *ring->ctxt_wp =3D ctxt_wp; + *ring->ctxt_wp =3D cpu_to_le64(ctxt_wp); =20 /* Update the RP */ ring->rp +=3D ring->el_size; @@ -801,7 +801,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi= _cntrl, struct device *dev =3D &mhi_cntrl->mhi_dev->dev; u32 chan; int count =3D 0; - dma_addr_t ptr =3D er_ctxt->rp; + dma_addr_t ptr =3D le64_to_cpu(er_ctxt->rp); =20 /* * This is a quick check to avoid unnecessary event processing @@ -940,7 +940,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi= _cntrl, mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp =3D ev_ring->rp; =20 - ptr =3D er_ctxt->rp; + ptr =3D le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); @@ -970,7 +970,7 @@ int mhi_process_data_event_ring(struct mhi_controller *= mhi_cntrl, int count =3D 0; u32 chan; struct mhi_chan *mhi_chan; - dma_addr_t ptr =3D er_ctxt->rp; + dma_addr_t ptr =3D le64_to_cpu(er_ctxt->rp); =20 if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) return -EIO; @@ -1011,7 +1011,7 @@ int mhi_process_data_event_ring(struct mhi_controller= *mhi_cntrl, mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp =3D ev_ring->rp; =20 - ptr =3D er_ctxt->rp; + ptr =3D le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); @@ -1533,7 +1533,7 @@ static void mhi_mark_stale_events(struct mhi_controll= er *mhi_cntrl, /* mark all stale events related to channel as STALE event */ spin_lock_irqsave(&mhi_event->lock, flags); =20 - ptr =3D er_ctxt->rp; + ptr =3D le64_to_cpu(er_ctxt->rp); if (!is_valid_ring_ptr(ev_ring, ptr)) { dev_err(&mhi_cntrl->mhi_dev->dev, "Event ring rp points outside of the event ring\n"); diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index 4aae0baea008..c35c5ddc7220 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -218,7 +218,7 @@ int mhi_ready_state_transition(struct mhi_controller *m= hi_cntrl) continue; =20 ring->wp =3D ring->base + ring->len - ring->el_size; - *ring->ctxt_wp =3D ring->iommu_base + ring->len - ring->el_size; + *ring->ctxt_wp =3D cpu_to_le64(ring->iommu_base + ring->len - ring->el_s= ize); /* Update all cores */ smp_wmb(); =20 @@ -420,7 +420,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_co= ntroller *mhi_cntrl) continue; =20 ring->wp =3D ring->base + ring->len - ring->el_size; - *ring->ctxt_wp =3D ring->iommu_base + ring->len - ring->el_size; + *ring->ctxt_wp =3D cpu_to_le64(ring->iommu_base + ring->len - ring->el_s= ize); /* Update to all cores */ smp_wmb(); =20 --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58E28C433EF for ; Mon, 28 Feb 2022 12:44:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236618AbiB1MpS (ORCPT ); Mon, 28 Feb 2022 07:45:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236626AbiB1MpG (ORCPT ); Mon, 28 Feb 2022 07:45:06 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10A5D4BFE1 for ; Mon, 28 Feb 2022 04:44:14 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id g1so11066885pfv.1 for ; Mon, 28 Feb 2022 04:44:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=37H2SCIcd0NGgB8HVqt8l3vRUxyFXtyBqdC2/L2gdR4=; b=FPxB0NWWS9WFhk05m8DZpu3KSQxUr8QE9nBQc2Dbcg/rr6aZVkaZoa53srC+oq5W3Q G4CRJqHQhIK+FtD86fNu0KLcJt91xsd0w2uwRYlg/+PIAsd3nnRltuTTHsAd5vcxzfl7 Rko/W5LUzf37QhhDhlzzoY0vd5qOZ1500aaLbzKMiToTbrcSULUQBYRRQ0aM8FA1spC3 xAO4NCzNYr8FHm/OVXwlyD4I0+f8IsTqaK+GGe9T/GMIqy8Dn5aRp8SmWXpsqO36f+Ve NAK+HOjus7QoD2MVjJj/4f6FrAI+pwMjnNt5QYbL5CdAiRlyx3w/mxrPZZZvnX828NXe YRSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=37H2SCIcd0NGgB8HVqt8l3vRUxyFXtyBqdC2/L2gdR4=; b=j0bcZj0V7uXd3lIKnbbq/5Qb4qMZdT10R4MePgiP9KiLBoPMMWmWh7DoYNyG+1rUev nIbUYrEHHHe3TPjOQQDzr5P/NobhdghIl1XMKFcUvatM9PZ7T7QXhtZKKrZcTFnAKEy6 1D+Qnc/H59ypq3LcW46kZIIVIYN+IaevVaJT87voWc2I6PweBnwc9JnBUJb9bDDFuDO/ tdCDMWyyApUSARUx/fDi43LkC0+f/NPOnUPnwm3n+wsXzrCn4JB9StX8vgeT5wyBbuIf se4lBMJ5KHWfen1WLkeLwATSxv3K+umvHiA1ddIf5sG6qPR0Isj7trv4EDUZIQUcNg3o 0doA== X-Gm-Message-State: AOAM533VEuAX6uqRYWePtYTbmENQD2rVKpVdpx/S5H52t4r6QIyxrf7N 02eR3owZDpyILfB7y0SpwxrI X-Google-Smtp-Source: ABdhPJxlxmS8m81k6dnuAkgduOrr04hd8kak4ihIp9Y7eFjy0htEA4G8rJdrZCPmglPwAVm54cH6og== X-Received: by 2002:a65:6bcd:0:b0:35e:d94:7b79 with SMTP id e13-20020a656bcd000000b0035e0d947b79mr7740302pgw.81.1646052253508; Mon, 28 Feb 2022 04:44:13 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:13 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v4 03/27] bus: mhi: Move host MHI code to "host" directory Date: Mon, 28 Feb 2022 18:13:20 +0530 Message-Id: <20220228124344.77359-4-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In preparation of the endpoint MHI support, let's move the host MHI code to its own "host" directory and adjust the toplevel MHI Kconfig & Makefile. While at it, let's also move the "pci_generic" driver to "host" directory as it is a host MHI controller driver. Reviewed-by: Hemant Kumar Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/Makefile | 2 +- drivers/bus/mhi/Kconfig | 27 ++------------------ drivers/bus/mhi/Makefile | 8 ++---- drivers/bus/mhi/host/Kconfig | 31 +++++++++++++++++++++++ drivers/bus/mhi/{core =3D> host}/Makefile | 4 ++- drivers/bus/mhi/{core =3D> host}/boot.c | 0 drivers/bus/mhi/{core =3D> host}/debugfs.c | 0 drivers/bus/mhi/{core =3D> host}/init.c | 0 drivers/bus/mhi/{core =3D> host}/internal.h | 0 drivers/bus/mhi/{core =3D> host}/main.c | 0 drivers/bus/mhi/{ =3D> host}/pci_generic.c | 0 drivers/bus/mhi/{core =3D> host}/pm.c | 0 12 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 drivers/bus/mhi/host/Kconfig rename drivers/bus/mhi/{core =3D> host}/Makefile (54%) rename drivers/bus/mhi/{core =3D> host}/boot.c (100%) rename drivers/bus/mhi/{core =3D> host}/debugfs.c (100%) rename drivers/bus/mhi/{core =3D> host}/init.c (100%) rename drivers/bus/mhi/{core =3D> host}/internal.h (100%) rename drivers/bus/mhi/{core =3D> host}/main.c (100%) rename drivers/bus/mhi/{ =3D> host}/pci_generic.c (100%) rename drivers/bus/mhi/{core =3D> host}/pm.c (100%) diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 52c2f35a26a9..16da51130d1a 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -39,4 +39,4 @@ obj-$(CONFIG_VEXPRESS_CONFIG) +=3D vexpress-config.o obj-$(CONFIG_DA8XX_MSTPRI) +=3D da8xx-mstpri.o =20 # MHI -obj-$(CONFIG_MHI_BUS) +=3D mhi/ +obj-y +=3D mhi/ diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig index da5cd0c9fc62..4748df7f9cd5 100644 --- a/drivers/bus/mhi/Kconfig +++ b/drivers/bus/mhi/Kconfig @@ -2,30 +2,7 @@ # # MHI bus # -# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +# Copyright (c) 2021, Linaro Ltd. # =20 -config MHI_BUS - tristate "Modem Host Interface (MHI) bus" - help - Bus driver for MHI protocol. Modem Host Interface (MHI) is a - communication protocol used by the host processors to control - and communicate with modem devices over a high speed peripheral - bus or shared memory. - -config MHI_BUS_DEBUG - bool "Debugfs support for the MHI bus" - depends on MHI_BUS && DEBUG_FS - help - Enable debugfs support for use with the MHI transport. Allows - reading and/or modifying some values within the MHI controller - for debug and test purposes. - -config MHI_BUS_PCI_GENERIC - tristate "MHI PCI controller driver" - depends on MHI_BUS - depends on PCI - help - This driver provides MHI PCI controller driver for devices such as - Qualcomm SDX55 based PCIe modems. - +source "drivers/bus/mhi/host/Kconfig" diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile index 0a2d778d6fb4..5f5708a249f5 100644 --- a/drivers/bus/mhi/Makefile +++ b/drivers/bus/mhi/Makefile @@ -1,6 +1,2 @@ -# core layer -obj-y +=3D core/ - -obj-$(CONFIG_MHI_BUS_PCI_GENERIC) +=3D mhi_pci_generic.o -mhi_pci_generic-y +=3D pci_generic.o - +# Host MHI stack +obj-y +=3D host/ diff --git a/drivers/bus/mhi/host/Kconfig b/drivers/bus/mhi/host/Kconfig new file mode 100644 index 000000000000..da5cd0c9fc62 --- /dev/null +++ b/drivers/bus/mhi/host/Kconfig @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# MHI bus +# +# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. +# + +config MHI_BUS + tristate "Modem Host Interface (MHI) bus" + help + Bus driver for MHI protocol. Modem Host Interface (MHI) is a + communication protocol used by the host processors to control + and communicate with modem devices over a high speed peripheral + bus or shared memory. + +config MHI_BUS_DEBUG + bool "Debugfs support for the MHI bus" + depends on MHI_BUS && DEBUG_FS + help + Enable debugfs support for use with the MHI transport. Allows + reading and/or modifying some values within the MHI controller + for debug and test purposes. + +config MHI_BUS_PCI_GENERIC + tristate "MHI PCI controller driver" + depends on MHI_BUS + depends on PCI + help + This driver provides MHI PCI controller driver for devices such as + Qualcomm SDX55 based PCIe modems. + diff --git a/drivers/bus/mhi/core/Makefile b/drivers/bus/mhi/host/Makefile similarity index 54% rename from drivers/bus/mhi/core/Makefile rename to drivers/bus/mhi/host/Makefile index c3feb4130aa3..859c2f38451c 100644 --- a/drivers/bus/mhi/core/Makefile +++ b/drivers/bus/mhi/host/Makefile @@ -1,4 +1,6 @@ obj-$(CONFIG_MHI_BUS) +=3D mhi.o - mhi-y :=3D init.o main.o pm.o boot.o mhi-$(CONFIG_MHI_BUS_DEBUG) +=3D debugfs.o + +obj-$(CONFIG_MHI_BUS_PCI_GENERIC) +=3D mhi_pci_generic.o +mhi_pci_generic-y +=3D pci_generic.o diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/host/boot.c similarity index 100% rename from drivers/bus/mhi/core/boot.c rename to drivers/bus/mhi/host/boot.c diff --git a/drivers/bus/mhi/core/debugfs.c b/drivers/bus/mhi/host/debugfs.c similarity index 100% rename from drivers/bus/mhi/core/debugfs.c rename to drivers/bus/mhi/host/debugfs.c diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/host/init.c similarity index 100% rename from drivers/bus/mhi/core/init.c rename to drivers/bus/mhi/host/init.c diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/host/interna= l.h similarity index 100% rename from drivers/bus/mhi/core/internal.h rename to drivers/bus/mhi/host/internal.h diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/host/main.c similarity index 100% rename from drivers/bus/mhi/core/main.c rename to drivers/bus/mhi/host/main.c diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/host/pci_gener= ic.c similarity index 100% rename from drivers/bus/mhi/pci_generic.c rename to drivers/bus/mhi/host/pci_generic.c diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/host/pm.c similarity index 100% rename from drivers/bus/mhi/core/pm.c rename to drivers/bus/mhi/host/pm.c --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2176C433FE for ; Mon, 28 Feb 2022 12:44:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236624AbiB1MpO (ORCPT ); Mon, 28 Feb 2022 07:45:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33884 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236640AbiB1MpH (ORCPT ); Mon, 28 Feb 2022 07:45:07 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C18D947547 for ; Mon, 28 Feb 2022 04:44:19 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id em10-20020a17090b014a00b001bc3071f921so14653082pjb.5 for ; Mon, 28 Feb 2022 04:44:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CxtZZOug5pAozaT+Hjy+nXQP3phus2MtPvrSLnbfFXs=; b=o2n1A/YUUqp4OCKi0bGq3tGbM0g2TFyXUpC8rF1mqzC9s3i4SLRWAgZh0co9+JDc2P 8qgGIhFjpyKAqDRKftF/2a6cMEeiOOTvFZnrDTkYTTO5S58qTqq20BuscQ5JncFk6V4C jGuLd40x9kpkJ/LuFbjFYENl+lDOY+VsxFPaqUKa44MoyEkLZaz4uYOKHIxrc6HbdaOk HdPs09SZc6z5tIO6wFyCbbkbBwLQhacZsheqwtkYRszSyMMOvZ/yxqhHsHAQ8fLJLgSx ZoN1t1L4T3inCZn2DBDskN50KBURXHgoWYu+8qgUal6zG/QF9AW6IDWQbgjkMvz9XZig TUPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CxtZZOug5pAozaT+Hjy+nXQP3phus2MtPvrSLnbfFXs=; b=WgpTJwx4JL/0Zmx9cIw8W3XLS+kRojzRWfMWRIoQkXMslHOZQ7jARygvU4ogI8fxtN VWjjVtVvipQ6DItqbSkcW90tKGFYVgykb0ojxNRi4N2meXfqmZpn/mMusdGSonA+Bc/t uPiYszwj9i7tjcDnHrBSa4C5z1LBAIcBmJn7QzMU3TfJpKZgoRponsr9O0uYM6yzvKY2 GAlPP6kaMb7Dg4zkI08GMafej3xfVRzDqaR8y0dFxV0vA2h7WqGHYu/KV0oXFYcWTLOj WkZvCEkdKebQed3pD2Yo7ak9WLimWu/Oni9cnf31nI/oTEKLMDP7TG7f4SQDRXCL6ZcE 0ZKw== X-Gm-Message-State: AOAM530KrnGRGe1NvCvD2PELI+7ibTg8n6AntQsdS1noeYOY3cX0QYjf nd/9rmI663Y0Pc4wvA25usTL X-Google-Smtp-Source: ABdhPJz8N+rFTg1EoHnoTkkFgFU71E0bSwYHkhCZ3gPpDUxO3ESVXGVyI745j0u1kEwVnZrwnJjEbQ== X-Received: by 2002:a17:90a:6c05:b0:1bc:94af:13d4 with SMTP id x5-20020a17090a6c0500b001bc94af13d4mr16561779pjj.170.1646052259098; Mon, 28 Feb 2022 04:44:19 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:18 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 04/27] bus: mhi: Use bitfield operations for register read and write Date: Mon, 28 Feb 2022 18:13:21 +0530 Message-Id: <20220228124344.77359-5-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Functions like mhi_read_reg_field(), mhi_poll_reg_field() and mhi_write_reg_field() could be modified to not depend on the shift value passed as an argument. Instead, the bitfield operation could be used to extract the shift value from the mask itself. This eliminates the need to define _SHIFT (and _SHFT) macros and simplifies the code a bit. For shift values those cannot be determined during build time, "__ffs()" helper is used find the shift value during runtime. While at it, let's also get rid of 32-bit masks like CHDBOFF_CHDBOFF_MASK by doing the full 32-bit register read. Suggested-by: Alex Elder Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/boot.c | 15 ++-- drivers/bus/mhi/host/debugfs.c | 10 +-- drivers/bus/mhi/host/init.c | 67 ++++++++---------- drivers/bus/mhi/host/internal.h | 120 +++++++------------------------- drivers/bus/mhi/host/main.c | 16 ++--- drivers/bus/mhi/host/pm.c | 18 ++--- 6 files changed, 76 insertions(+), 170 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 74295d3cc662..d5ba3c7efb61 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -46,8 +46,7 @@ void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, sequence_id =3D MHI_RANDOM_U32_NONZERO(BHIE_RXVECSTATUS_SEQNUM_BMSK); =20 mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS, - BHIE_RXVECDB_SEQNUM_BMSK, BHIE_RXVECDB_SEQNUM_SHFT, - sequence_id); + BHIE_RXVECDB_SEQNUM_BMSK, sequence_id); =20 dev_dbg(dev, "Address: %p and len: 0x%zx sequence: %u\n", &mhi_buf->dma_addr, mhi_buf->len, sequence_id); @@ -127,9 +126,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_cont= roller *mhi_cntrl) =20 while (retry--) { ret =3D mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, - BHIE_RXVECSTATUS_STATUS_BMSK, - BHIE_RXVECSTATUS_STATUS_SHFT, - &rx_status); + BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status); if (ret) return -EIO; =20 @@ -168,7 +165,6 @@ int mhi_download_rddm_image(struct mhi_controller *mhi_= cntrl, bool in_panic) mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, BHIE_RXVECSTATUS_STATUS_BMSK, - BHIE_RXVECSTATUS_STATUS_SHFT, &rx_status) || rx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); =20 @@ -203,8 +199,7 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_= cntrl, mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len); =20 mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS, - BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT, - sequence_id); + BHIE_TXVECDB_SEQNUM_BMSK, sequence_id); read_unlock_bh(pm_lock); =20 /* Wait for the image download to complete */ @@ -213,7 +208,6 @@ static int mhi_fw_load_bhie(struct mhi_controller *mhi_= cntrl, mhi_read_reg_field(mhi_cntrl, base, BHIE_TXVECSTATUS_OFFS, BHIE_TXVECSTATUS_STATUS_BMSK, - BHIE_TXVECSTATUS_STATUS_SHFT, &tx_status) || tx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || @@ -265,8 +259,7 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_c= ntrl, ret =3D wait_event_timeout(mhi_cntrl->state_event, MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state) || mhi_read_reg_field(mhi_cntrl, base, BHI_STATUS, - BHI_STATUS_MASK, BHI_STATUS_SHIFT, - &tx_status) || tx_status, + BHI_STATUS_MASK, &tx_status) || tx_status, msecs_to_jiffies(mhi_cntrl->timeout_ms)); if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) goto invalid_pm_state; diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index d818586c229d..bdc875d7bd4d 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -61,9 +61,9 @@ static int mhi_debugfs_events_show(struct seq_file *m, vo= id *d) =20 seq_printf(m, "Index: %d intmod count: %lu time: %lu", i, (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODC_MASK) >> - EV_CTX_INTMODC_SHIFT, + __ffs(EV_CTX_INTMODC_MASK), (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODT_MASK) >> - EV_CTX_INTMODT_SHIFT); + __ffs(EV_CTX_INTMODT_MASK)); =20 seq_printf(m, " base: 0x%0llx len: 0x%llx", le64_to_cpu(er_ctxt->rbase), le64_to_cpu(er_ctxt->rlen)); @@ -107,10 +107,10 @@ static int mhi_debugfs_channels_show(struct seq_file = *m, void *d) seq_printf(m, "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx", mhi_chan->name, mhi_chan->chan, (le32_to_cpu(chan_ctxt->chcfg) & - CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT, + CHAN_CTX_CHSTATE_MASK) >> __ffs(CHAN_CTX_CHSTATE_MASK), (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_BRSTMODE_MASK) >> - CHAN_CTX_BRSTMODE_SHIFT, (le32_to_cpu(chan_ctxt->chcfg) & - CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT); + __ffs(CHAN_CTX_BRSTMODE_MASK), (le32_to_cpu(chan_ctxt->chcfg) & + CHAN_CTX_POLLCFG_MASK) >> __ffs(CHAN_CTX_POLLCFG_MASK)); =20 seq_printf(m, " type: 0x%x event ring: %u", le32_to_cpu(chan_ctxt->chtyp= e), le32_to_cpu(chan_ctxt->erindex)); diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index d8787aaa176b..ca068a017a42 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -4,6 +4,7 @@ * */ =20 +#include #include #include #include @@ -295,11 +296,11 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntr= l) =20 tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; - tmp |=3D (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); tmp &=3D ~CHAN_CTX_BRSTMODE_MASK; - tmp |=3D (mhi_chan->db_cfg.brstmode << CHAN_CTX_BRSTMODE_SHIFT); + tmp |=3D FIELD_PREP(CHAN_CTX_BRSTMODE_MASK, mhi_chan->db_cfg.brstmode); tmp &=3D ~CHAN_CTX_POLLCFG_MASK; - tmp |=3D (mhi_chan->db_cfg.pollcfg << CHAN_CTX_POLLCFG_SHIFT); + tmp |=3D FIELD_PREP(CHAN_CTX_POLLCFG_MASK, mhi_chan->db_cfg.pollcfg); chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 chan_ctxt->chtype =3D cpu_to_le32(mhi_chan->type); @@ -331,7 +332,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) tmp =3D le32_to_cpu(er_ctxt->intmod); tmp &=3D ~EV_CTX_INTMODC_MASK; tmp &=3D ~EV_CTX_INTMODT_MASK; - tmp |=3D (mhi_event->intmod << EV_CTX_INTMODT_SHIFT); + tmp |=3D FIELD_PREP(EV_CTX_INTMODT_MASK, mhi_event->intmod); er_ctxt->intmod =3D cpu_to_le32(tmp); =20 er_ctxt->ertype =3D cpu_to_le32(MHI_ER_TYPE_VALID); @@ -437,71 +438,70 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) struct { u32 offset; u32 mask; - u32 shift; u32 val; } reg_info[] =3D { { - CCABAP_HIGHER, U32_MAX, 0, + CCABAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->chan_ctxt_addr), }, { - CCABAP_LOWER, U32_MAX, 0, + CCABAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->chan_ctxt_addr), }, { - ECABAP_HIGHER, U32_MAX, 0, + ECABAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->er_ctxt_addr), }, { - ECABAP_LOWER, U32_MAX, 0, + ECABAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->er_ctxt_addr), }, { - CRCBAP_HIGHER, U32_MAX, 0, + CRCBAP_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->mhi_ctxt->cmd_ctxt_addr), }, { - CRCBAP_LOWER, U32_MAX, 0, + CRCBAP_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->mhi_ctxt->cmd_ctxt_addr), }, { - MHICFG, MHICFG_NER_MASK, MHICFG_NER_SHIFT, + MHICFG, MHICFG_NER_MASK, mhi_cntrl->total_ev_rings, }, { - MHICFG, MHICFG_NHWER_MASK, MHICFG_NHWER_SHIFT, + MHICFG, MHICFG_NHWER_MASK, mhi_cntrl->hw_ev_rings, }, { - MHICTRLBASE_HIGHER, U32_MAX, 0, + MHICTRLBASE_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_start), }, { - MHICTRLBASE_LOWER, U32_MAX, 0, + MHICTRLBASE_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_start), }, { - MHIDATABASE_HIGHER, U32_MAX, 0, + MHIDATABASE_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_start), }, { - MHIDATABASE_LOWER, U32_MAX, 0, + MHIDATABASE_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_start), }, { - MHICTRLLIMIT_HIGHER, U32_MAX, 0, + MHICTRLLIMIT_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_stop), }, { - MHICTRLLIMIT_LOWER, U32_MAX, 0, + MHICTRLLIMIT_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_stop), }, { - MHIDATALIMIT_HIGHER, U32_MAX, 0, + MHIDATALIMIT_HIGHER, U32_MAX, upper_32_bits(mhi_cntrl->iova_stop), }, { - MHIDATALIMIT_LOWER, U32_MAX, 0, + MHIDATALIMIT_LOWER, U32_MAX, lower_32_bits(mhi_cntrl->iova_stop), }, { 0, 0, 0 } @@ -510,8 +510,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) dev_dbg(dev, "Initializing MHI registers\n"); =20 /* Read channel db offset */ - ret =3D mhi_read_reg_field(mhi_cntrl, base, CHDBOFF, CHDBOFF_CHDBOFF_MASK, - CHDBOFF_CHDBOFF_SHIFT, &val); + ret =3D mhi_read_reg(mhi_cntrl, base, CHDBOFF, &val); if (ret) { dev_err(dev, "Unable to read CHDBOFF register\n"); return -EIO; @@ -527,8 +526,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) mhi_chan->tre_ring.db_addr =3D base + val; =20 /* Read event ring db offset */ - ret =3D mhi_read_reg_field(mhi_cntrl, base, ERDBOFF, ERDBOFF_ERDBOFF_MASK, - ERDBOFF_ERDBOFF_SHIFT, &val); + ret =3D mhi_read_reg(mhi_cntrl, base, ERDBOFF, &val); if (ret) { dev_err(dev, "Unable to read ERDBOFF register\n"); return -EIO; @@ -549,8 +547,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) /* Write to MMIO registers */ for (i =3D 0; reg_info[i].offset; i++) mhi_write_reg_field(mhi_cntrl, base, reg_info[i].offset, - reg_info[i].mask, reg_info[i].shift, - reg_info[i].val); + reg_info[i].mask, reg_info[i].val); =20 return 0; } @@ -583,7 +580,7 @@ void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cn= trl, =20 tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; - tmp |=3D (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 /* Update to all cores */ @@ -620,7 +617,7 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, =20 tmp =3D le32_to_cpu(chan_ctxt->chcfg); tmp &=3D ~CHAN_CTX_CHSTATE_MASK; - tmp |=3D (MHI_CH_STATE_ENABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_ENABLED); chan_ctxt->chcfg =3D cpu_to_le32(tmp); =20 chan_ctxt->rbase =3D cpu_to_le64(tre_ring->iommu_base); @@ -964,14 +961,10 @@ int mhi_register_controller(struct mhi_controller *mh= i_cntrl, if (ret) goto err_destroy_wq; =20 - mhi_cntrl->family_number =3D (soc_info & SOC_HW_VERSION_FAM_NUM_BMSK) >> - SOC_HW_VERSION_FAM_NUM_SHFT; - mhi_cntrl->device_number =3D (soc_info & SOC_HW_VERSION_DEV_NUM_BMSK) >> - SOC_HW_VERSION_DEV_NUM_SHFT; - mhi_cntrl->major_version =3D (soc_info & SOC_HW_VERSION_MAJOR_VER_BMSK) >> - SOC_HW_VERSION_MAJOR_VER_SHFT; - mhi_cntrl->minor_version =3D (soc_info & SOC_HW_VERSION_MINOR_VER_BMSK) >> - SOC_HW_VERSION_MINOR_VER_SHFT; + mhi_cntrl->family_number =3D FIELD_GET(SOC_HW_VERSION_FAM_NUM_BMSK, soc_i= nfo); + mhi_cntrl->device_number =3D FIELD_GET(SOC_HW_VERSION_DEV_NUM_BMSK, soc_i= nfo); + mhi_cntrl->major_version =3D FIELD_GET(SOC_HW_VERSION_MAJOR_VER_BMSK, soc= _info); + mhi_cntrl->minor_version =3D FIELD_GET(SOC_HW_VERSION_MINOR_VER_BMSK, soc= _info); =20 mhi_cntrl->index =3D ida_alloc(&mhi_controller_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 37c39bf1c7a9..156bf65b6810 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -12,120 +12,65 @@ extern struct bus_type mhi_bus_type; =20 #define MHIREGLEN (0x0) -#define MHIREGLEN_MHIREGLEN_MASK (0xFFFFFFFF) -#define MHIREGLEN_MHIREGLEN_SHIFT (0) =20 #define MHIVER (0x8) -#define MHIVER_MHIVER_MASK (0xFFFFFFFF) -#define MHIVER_MHIVER_SHIFT (0) =20 #define MHICFG (0x10) -#define MHICFG_NHWER_MASK (0xFF000000) -#define MHICFG_NHWER_SHIFT (24) -#define MHICFG_NER_MASK (0xFF0000) -#define MHICFG_NER_SHIFT (16) -#define MHICFG_NHWCH_MASK (0xFF00) -#define MHICFG_NHWCH_SHIFT (8) -#define MHICFG_NCH_MASK (0xFF) -#define MHICFG_NCH_SHIFT (0) +#define MHICFG_NHWER_MASK (GENMASK(31, 24)) +#define MHICFG_NER_MASK (GENMASK(23, 16)) +#define MHICFG_NHWCH_MASK (GENMASK(15, 8)) +#define MHICFG_NCH_MASK (GENMASK(7, 0)) =20 #define CHDBOFF (0x18) -#define CHDBOFF_CHDBOFF_MASK (0xFFFFFFFF) -#define CHDBOFF_CHDBOFF_SHIFT (0) =20 #define ERDBOFF (0x20) -#define ERDBOFF_ERDBOFF_MASK (0xFFFFFFFF) -#define ERDBOFF_ERDBOFF_SHIFT (0) =20 #define BHIOFF (0x28) -#define BHIOFF_BHIOFF_MASK (0xFFFFFFFF) -#define BHIOFF_BHIOFF_SHIFT (0) =20 #define BHIEOFF (0x2C) -#define BHIEOFF_BHIEOFF_MASK (0xFFFFFFFF) -#define BHIEOFF_BHIEOFF_SHIFT (0) =20 #define DEBUGOFF (0x30) -#define DEBUGOFF_DEBUGOFF_MASK (0xFFFFFFFF) -#define DEBUGOFF_DEBUGOFF_SHIFT (0) =20 #define MHICTRL (0x38) -#define MHICTRL_MHISTATE_MASK (0x0000FF00) -#define MHICTRL_MHISTATE_SHIFT (8) -#define MHICTRL_RESET_MASK (0x2) -#define MHICTRL_RESET_SHIFT (1) +#define MHICTRL_MHISTATE_MASK (GENMASK(15, 8)) +#define MHICTRL_RESET_MASK (BIT(1)) =20 #define MHISTATUS (0x48) -#define MHISTATUS_MHISTATE_MASK (0x0000FF00) -#define MHISTATUS_MHISTATE_SHIFT (8) -#define MHISTATUS_SYSERR_MASK (0x4) -#define MHISTATUS_SYSERR_SHIFT (2) -#define MHISTATUS_READY_MASK (0x1) -#define MHISTATUS_READY_SHIFT (0) +#define MHISTATUS_MHISTATE_MASK (GENMASK(15, 8)) +#define MHISTATUS_SYSERR_MASK (BIT(2)) +#define MHISTATUS_READY_MASK (BIT(0)) =20 #define CCABAP_LOWER (0x58) -#define CCABAP_LOWER_CCABAP_LOWER_MASK (0xFFFFFFFF) -#define CCABAP_LOWER_CCABAP_LOWER_SHIFT (0) =20 #define CCABAP_HIGHER (0x5C) -#define CCABAP_HIGHER_CCABAP_HIGHER_MASK (0xFFFFFFFF) -#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT (0) =20 #define ECABAP_LOWER (0x60) -#define ECABAP_LOWER_ECABAP_LOWER_MASK (0xFFFFFFFF) -#define ECABAP_LOWER_ECABAP_LOWER_SHIFT (0) =20 #define ECABAP_HIGHER (0x64) -#define ECABAP_HIGHER_ECABAP_HIGHER_MASK (0xFFFFFFFF) -#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT (0) =20 #define CRCBAP_LOWER (0x68) -#define CRCBAP_LOWER_CRCBAP_LOWER_MASK (0xFFFFFFFF) -#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT (0) =20 #define CRCBAP_HIGHER (0x6C) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK (0xFFFFFFFF) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT (0) =20 #define CRDB_LOWER (0x70) -#define CRDB_LOWER_CRDB_LOWER_MASK (0xFFFFFFFF) -#define CRDB_LOWER_CRDB_LOWER_SHIFT (0) =20 #define CRDB_HIGHER (0x74) -#define CRDB_HIGHER_CRDB_HIGHER_MASK (0xFFFFFFFF) -#define CRDB_HIGHER_CRDB_HIGHER_SHIFT (0) =20 #define MHICTRLBASE_LOWER (0x80) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT (0) =20 #define MHICTRLBASE_HIGHER (0x84) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT (0) =20 #define MHICTRLLIMIT_LOWER (0x88) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT (0) =20 #define MHICTRLLIMIT_HIGHER (0x8C) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT (0) =20 #define MHIDATABASE_LOWER (0x98) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK (0xFFFFFFFF) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT (0) =20 #define MHIDATABASE_HIGHER (0x9C) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT (0) =20 #define MHIDATALIMIT_LOWER (0xA0) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT (0) =20 #define MHIDATALIMIT_HIGHER (0xA4) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0) =20 /* Host request register */ #define MHI_SOC_RESET_REQ_OFFSET (0xB0) @@ -139,8 +84,7 @@ extern struct bus_type mhi_bus_type; #define BHI_IMGSIZE (0x10) #define BHI_RSVD1 (0x14) #define BHI_IMGTXDB (0x18) -#define BHI_TXDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHI_TXDB_SEQNUM_SHFT (0) +#define BHI_TXDB_SEQNUM_BMSK (GENMASK(29, 0)) #define BHI_RSVD2 (0x1C) #define BHI_INTVEC (0x20) #define BHI_RSVD3 (0x24) @@ -156,8 +100,7 @@ extern struct bus_type mhi_bus_type; #define BHI_MSMHWID(n) (0x4C + (0x4 * (n))) #define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) #define BHI_RSVD5 (0xC4) -#define BHI_STATUS_MASK (0xC0000000) -#define BHI_STATUS_SHIFT (30) +#define BHI_STATUS_MASK (GENMASK(31, 30)) #define BHI_STATUS_ERROR (3) #define BHI_STATUS_SUCCESS (2) #define BHI_STATUS_RESET (0) @@ -168,13 +111,10 @@ extern struct bus_type mhi_bus_type; #define BHIE_TXVECADDR_HIGH_OFFS (0x0030) #define BHIE_TXVECSIZE_OFFS (0x0034) #define BHIE_TXVECDB_OFFS (0x003C) -#define BHIE_TXVECDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_TXVECDB_SEQNUM_SHFT (0) +#define BHIE_TXVECDB_SEQNUM_BMSK (GENMASK(29, 0)) #define BHIE_TXVECSTATUS_OFFS (0x0044) -#define BHIE_TXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_TXVECSTATUS_SEQNUM_SHFT (0) -#define BHIE_TXVECSTATUS_STATUS_BMSK (0xC0000000) -#define BHIE_TXVECSTATUS_STATUS_SHFT (30) +#define BHIE_TXVECSTATUS_SEQNUM_BMSK (GENMASK(29, 0)) +#define BHIE_TXVECSTATUS_STATUS_BMSK (GENMASK(31, 30)) #define BHIE_TXVECSTATUS_STATUS_RESET (0x00) #define BHIE_TXVECSTATUS_STATUS_XFER_COMPL (0x02) #define BHIE_TXVECSTATUS_STATUS_ERROR (0x03) @@ -182,32 +122,23 @@ extern struct bus_type mhi_bus_type; #define BHIE_RXVECADDR_HIGH_OFFS (0x0064) #define BHIE_RXVECSIZE_OFFS (0x0068) #define BHIE_RXVECDB_OFFS (0x0070) -#define BHIE_RXVECDB_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_RXVECDB_SEQNUM_SHFT (0) +#define BHIE_RXVECDB_SEQNUM_BMSK (GENMASK(29, 0)) #define BHIE_RXVECSTATUS_OFFS (0x0078) -#define BHIE_RXVECSTATUS_SEQNUM_BMSK (0x3FFFFFFF) -#define BHIE_RXVECSTATUS_SEQNUM_SHFT (0) -#define BHIE_RXVECSTATUS_STATUS_BMSK (0xC0000000) -#define BHIE_RXVECSTATUS_STATUS_SHFT (30) +#define BHIE_RXVECSTATUS_SEQNUM_BMSK (GENMASK(29, 0)) +#define BHIE_RXVECSTATUS_STATUS_BMSK (GENMASK(31, 30)) #define BHIE_RXVECSTATUS_STATUS_RESET (0x00) #define BHIE_RXVECSTATUS_STATUS_XFER_COMPL (0x02) #define BHIE_RXVECSTATUS_STATUS_ERROR (0x03) =20 #define SOC_HW_VERSION_OFFS (0x224) -#define SOC_HW_VERSION_FAM_NUM_BMSK (0xF0000000) -#define SOC_HW_VERSION_FAM_NUM_SHFT (28) -#define SOC_HW_VERSION_DEV_NUM_BMSK (0x0FFF0000) -#define SOC_HW_VERSION_DEV_NUM_SHFT (16) -#define SOC_HW_VERSION_MAJOR_VER_BMSK (0x0000FF00) -#define SOC_HW_VERSION_MAJOR_VER_SHFT (8) -#define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF) -#define SOC_HW_VERSION_MINOR_VER_SHFT (0) +#define SOC_HW_VERSION_FAM_NUM_BMSK (GENMASK(31, 28)) +#define SOC_HW_VERSION_DEV_NUM_BMSK (GENMASK(27, 16)) +#define SOC_HW_VERSION_MAJOR_VER_BMSK (GENMASK(15, 8)) +#define SOC_HW_VERSION_MINOR_VER_BMSK (GENMASK(7, 0)) =20 #define EV_CTX_RESERVED_MASK GENMASK(7, 0) #define EV_CTX_INTMODC_MASK GENMASK(15, 8) -#define EV_CTX_INTMODC_SHIFT 8 #define EV_CTX_INTMODT_MASK GENMASK(31, 16) -#define EV_CTX_INTMODT_SHIFT 16 struct mhi_event_ctxt { __le32 intmod; __le32 ertype; @@ -220,11 +151,8 @@ struct mhi_event_ctxt { }; =20 #define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) -#define CHAN_CTX_CHSTATE_SHIFT 0 #define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) -#define CHAN_CTX_BRSTMODE_SHIFT 8 #define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) -#define CHAN_CTX_POLLCFG_SHIFT 10 #define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) struct mhi_chan_ctxt { __le32 chcfg; @@ -659,14 +587,14 @@ int __must_check mhi_read_reg(struct mhi_controller *= mhi_cntrl, void __iomem *base, u32 offset, u32 *out); int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 mask, - u32 shift, u32 *out); + u32 *out); int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 mask, - u32 shift, u32 val, u32 delayus); + u32 val, u32 delayus); void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, u32 val); void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *b= ase, - u32 offset, u32 mask, u32 shift, u32 val); + u32 offset, u32 mask, u32 val); void mhi_ring_er_db(struct mhi_event *mhi_event); void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr, dma_addr_t db_val); diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 85f4f7c8d7c6..3e6e615466b7 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -24,7 +24,7 @@ int __must_check mhi_read_reg(struct mhi_controller *mhi_= cntrl, =20 int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, - u32 mask, u32 shift, u32 *out) + u32 mask, u32 *out) { u32 tmp; int ret; @@ -33,21 +33,20 @@ int __must_check mhi_read_reg_field(struct mhi_controll= er *mhi_cntrl, if (ret) return ret; =20 - *out =3D (tmp & mask) >> shift; + *out =3D (tmp & mask) >> __ffs(mask); =20 return 0; } =20 int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base, u32 offset, - u32 mask, u32 shift, u32 val, u32 delayus) + u32 mask, u32 val, u32 delayus) { int ret; u32 out, retry =3D (mhi_cntrl->timeout_ms * 1000) / delayus; =20 while (retry--) { - ret =3D mhi_read_reg_field(mhi_cntrl, base, offset, mask, shift, - &out); + ret =3D mhi_read_reg_field(mhi_cntrl, base, offset, mask, &out); if (ret) return ret; =20 @@ -67,7 +66,7 @@ void mhi_write_reg(struct mhi_controller *mhi_cntrl, void= __iomem *base, } =20 void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *b= ase, - u32 offset, u32 mask, u32 shift, u32 val) + u32 offset, u32 mask, u32 val) { int ret; u32 tmp; @@ -77,7 +76,7 @@ void mhi_write_reg_field(struct mhi_controller *mhi_cntrl= , void __iomem *base, return; =20 tmp &=3D ~mask; - tmp |=3D (val << shift); + tmp |=3D (val << __ffs(mask)); mhi_write_reg(mhi_cntrl, base, offset, tmp); } =20 @@ -159,8 +158,7 @@ enum mhi_state mhi_get_mhi_state(struct mhi_controller = *mhi_cntrl) { u32 state; int ret =3D mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, - MHISTATUS_MHISTATE_MASK, - MHISTATUS_MHISTATE_SHIFT, &state); + MHISTATUS_MHISTATE_MASK, &state); return ret ? MHI_STATE_MAX : state; } EXPORT_SYMBOL_GPL(mhi_get_mhi_state); diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index c35c5ddc7220..bb8a23e80e19 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -131,11 +131,10 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cnt= rl, enum mhi_state state) { if (state =3D=3D MHI_STATE_RESET) { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 1); + MHICTRL_RESET_MASK, 1); } else { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_MHISTATE_MASK, - MHICTRL_MHISTATE_SHIFT, state); + MHICTRL_MHISTATE_MASK, state); } } =20 @@ -167,16 +166,14 @@ int mhi_ready_state_transition(struct mhi_controller = *mhi_cntrl) =20 /* Wait for RESET to be cleared and READY bit to be set by the device */ ret =3D mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - interval_us); + MHICTRL_RESET_MASK, 0, interval_us); if (ret) { dev_err(dev, "Device failed to clear MHI Reset\n"); return ret; } =20 ret =3D mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, - MHISTATUS_READY_MASK, MHISTATUS_READY_SHIFT, 1, - interval_us); + MHISTATUS_READY_MASK, 1, interval_us); if (ret) { dev_err(dev, "Device failed to enter MHI Ready\n"); return ret; @@ -470,8 +467,7 @@ static void mhi_pm_disable_transition(struct mhi_contro= ller *mhi_cntrl) =20 /* Wait for the reset bit to be cleared by the device */ ret =3D mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - 25000); + MHICTRL_RESET_MASK, 0, 25000); if (ret) dev_err(dev, "Device failed to clear MHI Reset\n"); =20 @@ -602,7 +598,6 @@ static void mhi_pm_sys_error_transition(struct mhi_cont= roller *mhi_cntrl) mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, - MHICTRL_RESET_SHIFT, &in_reset) || !in_reset, timeout); if (!ret || in_reset) { @@ -1093,8 +1088,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cnt= rl) if (state =3D=3D MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); ret =3D mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, - MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, - interval_us); + MHICTRL_RESET_MASK, 0, interval_us); if (ret) { dev_info(dev, "Failed to reset MHI due to syserr state\n"); goto error_exit; --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D82AC433EF for ; Mon, 28 Feb 2022 12:44:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236675AbiB1Mp3 (ORCPT ); Mon, 28 Feb 2022 07:45:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236688AbiB1MpI (ORCPT ); Mon, 28 Feb 2022 07:45:08 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 032A470F4B for ; Mon, 28 Feb 2022 04:44:24 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id p8so11043158pfh.8 for ; Mon, 28 Feb 2022 04:44:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6g5od/KEwr4ZJk1saQZpLMEk+CU+pk4PGJ3mnuEHKxc=; b=LYyKDS5E6u236sxSPG95jTwxHjnVvCIm2ZFMCgGIr7/gdPtBBRcJxdfr5hTjomLqWf IZbdSdddI6KCueydHwV47hjtDkQPPI7YUol27+2XWWziTR9QsQkx8jU7Ud8buuIObwYb z/fxU/nTe7KkHiPsRJmN9hH0v4axwI4DDZ+EwKyB0Ge6kxg0e9Kdf78IyrmbMpjim7E8 KOnQt4FtMGjj9Dn9lVep1D1TL63ae6WrK06j1czWBi63tZ3oxe4AlCJFUg1sQbmsEb4x bReAFoYskU+W03rbxHvDjEV2N1OGpb1K4b4HB7jzFTQ9/PDy6hClUuNynj7YxAAs2vkb UVVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6g5od/KEwr4ZJk1saQZpLMEk+CU+pk4PGJ3mnuEHKxc=; b=ZCsztEKg8EUY6PisnG1NuM5a7VsbYD3HMDZg7Y0xdNq/aGXZLm3d8L6ilaoRYKyQS0 Gb2zV4SrkKcUFV8uYL3KsHWjsQ7UwA8OZZknjlc5fjNL/IweAlHUcMuEHWBwRpc69azy GxH2dRHud9q6toDkeeENLSckax8Kr65tZLMqXD/FgQF+QCmnqGBeZUZ91OH3TuUSpw/7 WltgrNVW+rPr+tSMkv0R8k9Dn8beYSRfsyWUpyVJcDt4evNrxqWZIAikkgpmPrhJmjhG x3IHi/Hfcs6SE9wtCDIficGnJ4KANCPk8U5UnDeN4jOO96HcvdU1ZhAGhmBz1Ol6JJam Kvfw== X-Gm-Message-State: AOAM533GjjU+rN1q4EX1rhs3g9oO71Gm2AytLTnJbz/AACg8oCs/bDO2 ZcvNPwAkfbhHuMNaZIH5vu9O X-Google-Smtp-Source: ABdhPJwKoM1b/QRNPoa4M6cjOzIs1+5twf2bVahGrolMmQPMnMn7DgTxNe9RqRTiP/uIiT2yL0fbYQ== X-Received: by 2002:a63:200d:0:b0:373:a7d1:75d4 with SMTP id g13-20020a63200d000000b00373a7d175d4mr16844015pgg.547.1646052264358; Mon, 28 Feb 2022 04:44:24 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:24 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 05/27] bus: mhi: Use bitfield operations for handling DWORDs of ring elements Date: Mon, 28 Feb 2022 18:13:22 +0530 Message-Id: <20220228124344.77359-6-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Instead of using the hardcoded bits in DWORD definitions, let's use the bitfield operations to make it more clear how the DWORDs are structured. Suggested-by: Alex Elder Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/host/internal.h | 58 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 156bf65b6810..1d1790e83a93 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -7,6 +7,7 @@ #ifndef _MHI_INT_H #define _MHI_INT_H =20 +#include #include =20 extern struct bus_type mhi_bus_type; @@ -205,58 +206,65 @@ enum mhi_cmd_type { /* No operation command */ #define MHI_TRE_CMD_NOOP_PTR (0) #define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) +#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(FIELD_PREP(GENMASK(23, 16), M= HI_CMD_NOP))) =20 /* Channel reset command */ #define MHI_TRE_CMD_RESET_PTR (0) #define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_RESET_CHAN << 16))) +#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31,= 24), chid)) | \ + FIELD_PREP(GENMASK(23, 16), MHI_CMD_RESET_CHAN)) =20 /* Channel stop command */ #define MHI_TRE_CMD_STOP_PTR (0) #define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_STOP_CHAN << 16))) +#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid)) | \ + FIELD_PREP(GENMASK(23, 16), MHI_CMD_STOP_CHAN)) =20 /* Channel start command */ #define MHI_TRE_CMD_START_PTR (0) #define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ - (MHI_CMD_START_CHAN << 16))) +#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31,= 24), chid)) | \ + FIELD_PREP(GENMASK(23, 16), MHI_CMD_START_CHAN)) =20 #define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) -#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xF= F) -#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xF= F) +#define MHI_TRE_GET_CMD_CHID(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET= _DWORD(tre, 1)))) +#define MHI_TRE_GET_CMD_TYPE(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET= _DWORD(tre, 1)))) =20 /* Event descriptor macros */ #define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) -#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type <<= 16))) +#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), code) | \ + FIELD_PREP(GENMASK(15, 0), len))) +#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ + FIELD_PREP(GENMASK(23, 16), type))) #define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) -#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) -#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) -#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xF= F) -#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0= xFF) +#define MHI_TRE_GET_EV_CODE(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 0)))) +#define MHI_TRE_GET_EV_LEN(tre) (FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DW= ORD(tre, 0)))) +#define MHI_TRE_GET_EV_CHID(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 1)))) +#define MHI_TRE_GET_EV_TYPE(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_= DWORD(tre, 1)))) +#define MHI_TRE_GET_EV_STATE(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET= _DWORD(tre, 0)))) +#define MHI_TRE_GET_EV_EXECENV(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_G= ET_DWORD(tre, 0)))) #define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) #define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) #define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) -#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) &= 0xFF) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) +#define MHI_TRE_GET_EV_VEID(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_= DWORD(tre, 0)))) +#define MHI_TRE_GET_EV_LINKSPEED(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE= _GET_DWORD(tre, 1)))) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) (FIELD_GET(GENMASK(7, 0), (MHI_TRE_G= ET_DWORD(tre, 0)))) =20 /* Transfer descriptor macros */ #define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16)= | (bei << 10) \ - | (ieot << 9) | (ieob << 8) | chain)) +#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(FIELD_PREP(GENMASK(15, 0), l= en))) +#define MHI_TRE_TYPE_TRANSFER 2 +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32(FIELD_PRE= P(GENMASK(23, 16), \ + MHI_TRE_TYPE_TRANSFER) | \ + FIELD_PREP(BIT(10), bei) | \ + FIELD_PREP(BIT(9), ieot) | \ + FIELD_PREP(BIT(8), ieob) | \ + FIELD_PREP(BIT(0), chain))) =20 /* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) +#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(FIELD_PREP(GENMASK(64, = 48), len) | ptr)) #define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) -#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) +#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(FIELD_PREP(GENMASK(23, 16), MH= I_PKT_TYPE_COALESCING) =20 enum mhi_pkt_type { MHI_PKT_TYPE_INVALID =3D 0x0, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DAE34C4332F for ; Mon, 28 Feb 2022 12:44:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234919AbiB1MpX (ORCPT ); Mon, 28 Feb 2022 07:45:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236660AbiB1MpL (ORCPT ); Mon, 28 Feb 2022 07:45:11 -0500 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99EDD47548 for ; Mon, 28 Feb 2022 04:44:30 -0800 (PST) Received: by mail-pj1-x1036.google.com with SMTP id d15so7695126pjg.1 for ; Mon, 28 Feb 2022 04:44:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ztR1ZgN3LqpzmgE/aV5hpMhENVc6hmHomH8afl5GlOs=; b=fMnNsff+yhkxaMSK6q8IusnnVADwZxpaeL/W10XThj/OXWnyCF+Ww9Zpggl4aag6yA R0Z2luR0re2zIrdofXf3DxSoXMZQOBCqt2ZXm7uBm/hTx1OUdSm9ID8DKHadvRd0g90s Hic+5mFsOUDWwLCxfDUyrpSl1QmQWwCf8YGh8pFIvdZ3poG7+ibtwe2O4Ly4ev19LPJ3 VHckSDhOOAjxpql/xHMpqSDV7tu2f4kVTWPKzzs/QzcsNHlFrE1CVt0sLaQ8kCgZVpna UkzqEjc9XcFvybW3goKJ7Nqj5LvdpTU26+/8yEtwONjLOTneTj9cc73IM9KqKxaPvVDF BxnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ztR1ZgN3LqpzmgE/aV5hpMhENVc6hmHomH8afl5GlOs=; b=NYNr0Oe3soLhgYEk45XJnTSIfvBQ2B9+k33nI2Y4a35ZGs7PH5veZtkF0gKA/wXf1o FvT5x+hfB1jkKGuIqyMrXOFmKERozNM8raK3L5rSlaTteUrFRIPULTeqI0ktL0KKAIbe Y4GZKBbMSAoxcj87djct85Uyh2YuvA4XwgyhTnqW5cXqeTD/QWfXXZoGyqFgxQ6C4ngR 7bXVr97uKLL4mpzET7UWczeeqSiKGchrxT6wr5YWqStaw9N0eRGfLOIa/t78sAycEoob icoSWIGfJly7osBRnv5V83LB6oAQ8GU2LB4SMkyJl0Iz57J/G/XFXg61pSi1KjlMavzz WVkA== X-Gm-Message-State: AOAM532oDzpMWvE7TCU8LAes+HCikHusurneS8pIsjyYDzmu876pi4lO 7VwM7F2AFYQaXYDiroT5Ib2x X-Google-Smtp-Source: ABdhPJxCmTph9UQ/ZysPF/okRtyIduLlLhYhLMeHYg7TbRKbbmzxLbN+UAmfwLh42h23nB3EjREo7Q== X-Received: by 2002:a17:90a:8595:b0:1bb:fbfd:bfbf with SMTP id m21-20020a17090a859500b001bbfbfdbfbfmr16374251pjn.125.1646052269943; Mon, 28 Feb 2022 04:44:29 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:29 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v4 06/27] bus: mhi: Cleanup the register definitions used in headers Date: Mon, 28 Feb 2022 18:13:23 +0530 Message-Id: <20220228124344.77359-7-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Cleanup includes: 1. Using the GENMASK macro for masks 2. Removing brackets for single values 3. Using lowercase for hex values 4. Using two digits for hex values where applicable 5. Aligning the defines on same column Reviewed-by: Hemant Kumar Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/host/internal.h | 413 +++++++++++++++----------------- 1 file changed, 199 insertions(+), 214 deletions(-) diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 1d1790e83a93..1c7a48be033f 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -12,134 +12,116 @@ =20 extern struct bus_type mhi_bus_type; =20 -#define MHIREGLEN (0x0) - -#define MHIVER (0x8) - -#define MHICFG (0x10) -#define MHICFG_NHWER_MASK (GENMASK(31, 24)) -#define MHICFG_NER_MASK (GENMASK(23, 16)) -#define MHICFG_NHWCH_MASK (GENMASK(15, 8)) -#define MHICFG_NCH_MASK (GENMASK(7, 0)) - -#define CHDBOFF (0x18) - -#define ERDBOFF (0x20) - -#define BHIOFF (0x28) - -#define BHIEOFF (0x2C) - -#define DEBUGOFF (0x30) - -#define MHICTRL (0x38) -#define MHICTRL_MHISTATE_MASK (GENMASK(15, 8)) -#define MHICTRL_RESET_MASK (BIT(1)) - -#define MHISTATUS (0x48) -#define MHISTATUS_MHISTATE_MASK (GENMASK(15, 8)) -#define MHISTATUS_SYSERR_MASK (BIT(2)) -#define MHISTATUS_READY_MASK (BIT(0)) - -#define CCABAP_LOWER (0x58) - -#define CCABAP_HIGHER (0x5C) - -#define ECABAP_LOWER (0x60) - -#define ECABAP_HIGHER (0x64) - -#define CRCBAP_LOWER (0x68) - -#define CRCBAP_HIGHER (0x6C) - -#define CRDB_LOWER (0x70) - -#define CRDB_HIGHER (0x74) - -#define MHICTRLBASE_LOWER (0x80) - -#define MHICTRLBASE_HIGHER (0x84) - -#define MHICTRLLIMIT_LOWER (0x88) - -#define MHICTRLLIMIT_HIGHER (0x8C) - -#define MHIDATABASE_LOWER (0x98) - -#define MHIDATABASE_HIGHER (0x9C) - -#define MHIDATALIMIT_LOWER (0xA0) - -#define MHIDATALIMIT_HIGHER (0xA4) +/* MHI registers */ +#define MHIREGLEN 0x00 +#define MHIVER 0x08 +#define MHICFG 0x10 +#define CHDBOFF 0x18 +#define ERDBOFF 0x20 +#define BHIOFF 0x28 +#define BHIEOFF 0x2c +#define DEBUGOFF 0x30 +#define MHICTRL 0x38 +#define MHISTATUS 0x48 +#define CCABAP_LOWER 0x58 +#define CCABAP_HIGHER 0x5c +#define ECABAP_LOWER 0x60 +#define ECABAP_HIGHER 0x64 +#define CRCBAP_LOWER 0x68 +#define CRCBAP_HIGHER 0x6c +#define CRDB_LOWER 0x70 +#define CRDB_HIGHER 0x74 +#define MHICTRLBASE_LOWER 0x80 +#define MHICTRLBASE_HIGHER 0x84 +#define MHICTRLLIMIT_LOWER 0x88 +#define MHICTRLLIMIT_HIGHER 0x8c +#define MHIDATABASE_LOWER 0x98 +#define MHIDATABASE_HIGHER 0x9c +#define MHIDATALIMIT_LOWER 0xa0 +#define MHIDATALIMIT_HIGHER 0xa4 =20 /* Host request register */ -#define MHI_SOC_RESET_REQ_OFFSET (0xB0) -#define MHI_SOC_RESET_REQ BIT(0) - -/* MHI BHI offfsets */ -#define BHI_BHIVERSION_MINOR (0x00) -#define BHI_BHIVERSION_MAJOR (0x04) -#define BHI_IMGADDR_LOW (0x08) -#define BHI_IMGADDR_HIGH (0x0C) -#define BHI_IMGSIZE (0x10) -#define BHI_RSVD1 (0x14) -#define BHI_IMGTXDB (0x18) -#define BHI_TXDB_SEQNUM_BMSK (GENMASK(29, 0)) -#define BHI_RSVD2 (0x1C) -#define BHI_INTVEC (0x20) -#define BHI_RSVD3 (0x24) -#define BHI_EXECENV (0x28) -#define BHI_STATUS (0x2C) -#define BHI_ERRCODE (0x30) -#define BHI_ERRDBG1 (0x34) -#define BHI_ERRDBG2 (0x38) -#define BHI_ERRDBG3 (0x3C) -#define BHI_SERIALNU (0x40) -#define BHI_SBLANTIROLLVER (0x44) -#define BHI_NUMSEG (0x48) -#define BHI_MSMHWID(n) (0x4C + (0x4 * (n))) -#define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) -#define BHI_RSVD5 (0xC4) -#define BHI_STATUS_MASK (GENMASK(31, 30)) -#define BHI_STATUS_ERROR (3) -#define BHI_STATUS_SUCCESS (2) -#define BHI_STATUS_RESET (0) - -/* MHI BHIE offsets */ -#define BHIE_MSMSOCID_OFFS (0x0000) -#define BHIE_TXVECADDR_LOW_OFFS (0x002C) -#define BHIE_TXVECADDR_HIGH_OFFS (0x0030) -#define BHIE_TXVECSIZE_OFFS (0x0034) -#define BHIE_TXVECDB_OFFS (0x003C) -#define BHIE_TXVECDB_SEQNUM_BMSK (GENMASK(29, 0)) -#define BHIE_TXVECSTATUS_OFFS (0x0044) -#define BHIE_TXVECSTATUS_SEQNUM_BMSK (GENMASK(29, 0)) -#define BHIE_TXVECSTATUS_STATUS_BMSK (GENMASK(31, 30)) -#define BHIE_TXVECSTATUS_STATUS_RESET (0x00) -#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL (0x02) -#define BHIE_TXVECSTATUS_STATUS_ERROR (0x03) -#define BHIE_RXVECADDR_LOW_OFFS (0x0060) -#define BHIE_RXVECADDR_HIGH_OFFS (0x0064) -#define BHIE_RXVECSIZE_OFFS (0x0068) -#define BHIE_RXVECDB_OFFS (0x0070) -#define BHIE_RXVECDB_SEQNUM_BMSK (GENMASK(29, 0)) -#define BHIE_RXVECSTATUS_OFFS (0x0078) -#define BHIE_RXVECSTATUS_SEQNUM_BMSK (GENMASK(29, 0)) -#define BHIE_RXVECSTATUS_STATUS_BMSK (GENMASK(31, 30)) -#define BHIE_RXVECSTATUS_STATUS_RESET (0x00) -#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL (0x02) -#define BHIE_RXVECSTATUS_STATUS_ERROR (0x03) - -#define SOC_HW_VERSION_OFFS (0x224) -#define SOC_HW_VERSION_FAM_NUM_BMSK (GENMASK(31, 28)) -#define SOC_HW_VERSION_DEV_NUM_BMSK (GENMASK(27, 16)) -#define SOC_HW_VERSION_MAJOR_VER_BMSK (GENMASK(15, 8)) -#define SOC_HW_VERSION_MINOR_VER_BMSK (GENMASK(7, 0)) - -#define EV_CTX_RESERVED_MASK GENMASK(7, 0) -#define EV_CTX_INTMODC_MASK GENMASK(15, 8) -#define EV_CTX_INTMODT_MASK GENMASK(31, 16) +#define MHI_SOC_RESET_REQ_OFFSET 0xb0 +#define MHI_SOC_RESET_REQ BIT(0) + +/* MHI register bits */ +#define MHICFG_NHWER_MASK GENMASK(31, 24) +#define MHICFG_NER_MASK GENMASK(23, 16) +#define MHICFG_NHWCH_MASK GENMASK(15, 8) +#define MHICFG_NCH_MASK GENMASK(7, 0) +#define MHICTRL_MHISTATE_MASK GENMASK(15, 8) +#define MHICTRL_RESET_MASK BIT(1) +#define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) +#define MHISTATUS_SYSERR_MASK BIT(2) +#define MHISTATUS_READY_MASK BIT(0) + +/* MHI BHI registers */ +#define BHI_BHIVERSION_MINOR 0x00 +#define BHI_BHIVERSION_MAJOR 0x04 +#define BHI_IMGADDR_LOW 0x08 +#define BHI_IMGADDR_HIGH 0x0c +#define BHI_IMGSIZE 0x10 +#define BHI_RSVD1 0x14 +#define BHI_IMGTXDB 0x18 +#define BHI_RSVD2 0x1c +#define BHI_INTVEC 0x20 +#define BHI_RSVD3 0x24 +#define BHI_EXECENV 0x28 +#define BHI_STATUS 0x2c +#define BHI_ERRCODE 0x30 +#define BHI_ERRDBG1 0x34 +#define BHI_ERRDBG2 0x38 +#define BHI_ERRDBG3 0x3c +#define BHI_SERIALNU 0x40 +#define BHI_SBLANTIROLLVER 0x44 +#define BHI_NUMSEG 0x48 +#define BHI_MSMHWID(n) (0x4c + (0x4 * (n))) +#define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) +#define BHI_RSVD5 0xc4 + +/* BHI register bits */ +#define BHI_TXDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHI_STATUS_MASK GENMASK(31, 30) +#define BHI_STATUS_ERROR 0x03 +#define BHI_STATUS_SUCCESS 0x02 +#define BHI_STATUS_RESET 0x00 + +/* MHI BHIE registers */ +#define BHIE_MSMSOCID_OFFS 0x00 +#define BHIE_TXVECADDR_LOW_OFFS 0x2c +#define BHIE_TXVECADDR_HIGH_OFFS 0x30 +#define BHIE_TXVECSIZE_OFFS 0x34 +#define BHIE_TXVECDB_OFFS 0x3c +#define BHIE_TXVECSTATUS_OFFS 0x44 +#define BHIE_RXVECADDR_LOW_OFFS 0x60 +#define BHIE_RXVECADDR_HIGH_OFFS 0x64 +#define BHIE_RXVECSIZE_OFFS 0x68 +#define BHIE_RXVECDB_OFFS 0x70 +#define BHIE_RXVECSTATUS_OFFS 0x78 + +/* BHIE register bits */ +#define BHIE_TXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_TXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_TXVECSTATUS_STATUS_ERROR 0x03 +#define BHIE_RXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_RXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_RXVECSTATUS_STATUS_ERROR 0x03 + +#define SOC_HW_VERSION_OFFS 0x224 +#define SOC_HW_VERSION_FAM_NUM_BMSK GENMASK(31, 28) +#define SOC_HW_VERSION_DEV_NUM_BMSK GENMASK(27, 16) +#define SOC_HW_VERSION_MAJOR_VER_BMSK GENMASK(15, 8) +#define SOC_HW_VERSION_MINOR_VER_BMSK GENMASK(7, 0) + +#define EV_CTX_RESERVED_MASK GENMASK(7, 0) +#define EV_CTX_INTMODC_MASK GENMASK(15, 8) +#define EV_CTX_INTMODT_MASK GENMASK(31, 16) struct mhi_event_ctxt { __le32 intmod; __le32 ertype; @@ -151,10 +133,10 @@ struct mhi_event_ctxt { __le64 wp __packed __aligned(4); }; =20 -#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) -#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) -#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) -#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) +#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) +#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) +#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) +#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) struct mhi_chan_ctxt { __le32 chcfg; __le32 chtype; @@ -204,67 +186,71 @@ enum mhi_cmd_type { }; =20 /* No operation command */ -#define MHI_TRE_CMD_NOOP_PTR (0) -#define MHI_TRE_CMD_NOOP_DWORD0 (0) -#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(FIELD_PREP(GENMASK(23, 16), M= HI_CMD_NOP))) +#define MHI_TRE_CMD_NOOP_PTR 0 +#define MHI_TRE_CMD_NOOP_DWORD0 0 +#define MHI_TRE_CMD_NOOP_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), M= HI_CMD_NOP)) =20 /* Channel reset command */ -#define MHI_TRE_CMD_RESET_PTR (0) -#define MHI_TRE_CMD_RESET_DWORD0 (0) -#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31,= 24), chid)) | \ - FIELD_PREP(GENMASK(23, 16), MHI_CMD_RESET_CHAN)) +#define MHI_TRE_CMD_RESET_PTR 0 +#define MHI_TRE_CMD_RESET_DWORD0 0 +#define MHI_TRE_CMD_RESET_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_RESET_CHAN)) =20 /* Channel stop command */ -#define MHI_TRE_CMD_STOP_PTR (0) -#define MHI_TRE_CMD_STOP_DWORD0 (0) -#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid)) | \ - FIELD_PREP(GENMASK(23, 16), MHI_CMD_STOP_CHAN)) +#define MHI_TRE_CMD_STOP_PTR 0 +#define MHI_TRE_CMD_STOP_DWORD0 0 +#define MHI_TRE_CMD_STOP_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_STOP_CHAN)) =20 /* Channel start command */ -#define MHI_TRE_CMD_START_PTR (0) -#define MHI_TRE_CMD_START_DWORD0 (0) -#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32(FIELD_PREP(GENMASK(31,= 24), chid)) | \ - FIELD_PREP(GENMASK(23, 16), MHI_CMD_START_CHAN)) +#define MHI_TRE_CMD_START_PTR 0 +#define MHI_TRE_CMD_START_DWORD0 0 +#define MHI_TRE_CMD_START_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_START_CHAN)) =20 -#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) -#define MHI_TRE_GET_CMD_CHID(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET= _DWORD(tre, 1)))) -#define MHI_TRE_GET_CMD_TYPE(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET= _DWORD(tre, 1)))) +#define MHI_TRE_GET_DWORD(tre, word) le32_to_cpu((tre)->dword[(word)]) +#define MHI_TRE_GET_CMD_CHID(tre) FIELD_GET(GENMASK(31, 24), MHI_TRE_GET_D= WORD(tre, 1)) +#define MHI_TRE_GET_CMD_TYPE(tre) FIELD_GET(GENMASK(23, 16), MHI_TRE_GET_D= WORD(tre, 1)) =20 /* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), code) | \ - FIELD_PREP(GENMASK(15, 0), len))) -#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ - FIELD_PREP(GENMASK(23, 16), type))) -#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) -#define MHI_TRE_GET_EV_CODE(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 0)))) -#define MHI_TRE_GET_EV_LEN(tre) (FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DW= ORD(tre, 0)))) -#define MHI_TRE_GET_EV_CHID(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 1)))) -#define MHI_TRE_GET_EV_TYPE(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_= DWORD(tre, 1)))) -#define MHI_TRE_GET_EV_STATE(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET= _DWORD(tre, 0)))) -#define MHI_TRE_GET_EV_EXECENV(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE_G= ET_DWORD(tre, 0)))) -#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) -#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_VEID(tre) (FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_= DWORD(tre, 0)))) -#define MHI_TRE_GET_EV_LINKSPEED(tre) (FIELD_GET(GENMASK(31, 24), (MHI_TRE= _GET_DWORD(tre, 1)))) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) (FIELD_GET(GENMASK(7, 0), (MHI_TRE_G= ET_DWORD(tre, 0)))) +#define MHI_TRE_EV_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_EV_DWORD0(code, len) cpu_to_le32(FIELD_PREP(GENMASK(31, 24= ), code | \ + FIELD_PREP(GENMASK(15, 0), len))) +#define MHI_TRE_EV_DWORD1(chid, type) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid | \ + FIELD_PREP(GENMASK(23, 16), type))) +#define MHI_TRE_GET_EV_PTR(tre) le64_to_cpu((tre)->ptr) +#define MHI_TRE_GET_EV_CODE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 0))) +#define MHI_TRE_GET_EV_LEN(tre) FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DW= ORD(tre, 0))) +#define MHI_TRE_GET_EV_CHID(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 1))) +#define MHI_TRE_GET_EV_TYPE(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 1))) +#define MHI_TRE_GET_EV_STATE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 0))) +#define MHI_TRE_GET_EV_EXECENV(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GE= T_DWORD(tre, 0))) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) MHI_TRE_GET_EV_PTR(tre) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 0))) +#define MHI_TRE_GET_EV_LINKSPEED(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_= GET_DWORD(tre, 1))) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) FIELD_GET(GENMASK(7, 0), (MHI_TRE_GE= T_DWORD(tre, 0))) =20 /* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) -#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(FIELD_PREP(GENMASK(15, 0), l= en))) -#define MHI_TRE_TYPE_TRANSFER 2 -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32(FIELD_PRE= P(GENMASK(23, 16), \ - MHI_TRE_TYPE_TRANSFER) | \ - FIELD_PREP(BIT(10), bei) | \ - FIELD_PREP(BIT(9), ieot) | \ - FIELD_PREP(BIT(8), ieob) | \ - FIELD_PREP(BIT(0), chain))) +#define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(FIELD_PREP(GENMASK(15, 0), le= n)) +#define MHI_TRE_TYPE_TRANSFER 2 +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) cpu_to_le32(FIELD_PREP= (GENMASK(23, 16), \ + MHI_TRE_TYPE_TRANSFER) | \ + FIELD_PREP(BIT(10), bei) | \ + FIELD_PREP(BIT(9), ieot) | \ + FIELD_PREP(BIT(8), ieob) | \ + FIELD_PREP(BIT(0), chain)) =20 /* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(FIELD_PREP(GENMASK(64, = 48), len) | ptr)) -#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) -#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(FIELD_PREP(GENMASK(23, 16), MH= I_PKT_TYPE_COALESCING) +#define MHI_RSCTRE_DATA_PTR(ptr, len) cpu_to_le64(FIELD_PREP(GENMASK(64, 4= 8), len) | ptr) +#define MHI_RSCTRE_DATA_DWORD0(cookie) cpu_to_le32(cookie) +#define MHI_RSCTRE_DATA_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \ + MHI_PKT_TYPE_COALESCING)) =20 enum mhi_pkt_type { MHI_PKT_TYPE_INVALID =3D 0x0, @@ -369,44 +355,43 @@ enum mhi_pm_state { MHI_PM_STATE_MAX }; =20 -#define MHI_PM_DISABLE BIT(0) -#define MHI_PM_POR BIT(1) -#define MHI_PM_M0 BIT(2) -#define MHI_PM_M2 BIT(3) -#define MHI_PM_M3_ENTER BIT(4) -#define MHI_PM_M3 BIT(5) -#define MHI_PM_M3_EXIT BIT(6) +#define MHI_PM_DISABLE BIT(0) +#define MHI_PM_POR BIT(1) +#define MHI_PM_M0 BIT(2) +#define MHI_PM_M2 BIT(3) +#define MHI_PM_M3_ENTER BIT(4) +#define MHI_PM_M3 BIT(5) +#define MHI_PM_M3_EXIT BIT(6) /* firmware download failure state */ -#define MHI_PM_FW_DL_ERR BIT(7) -#define MHI_PM_SYS_ERR_DETECT BIT(8) -#define MHI_PM_SYS_ERR_PROCESS BIT(9) -#define MHI_PM_SHUTDOWN_PROCESS BIT(10) +#define MHI_PM_FW_DL_ERR BIT(7) +#define MHI_PM_SYS_ERR_DETECT BIT(8) +#define MHI_PM_SYS_ERR_PROCESS BIT(9) +#define MHI_PM_SHUTDOWN_PROCESS BIT(10) /* link not accessible */ -#define MHI_PM_LD_ERR_FATAL_DETECT BIT(11) - -#define MHI_REG_ACCESS_VALID(pm_state) ((pm_state & (MHI_PM_POR | MHI_PM_M= 0 | \ - MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \ - MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \ - MHI_PM_SHUTDOWN_PROCESS | MHI_PM_FW_DL_ERR))) -#define MHI_PM_IN_ERROR_STATE(pm_state) (pm_state >=3D MHI_PM_FW_DL_ERR) -#define MHI_PM_IN_FATAL_STATE(pm_state) (pm_state =3D=3D MHI_PM_LD_ERR_FAT= AL_DETECT) -#define MHI_DB_ACCESS_VALID(mhi_cntrl) (mhi_cntrl->pm_state & \ - mhi_cntrl->db_access) -#define MHI_WAKE_DB_CLEAR_VALID(pm_state) (pm_state & (MHI_PM_M0 | \ - MHI_PM_M2 | MHI_PM_M3_EXIT)) -#define MHI_WAKE_DB_SET_VALID(pm_state) (pm_state & MHI_PM_M2) -#define MHI_WAKE_DB_FORCE_SET_VALID(pm_state) MHI_WAKE_DB_CLEAR_VALID(pm_s= tate) -#define MHI_EVENT_ACCESS_INVALID(pm_state) (pm_state =3D=3D MHI_PM_DISABLE= || \ - MHI_PM_IN_ERROR_STATE(pm_state)) -#define MHI_PM_IN_SUSPEND_STATE(pm_state) (pm_state & \ - (MHI_PM_M3_ENTER | MHI_PM_M3)) - -#define NR_OF_CMD_RINGS 1 -#define CMD_EL_PER_RING 128 -#define PRIMARY_CMD_RING 0 -#define MHI_DEV_WAKE_DB 127 -#define MHI_MAX_MTU 0xffff -#define MHI_RANDOM_U32_NONZERO(bmsk) (prandom_u32_max(bmsk) + 1) +#define MHI_PM_LD_ERR_FATAL_DETECT BIT(11) + +#define MHI_REG_ACCESS_VALID(pm_state) ((pm_state & (MHI_PM_POR | MHI_PM= _M0 | \ + MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \ + MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \ + MHI_PM_SHUTDOWN_PROCESS | MHI_PM_FW_DL_ERR))) +#define MHI_PM_IN_ERROR_STATE(pm_state) (pm_state >=3D MHI_PM_FW_DL_ERR) +#define MHI_PM_IN_FATAL_STATE(pm_state) (pm_state =3D=3D MHI_PM_LD_ERR_F= ATAL_DETECT) +#define MHI_DB_ACCESS_VALID(mhi_cntrl) (mhi_cntrl->pm_state & mhi_cntrl-= >db_access) +#define MHI_WAKE_DB_CLEAR_VALID(pm_state) (pm_state & (MHI_PM_M0 | \ + MHI_PM_M2 | MHI_PM_M3_EXIT)) +#define MHI_WAKE_DB_SET_VALID(pm_state) (pm_state & MHI_PM_M2) +#define MHI_WAKE_DB_FORCE_SET_VALID(pm_state) MHI_WAKE_DB_CLEAR_VALID(pm_= state) +#define MHI_EVENT_ACCESS_INVALID(pm_state) (pm_state =3D=3D MHI_PM_DISABL= E || \ + MHI_PM_IN_ERROR_STATE(pm_state)) +#define MHI_PM_IN_SUSPEND_STATE(pm_state) (pm_state & \ + (MHI_PM_M3_ENTER | MHI_PM_M3)) + +#define NR_OF_CMD_RINGS 1 +#define CMD_EL_PER_RING 128 +#define PRIMARY_CMD_RING 0 +#define MHI_DEV_WAKE_DB 127 +#define MHI_MAX_MTU 0xffff +#define MHI_RANDOM_U32_NONZERO(bmsk) (prandom_u32_max(bmsk) + 1) =20 enum mhi_er_type { MHI_ER_TYPE_INVALID =3D 0x0, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BA22C433EF for ; Mon, 28 Feb 2022 12:44:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236666AbiB1MpZ (ORCPT ); Mon, 28 Feb 2022 07:45:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236607AbiB1MpQ (ORCPT ); Mon, 28 Feb 2022 07:45:16 -0500 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B46D49267 for ; Mon, 28 Feb 2022 04:44:36 -0800 (PST) Received: by mail-pg1-x52a.google.com with SMTP id 132so11270142pga.5 for ; Mon, 28 Feb 2022 04:44:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PE9CgvE4/CMk5CfWwB0BSUGPQ2yftNehgiOsx4r0KEw=; b=UwChw/Uz6Gcrq9v5Doy/tBKQsjyDjQ5n7a3NRfHxBziEBpyo/wXhgmc1k8W56oYjoy pT+kgs816mk2N94a5F2oIRYK0EtQr6vkqdElajp0s50xkND2AODkpRTG3FUVKi6dDt51 hS+9trxIVEFRaZ2idt4L+jyO9C/tVfebq8bXhZz6hGk3Up7i9BynQzgY6VVkpLjw442X hLC5PSSqpx0M/qgDJdEkZod9yzuIDXHxPEdzMhjrlzgZ9VJaMwZdwo6bE7cBEZwMh2cV e0WyN8AMZvGMMy73PipKaCurx6dXslQBDv9kyAT5dKAgSR66cz0XvuqER1QEmZsUpyva sA3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PE9CgvE4/CMk5CfWwB0BSUGPQ2yftNehgiOsx4r0KEw=; b=pzXRRIuMqhyOdeVbjS32IGtNIY7ClBovWCzGXx+GoSmKoe/933wLMP3qgqDDxEnYXT Y3DU343x7znNxMntZgTK2bn8npfji2hbkLz2bDcaI31AxtTkJP7PdB7x8nklL52XSuc9 YUne950KnyZNpcroUJGUAgPv/ATXrrwM1F+uYqCSmfU5pgK4EjwPsqrxB3ouC97OCqyM M1ec82haHrJfcA1PEoE3nxeFonxd+AZr2RBKR6vwTASJ9EbfRHoMnunjN41LuVX2yACD q67g2UqYfM/gucrVN5KN1ce01pqynvoy1vRpsw82Qf2ZddCYSDPxUUrJIt/fYT2/tBho bb6A== X-Gm-Message-State: AOAM533GlyIMFOF4t4F5LqRmQDJtcgQzCHmEfRR6awsBy9B+VGyX2z8r k4YNIBxK53I9aR5T50eDn7xo X-Google-Smtp-Source: ABdhPJxf431kFjK3nyr0xfdblBiIsdWSrIiJOqJT8lyvfuxhzwmlGOCNoh0M+aYMW/AG6n0pEQsCJw== X-Received: by 2002:a63:e59:0:b0:374:a169:d558 with SMTP id 25-20020a630e59000000b00374a169d558mr16850279pgo.304.1646052275358; Mon, 28 Feb 2022 04:44:35 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:35 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 07/27] bus: mhi: host: Rename "struct mhi_tre" to "struct mhi_ring_element" Date: Mon, 28 Feb 2022 18:13:24 +0530 Message-Id: <20220228124344.77359-8-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Structure "struct mhi_tre" is representing a generic MHI ring element and not specifically a Transfer Ring Element (TRE). Fix the naming. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/host/init.c | 6 +++--- drivers/bus/mhi/host/internal.h | 2 +- drivers/bus/mhi/host/main.c | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index ca068a017a42..016dcc35db80 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -339,7 +339,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) er_ctxt->msivec =3D cpu_to_le32(mhi_event->irq); mhi_event->db_cfg.db_mode =3D true; =20 - ring->el_size =3D sizeof(struct mhi_tre); + ring->el_size =3D sizeof(struct mhi_ring_element); ring->len =3D ring->el_size * ring->elements; ret =3D mhi_alloc_aligned_ring(mhi_cntrl, ring, ring->len); if (ret) @@ -371,7 +371,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) for (i =3D 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++, cmd_ctxt++) { struct mhi_ring *ring =3D &mhi_cmd->ring; =20 - ring->el_size =3D sizeof(struct mhi_tre); + ring->el_size =3D sizeof(struct mhi_ring_element); ring->elements =3D CMD_EL_PER_RING; ring->len =3D ring->el_size * ring->elements; ret =3D mhi_alloc_aligned_ring(mhi_cntrl, ring, ring->len); @@ -598,7 +598,7 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, =20 buf_ring =3D &mhi_chan->buf_ring; tre_ring =3D &mhi_chan->tre_ring; - tre_ring->el_size =3D sizeof(struct mhi_tre); + tre_ring->el_size =3D sizeof(struct mhi_ring_element); tre_ring->len =3D tre_ring->el_size * tre_ring->elements; chan_ctxt =3D &mhi_cntrl->mhi_ctxt->chan_ctxt[mhi_chan->chan]; ret =3D mhi_alloc_aligned_ring(mhi_cntrl, tre_ring, tre_ring->len); diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 1c7a48be033f..5860cd326db6 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -168,7 +168,7 @@ struct mhi_ctxt { dma_addr_t cmd_ctxt_addr; }; =20 -struct mhi_tre { +struct mhi_ring_element { __le64 ptr; __le32 dword[2]; }; diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 3e6e615466b7..dabf85b92a84 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -554,7 +554,7 @@ static void mhi_recycle_ev_ring_element(struct mhi_cont= roller *mhi_cntrl, } =20 static int parse_xfer_event(struct mhi_controller *mhi_cntrl, - struct mhi_tre *event, + struct mhi_ring_element *event, struct mhi_chan *mhi_chan) { struct mhi_ring *buf_ring, *tre_ring; @@ -590,7 +590,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_= cntrl, case MHI_EV_CC_EOT: { dma_addr_t ptr =3D MHI_TRE_GET_EV_PTR(event); - struct mhi_tre *local_rp, *ev_tre; + struct mhi_ring_element *local_rp, *ev_tre; void *dev_rp; struct mhi_buf_info *buf_info; u16 xfer_len; @@ -689,7 +689,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_= cntrl, } =20 static int parse_rsc_event(struct mhi_controller *mhi_cntrl, - struct mhi_tre *event, + struct mhi_ring_element *event, struct mhi_chan *mhi_chan) { struct mhi_ring *buf_ring, *tre_ring; @@ -753,12 +753,12 @@ static int parse_rsc_event(struct mhi_controller *mhi= _cntrl, } =20 static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, - struct mhi_tre *tre) + struct mhi_ring_element *tre) { dma_addr_t ptr =3D MHI_TRE_GET_EV_PTR(tre); struct mhi_cmd *cmd_ring =3D &mhi_cntrl->mhi_cmd[PRIMARY_CMD_RING]; struct mhi_ring *mhi_ring =3D &cmd_ring->ring; - struct mhi_tre *cmd_pkt; + struct mhi_ring_element *cmd_pkt; struct mhi_chan *mhi_chan; u32 chan; =20 @@ -791,7 +791,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi= _cntrl, struct mhi_event *mhi_event, u32 event_quota) { - struct mhi_tre *dev_rp, *local_rp; + struct mhi_ring_element *dev_rp, *local_rp; struct mhi_ring *ev_ring =3D &mhi_event->ring; struct mhi_event_ctxt *er_ctxt =3D &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; @@ -961,7 +961,7 @@ int mhi_process_data_event_ring(struct mhi_controller *= mhi_cntrl, struct mhi_event *mhi_event, u32 event_quota) { - struct mhi_tre *dev_rp, *local_rp; + struct mhi_ring_element *dev_rp, *local_rp; struct mhi_ring *ev_ring =3D &mhi_event->ring; struct mhi_event_ctxt *er_ctxt =3D &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; @@ -1185,7 +1185,7 @@ int mhi_gen_tre(struct mhi_controller *mhi_cntrl, str= uct mhi_chan *mhi_chan, struct mhi_buf_info *info, enum mhi_flags flags) { struct mhi_ring *buf_ring, *tre_ring; - struct mhi_tre *mhi_tre; + struct mhi_ring_element *mhi_tre; struct mhi_buf_info *buf_info; int eot, eob, chain, bei; int ret; @@ -1256,7 +1256,7 @@ int mhi_send_cmd(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan, enum mhi_cmd_type cmd) { - struct mhi_tre *cmd_tre =3D NULL; + struct mhi_ring_element *cmd_tre =3D NULL; struct mhi_cmd *mhi_cmd =3D &mhi_cntrl->mhi_cmd[PRIMARY_CMD_RING]; struct mhi_ring *ring =3D &mhi_cmd->ring; struct device *dev =3D &mhi_cntrl->mhi_dev->dev; @@ -1518,7 +1518,7 @@ static void mhi_mark_stale_events(struct mhi_controll= er *mhi_cntrl, int chan) =20 { - struct mhi_tre *dev_rp, *local_rp; + struct mhi_ring_element *dev_rp, *local_rp; struct mhi_ring *ev_ring; struct device *dev =3D &mhi_cntrl->mhi_dev->dev; unsigned long flags; --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 149EEC433EF for ; Mon, 28 Feb 2022 12:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236690AbiB1Mpe (ORCPT ); Mon, 28 Feb 2022 07:45:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236661AbiB1MpZ (ORCPT ); Mon, 28 Feb 2022 07:45:25 -0500 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 707EE496A3 for ; Mon, 28 Feb 2022 04:44:41 -0800 (PST) Received: by mail-pg1-x529.google.com with SMTP id o8so11254969pgf.9 for ; Mon, 28 Feb 2022 04:44:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mq+2jUyDDojokJ6G5zgU1O7JDo/s8dSzxwe2miaI474=; b=lPT690AQPjYaIUgl/dICFrU1p51PiwOLhrZHwO7+apNmxnxEvG701A8oDByBMompGJ aapleXc/bCkjtznpabSfklShBzF/FgHMkv6EAp5uGtXFbK+kOAmTXBUmQ2cx5+/GChq7 b/g4janEZ7wCDsgv7W6D/3S9EIXgkVTYd57ebCmbInNsEAz8d8rEqzC1ajqQ/x7+8yLQ SxAhBiuCktIqD7+wbRN6WhzZEe9Vz+uvjlBEFPZ8zeptK0k0n52imFnRYS2HCCnkQkUn 536w9ifH1nJmuo7o7YnGW807zZCrtevuhO5zewo83hqYwGRUyD77KIt/r8XlWCDwOH9i 9Kaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mq+2jUyDDojokJ6G5zgU1O7JDo/s8dSzxwe2miaI474=; b=0c5cq+PiD4zOC+JX82+I8HWWofZCWUjx/8ccPrLKp/OPuR8I7Kd1CpqgmUwilKhZ+z eHpOb4HNOoBLIfq+vBDuOrGmaUFr3d67GMfxPQyVSf15dS8fne2Ax5mRcjoiWIKbaIwt iANJApYnJrgLq48Z2t683SiVqyIX+SwNVK9INPTaI7cFPzF3CpnX9XwLSadZ8C1kgsQ6 SrnyUMxBmqUPHZMB8qGQwcfa1jP7dcZiurSCh5DySidT7KEVM55xqAUaAJNov6j0G0xi 6g51640xDbbDnMGw/aBLWDxYIOBFy4b5XXplqdcgyFjsyuubBMbTNHyg0bsKfuiAAfd+ zV7g== X-Gm-Message-State: AOAM533JK1f3Q6BTdKbGlVNrPEPTHZ/rWZvScrF2kUAcB7IF4QjIPkw5 tIiJBfws2P9E41nUVcaP4qH7 X-Google-Smtp-Source: ABdhPJxsHyRCwe8dcLVU1taJ/pQX51M0XKnRVRZssMcMTsy0/FWKh4Wh2yWV4P3rVsHFi23cScFZng== X-Received: by 2002:a63:8549:0:b0:36c:2a9e:d247 with SMTP id u70-20020a638549000000b0036c2a9ed247mr16929760pgd.161.1646052280833; Mon, 28 Feb 2022 04:44:40 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:40 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v4 08/27] bus: mhi: Move common MHI definitions out of host directory Date: Mon, 28 Feb 2022 18:13:25 +0530 Message-Id: <20220228124344.77359-9-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Move the common MHI definitions in host "internal.h" to "common.h" so that the endpoint code can make use of them. This also avoids duplicating the definitions in the endpoint stack. Reviewed-by: Hemant Kumar Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/common.h | 283 ++++++++++++++++++++++++++++++++ drivers/bus/mhi/host/internal.h | 264 +---------------------------- 2 files changed, 284 insertions(+), 263 deletions(-) create mode 100644 drivers/bus/mhi/common.h diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h new file mode 100644 index 000000000000..f2690bf11c99 --- /dev/null +++ b/drivers/bus/mhi/common.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022, Linaro Ltd. + * + */ + +#ifndef _MHI_COMMON_H +#define _MHI_COMMON_H + +#include +#include + +/* MHI registers */ +#define MHIREGLEN 0x00 +#define MHIVER 0x08 +#define MHICFG 0x10 +#define CHDBOFF 0x18 +#define ERDBOFF 0x20 +#define BHIOFF 0x28 +#define BHIEOFF 0x2c +#define DEBUGOFF 0x30 +#define MHICTRL 0x38 +#define MHISTATUS 0x48 +#define CCABAP_LOWER 0x58 +#define CCABAP_HIGHER 0x5c +#define ECABAP_LOWER 0x60 +#define ECABAP_HIGHER 0x64 +#define CRCBAP_LOWER 0x68 +#define CRCBAP_HIGHER 0x6c +#define CRDB_LOWER 0x70 +#define CRDB_HIGHER 0x74 +#define MHICTRLBASE_LOWER 0x80 +#define MHICTRLBASE_HIGHER 0x84 +#define MHICTRLLIMIT_LOWER 0x88 +#define MHICTRLLIMIT_HIGHER 0x8c +#define MHIDATABASE_LOWER 0x98 +#define MHIDATABASE_HIGHER 0x9c +#define MHIDATALIMIT_LOWER 0xa0 +#define MHIDATALIMIT_HIGHER 0xa4 + +/* MHI BHI registers */ +#define BHI_BHIVERSION_MINOR 0x00 +#define BHI_BHIVERSION_MAJOR 0x04 +#define BHI_IMGADDR_LOW 0x08 +#define BHI_IMGADDR_HIGH 0x0c +#define BHI_IMGSIZE 0x10 +#define BHI_RSVD1 0x14 +#define BHI_IMGTXDB 0x18 +#define BHI_RSVD2 0x1c +#define BHI_INTVEC 0x20 +#define BHI_RSVD3 0x24 +#define BHI_EXECENV 0x28 +#define BHI_STATUS 0x2c +#define BHI_ERRCODE 0x30 +#define BHI_ERRDBG1 0x34 +#define BHI_ERRDBG2 0x38 +#define BHI_ERRDBG3 0x3c +#define BHI_SERIALNU 0x40 +#define BHI_SBLANTIROLLVER 0x44 +#define BHI_NUMSEG 0x48 +#define BHI_MSMHWID(n) (0x4c + (0x4 * (n))) +#define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) +#define BHI_RSVD5 0xc4 + +/* BHI register bits */ +#define BHI_TXDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHI_TXDB_SEQNUM_SHFT 0 +#define BHI_STATUS_MASK GENMASK(31, 30) +#define BHI_STATUS_ERROR 0x03 +#define BHI_STATUS_SUCCESS 0x02 +#define BHI_STATUS_RESET 0x00 + +/* MHI BHIE registers */ +#define BHIE_MSMSOCID_OFFS 0x00 +#define BHIE_TXVECADDR_LOW_OFFS 0x2c +#define BHIE_TXVECADDR_HIGH_OFFS 0x30 +#define BHIE_TXVECSIZE_OFFS 0x34 +#define BHIE_TXVECDB_OFFS 0x3c +#define BHIE_TXVECSTATUS_OFFS 0x44 +#define BHIE_RXVECADDR_LOW_OFFS 0x60 +#define BHIE_RXVECADDR_HIGH_OFFS 0x64 +#define BHIE_RXVECSIZE_OFFS 0x68 +#define BHIE_RXVECDB_OFFS 0x70 +#define BHIE_RXVECSTATUS_OFFS 0x78 + +/* BHIE register bits */ +#define BHIE_TXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECDB_SEQNUM_SHFT 0 +#define BHIE_TXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_TXVECSTATUS_SEQNUM_SHFT 0 +#define BHIE_TXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_TXVECSTATUS_STATUS_SHFT 30 +#define BHIE_TXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_TXVECSTATUS_STATUS_ERROR 0x03 +#define BHIE_RXVECDB_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECDB_SEQNUM_SHFT 0 +#define BHIE_RXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) +#define BHIE_RXVECSTATUS_SEQNUM_SHFT 0 +#define BHIE_RXVECSTATUS_STATUS_BMSK GENMASK(31, 30) +#define BHIE_RXVECSTATUS_STATUS_SHFT 30 +#define BHIE_RXVECSTATUS_STATUS_RESET 0x00 +#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL 0x02 +#define BHIE_RXVECSTATUS_STATUS_ERROR 0x03 + +/* MHI register bits */ +#define MHICFG_NHWER_MASK GENMASK(31, 24) +#define MHICFG_NER_MASK GENMASK(23, 16) +#define MHICFG_NHWCH_MASK GENMASK(15, 8) +#define MHICFG_NCH_MASK GENMASK(7, 0) +#define MHICTRL_MHISTATE_MASK GENMASK(15, 8) +#define MHICTRL_RESET_MASK BIT(1) +#define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) +#define MHISTATUS_SYSERR_MASK BIT(2) +#define MHISTATUS_READY_MASK BIT(0) + +/* Command Ring Element macros */ +/* No operation command */ +#define MHI_TRE_CMD_NOOP_PTR 0 +#define MHI_TRE_CMD_NOOP_DWORD0 0 +#define MHI_TRE_CMD_NOOP_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), M= HI_CMD_NOP)) + +/* Channel reset command */ +#define MHI_TRE_CMD_RESET_PTR 0 +#define MHI_TRE_CMD_RESET_DWORD0 0 +#define MHI_TRE_CMD_RESET_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_RESET_CHAN)) + +/* Channel stop command */ +#define MHI_TRE_CMD_STOP_PTR 0 +#define MHI_TRE_CMD_STOP_DWORD0 0 +#define MHI_TRE_CMD_STOP_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_STOP_CHAN)) + +/* Channel start command */ +#define MHI_TRE_CMD_START_PTR 0 +#define MHI_TRE_CMD_START_DWORD0 0 +#define MHI_TRE_CMD_START_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ + FIELD_PREP(GENMASK(23, 16), \ + MHI_CMD_START_CHAN)) + +#define MHI_TRE_GET_DWORD(tre, word) le32_to_cpu((tre)->dword[(word)]) +#define MHI_TRE_GET_CMD_CHID(tre) FIELD_GET(GENMASK(31, 24), MHI_TRE_GET_D= WORD(tre, 1)) +#define MHI_TRE_GET_CMD_TYPE(tre) FIELD_GET(GENMASK(23, 16), MHI_TRE_GET_D= WORD(tre, 1)) + +/* Event descriptor macros */ +#define MHI_TRE_EV_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_EV_DWORD0(code, len) cpu_to_le32(FIELD_PREP(GENMASK(31, 24= ), code) | \ + FIELD_PREP(GENMASK(15, 0), len)) +#define MHI_TRE_EV_DWORD1(chid, type) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid) | \ + FIELD_PREP(GENMASK(23, 16), type)) +#define MHI_TRE_GET_EV_PTR(tre) le64_to_cpu((tre)->ptr) +#define MHI_TRE_GET_EV_CODE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 0))) +#define MHI_TRE_GET_EV_LEN(tre) FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DW= ORD(tre, 0))) +#define MHI_TRE_GET_EV_CHID(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 1))) +#define MHI_TRE_GET_EV_TYPE(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 1))) +#define MHI_TRE_GET_EV_STATE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 0))) +#define MHI_TRE_GET_EV_EXECENV(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GE= T_DWORD(tre, 0))) +#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) +#define MHI_TRE_GET_EV_TIME(tre) MHI_TRE_GET_EV_PTR(tre) +#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) +#define MHI_TRE_GET_EV_VEID(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 0))) +#define MHI_TRE_GET_EV_LINKSPEED(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_= GET_DWORD(tre, 1))) +#define MHI_TRE_GET_EV_LINKWIDTH(tre) FIELD_GET(GENMASK(7, 0), (MHI_TRE_GE= T_DWORD(tre, 0))) + +/* Transfer descriptor macros */ +#define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) +#define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(FIELD_PREP(GENMASK(15, 0), le= n)) +#define MHI_TRE_TYPE_TRANSFER 2 +#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) cpu_to_le32(FIELD_PREP= (GENMASK(23, 16), \ + MHI_TRE_TYPE_TRANSFER) | \ + FIELD_PREP(BIT(10), bei) | \ + FIELD_PREP(BIT(9), ieot) | \ + FIELD_PREP(BIT(8), ieob) | \ + FIELD_PREP(BIT(0), chain)) + +/* RSC transfer descriptor macros */ +#define MHI_RSCTRE_DATA_PTR(ptr, len) cpu_to_le64(FIELD_PREP(GENMASK(64, 4= 8), len) | ptr) +#define MHI_RSCTRE_DATA_DWORD0(cookie) cpu_to_le32(cookie) +#define MHI_RSCTRE_DATA_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \ + MHI_PKT_TYPE_COALESCING)) + +enum mhi_pkt_type { + MHI_PKT_TYPE_INVALID =3D 0x0, + MHI_PKT_TYPE_NOOP_CMD =3D 0x1, + MHI_PKT_TYPE_TRANSFER =3D 0x2, + MHI_PKT_TYPE_COALESCING =3D 0x8, + MHI_PKT_TYPE_RESET_CHAN_CMD =3D 0x10, + MHI_PKT_TYPE_STOP_CHAN_CMD =3D 0x11, + MHI_PKT_TYPE_START_CHAN_CMD =3D 0x12, + MHI_PKT_TYPE_STATE_CHANGE_EVENT =3D 0x20, + MHI_PKT_TYPE_CMD_COMPLETION_EVENT =3D 0x21, + MHI_PKT_TYPE_TX_EVENT =3D 0x22, + MHI_PKT_TYPE_RSC_TX_EVENT =3D 0x28, + MHI_PKT_TYPE_EE_EVENT =3D 0x40, + MHI_PKT_TYPE_TSYNC_EVENT =3D 0x48, + MHI_PKT_TYPE_BW_REQ_EVENT =3D 0x50, + MHI_PKT_TYPE_STALE_EVENT, /* internal event */ +}; + +/* MHI transfer completion events */ +enum mhi_ev_ccs { + MHI_EV_CC_INVALID =3D 0x0, + MHI_EV_CC_SUCCESS =3D 0x1, + MHI_EV_CC_EOT =3D 0x2, /* End of transfer event */ + MHI_EV_CC_OVERFLOW =3D 0x3, + MHI_EV_CC_EOB =3D 0x4, /* End of block event */ + MHI_EV_CC_OOB =3D 0x5, /* Out of block event */ + MHI_EV_CC_DB_MODE =3D 0x6, + MHI_EV_CC_UNDEFINED_ERR =3D 0x10, + MHI_EV_CC_BAD_TRE =3D 0x11, +}; + +/* Channel state */ +enum mhi_ch_state { + MHI_CH_STATE_DISABLED, + MHI_CH_STATE_ENABLED, + MHI_CH_STATE_RUNNING, + MHI_CH_STATE_SUSPENDED, + MHI_CH_STATE_STOP, + MHI_CH_STATE_ERROR, +}; + +enum mhi_cmd_type { + MHI_CMD_NOP =3D 1, + MHI_CMD_RESET_CHAN =3D 16, + MHI_CMD_STOP_CHAN =3D 17, + MHI_CMD_START_CHAN =3D 18, +}; + +#define EV_CTX_RESERVED_MASK GENMASK(7, 0) +#define EV_CTX_INTMODC_MASK GENMASK(15, 8) +#define EV_CTX_INTMODT_MASK GENMASK(31, 16) +struct mhi_event_ctxt { + __le32 intmod; + __le32 ertype; + __le32 msivec; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) +#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) +#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) +#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) +struct mhi_chan_ctxt { + __le32 chcfg; + __le32 chtype; + __le32 erindex; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +struct mhi_cmd_ctxt { + __le32 reserved0; + __le32 reserved1; + __le32 reserved2; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +struct mhi_ring_element { + __le64 ptr; + __le32 dword[2]; +}; + +extern const char * const mhi_state_str[MHI_STATE_MAX]; +#define TO_MHI_STATE_STR(state) ((state >=3D MHI_STATE_MAX || \ + !mhi_state_str[state]) ? \ + "INVALID_STATE" : mhi_state_str[state]) + +#endif /* _MHI_COMMON_H */ diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 5860cd326db6..b47d8ef2624a 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -7,158 +7,20 @@ #ifndef _MHI_INT_H #define _MHI_INT_H =20 -#include -#include +#include "../common.h" =20 extern struct bus_type mhi_bus_type; =20 -/* MHI registers */ -#define MHIREGLEN 0x00 -#define MHIVER 0x08 -#define MHICFG 0x10 -#define CHDBOFF 0x18 -#define ERDBOFF 0x20 -#define BHIOFF 0x28 -#define BHIEOFF 0x2c -#define DEBUGOFF 0x30 -#define MHICTRL 0x38 -#define MHISTATUS 0x48 -#define CCABAP_LOWER 0x58 -#define CCABAP_HIGHER 0x5c -#define ECABAP_LOWER 0x60 -#define ECABAP_HIGHER 0x64 -#define CRCBAP_LOWER 0x68 -#define CRCBAP_HIGHER 0x6c -#define CRDB_LOWER 0x70 -#define CRDB_HIGHER 0x74 -#define MHICTRLBASE_LOWER 0x80 -#define MHICTRLBASE_HIGHER 0x84 -#define MHICTRLLIMIT_LOWER 0x88 -#define MHICTRLLIMIT_HIGHER 0x8c -#define MHIDATABASE_LOWER 0x98 -#define MHIDATABASE_HIGHER 0x9c -#define MHIDATALIMIT_LOWER 0xa0 -#define MHIDATALIMIT_HIGHER 0xa4 - /* Host request register */ #define MHI_SOC_RESET_REQ_OFFSET 0xb0 #define MHI_SOC_RESET_REQ BIT(0) =20 -/* MHI register bits */ -#define MHICFG_NHWER_MASK GENMASK(31, 24) -#define MHICFG_NER_MASK GENMASK(23, 16) -#define MHICFG_NHWCH_MASK GENMASK(15, 8) -#define MHICFG_NCH_MASK GENMASK(7, 0) -#define MHICTRL_MHISTATE_MASK GENMASK(15, 8) -#define MHICTRL_RESET_MASK BIT(1) -#define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) -#define MHISTATUS_SYSERR_MASK BIT(2) -#define MHISTATUS_READY_MASK BIT(0) - -/* MHI BHI registers */ -#define BHI_BHIVERSION_MINOR 0x00 -#define BHI_BHIVERSION_MAJOR 0x04 -#define BHI_IMGADDR_LOW 0x08 -#define BHI_IMGADDR_HIGH 0x0c -#define BHI_IMGSIZE 0x10 -#define BHI_RSVD1 0x14 -#define BHI_IMGTXDB 0x18 -#define BHI_RSVD2 0x1c -#define BHI_INTVEC 0x20 -#define BHI_RSVD3 0x24 -#define BHI_EXECENV 0x28 -#define BHI_STATUS 0x2c -#define BHI_ERRCODE 0x30 -#define BHI_ERRDBG1 0x34 -#define BHI_ERRDBG2 0x38 -#define BHI_ERRDBG3 0x3c -#define BHI_SERIALNU 0x40 -#define BHI_SBLANTIROLLVER 0x44 -#define BHI_NUMSEG 0x48 -#define BHI_MSMHWID(n) (0x4c + (0x4 * (n))) -#define BHI_OEMPKHASH(n) (0x64 + (0x4 * (n))) -#define BHI_RSVD5 0xc4 - -/* BHI register bits */ -#define BHI_TXDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHI_STATUS_MASK GENMASK(31, 30) -#define BHI_STATUS_ERROR 0x03 -#define BHI_STATUS_SUCCESS 0x02 -#define BHI_STATUS_RESET 0x00 - -/* MHI BHIE registers */ -#define BHIE_MSMSOCID_OFFS 0x00 -#define BHIE_TXVECADDR_LOW_OFFS 0x2c -#define BHIE_TXVECADDR_HIGH_OFFS 0x30 -#define BHIE_TXVECSIZE_OFFS 0x34 -#define BHIE_TXVECDB_OFFS 0x3c -#define BHIE_TXVECSTATUS_OFFS 0x44 -#define BHIE_RXVECADDR_LOW_OFFS 0x60 -#define BHIE_RXVECADDR_HIGH_OFFS 0x64 -#define BHIE_RXVECSIZE_OFFS 0x68 -#define BHIE_RXVECDB_OFFS 0x70 -#define BHIE_RXVECSTATUS_OFFS 0x78 - -/* BHIE register bits */ -#define BHIE_TXVECDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_TXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_TXVECSTATUS_STATUS_BMSK GENMASK(31, 30) -#define BHIE_TXVECSTATUS_STATUS_RESET 0x00 -#define BHIE_TXVECSTATUS_STATUS_XFER_COMPL 0x02 -#define BHIE_TXVECSTATUS_STATUS_ERROR 0x03 -#define BHIE_RXVECDB_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_RXVECSTATUS_SEQNUM_BMSK GENMASK(29, 0) -#define BHIE_RXVECSTATUS_STATUS_BMSK GENMASK(31, 30) -#define BHIE_RXVECSTATUS_STATUS_RESET 0x00 -#define BHIE_RXVECSTATUS_STATUS_XFER_COMPL 0x02 -#define BHIE_RXVECSTATUS_STATUS_ERROR 0x03 - #define SOC_HW_VERSION_OFFS 0x224 #define SOC_HW_VERSION_FAM_NUM_BMSK GENMASK(31, 28) #define SOC_HW_VERSION_DEV_NUM_BMSK GENMASK(27, 16) #define SOC_HW_VERSION_MAJOR_VER_BMSK GENMASK(15, 8) #define SOC_HW_VERSION_MINOR_VER_BMSK GENMASK(7, 0) =20 -#define EV_CTX_RESERVED_MASK GENMASK(7, 0) -#define EV_CTX_INTMODC_MASK GENMASK(15, 8) -#define EV_CTX_INTMODT_MASK GENMASK(31, 16) -struct mhi_event_ctxt { - __le32 intmod; - __le32 ertype; - __le32 msivec; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - -#define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) -#define CHAN_CTX_BRSTMODE_MASK GENMASK(9, 8) -#define CHAN_CTX_POLLCFG_MASK GENMASK(15, 10) -#define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) -struct mhi_chan_ctxt { - __le32 chcfg; - __le32 chtype; - __le32 erindex; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - -struct mhi_cmd_ctxt { - __le32 reserved0; - __le32 reserved1; - __le32 reserved2; - - __le64 rbase __packed __aligned(4); - __le64 rlen __packed __aligned(4); - __le64 rp __packed __aligned(4); - __le64 wp __packed __aligned(4); -}; - struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; struct mhi_chan_ctxt *chan_ctxt; @@ -168,130 +30,11 @@ struct mhi_ctxt { dma_addr_t cmd_ctxt_addr; }; =20 -struct mhi_ring_element { - __le64 ptr; - __le32 dword[2]; -}; - struct bhi_vec_entry { u64 dma_addr; u64 size; }; =20 -enum mhi_cmd_type { - MHI_CMD_NOP =3D 1, - MHI_CMD_RESET_CHAN =3D 16, - MHI_CMD_STOP_CHAN =3D 17, - MHI_CMD_START_CHAN =3D 18, -}; - -/* No operation command */ -#define MHI_TRE_CMD_NOOP_PTR 0 -#define MHI_TRE_CMD_NOOP_DWORD0 0 -#define MHI_TRE_CMD_NOOP_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), M= HI_CMD_NOP)) - -/* Channel reset command */ -#define MHI_TRE_CMD_RESET_PTR 0 -#define MHI_TRE_CMD_RESET_DWORD0 0 -#define MHI_TRE_CMD_RESET_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ - FIELD_PREP(GENMASK(23, 16), \ - MHI_CMD_RESET_CHAN)) - -/* Channel stop command */ -#define MHI_TRE_CMD_STOP_PTR 0 -#define MHI_TRE_CMD_STOP_DWORD0 0 -#define MHI_TRE_CMD_STOP_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid) | \ - FIELD_PREP(GENMASK(23, 16), \ - MHI_CMD_STOP_CHAN)) - -/* Channel start command */ -#define MHI_TRE_CMD_START_PTR 0 -#define MHI_TRE_CMD_START_DWORD0 0 -#define MHI_TRE_CMD_START_DWORD1(chid) cpu_to_le32(FIELD_PREP(GENMASK(31, = 24), chid) | \ - FIELD_PREP(GENMASK(23, 16), \ - MHI_CMD_START_CHAN)) - -#define MHI_TRE_GET_DWORD(tre, word) le32_to_cpu((tre)->dword[(word)]) -#define MHI_TRE_GET_CMD_CHID(tre) FIELD_GET(GENMASK(31, 24), MHI_TRE_GET_D= WORD(tre, 1)) -#define MHI_TRE_GET_CMD_TYPE(tre) FIELD_GET(GENMASK(23, 16), MHI_TRE_GET_D= WORD(tre, 1)) - -/* Event descriptor macros */ -#define MHI_TRE_EV_PTR(ptr) cpu_to_le64(ptr) -#define MHI_TRE_EV_DWORD0(code, len) cpu_to_le32(FIELD_PREP(GENMASK(31, 24= ), code | \ - FIELD_PREP(GENMASK(15, 0), len))) -#define MHI_TRE_EV_DWORD1(chid, type) cpu_to_le32(FIELD_PREP(GENMASK(31, 2= 4), chid | \ - FIELD_PREP(GENMASK(23, 16), type))) -#define MHI_TRE_GET_EV_PTR(tre) le64_to_cpu((tre)->ptr) -#define MHI_TRE_GET_EV_CODE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 0))) -#define MHI_TRE_GET_EV_LEN(tre) FIELD_GET(GENMASK(15, 0), (MHI_TRE_GET_DW= ORD(tre, 0))) -#define MHI_TRE_GET_EV_CHID(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_D= WORD(tre, 1))) -#define MHI_TRE_GET_EV_TYPE(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 1))) -#define MHI_TRE_GET_EV_STATE(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GET_= DWORD(tre, 0))) -#define MHI_TRE_GET_EV_EXECENV(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_GE= T_DWORD(tre, 0))) -#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) -#define MHI_TRE_GET_EV_TIME(tre) MHI_TRE_GET_EV_PTR(tre) -#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) -#define MHI_TRE_GET_EV_VEID(tre) FIELD_GET(GENMASK(23, 16), (MHI_TRE_GET_D= WORD(tre, 0))) -#define MHI_TRE_GET_EV_LINKSPEED(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_= GET_DWORD(tre, 1))) -#define MHI_TRE_GET_EV_LINKWIDTH(tre) FIELD_GET(GENMASK(7, 0), (MHI_TRE_GE= T_DWORD(tre, 0))) - -/* Transfer descriptor macros */ -#define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) -#define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(FIELD_PREP(GENMASK(15, 0), le= n)) -#define MHI_TRE_TYPE_TRANSFER 2 -#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) cpu_to_le32(FIELD_PREP= (GENMASK(23, 16), \ - MHI_TRE_TYPE_TRANSFER) | \ - FIELD_PREP(BIT(10), bei) | \ - FIELD_PREP(BIT(9), ieot) | \ - FIELD_PREP(BIT(8), ieob) | \ - FIELD_PREP(BIT(0), chain)) - -/* RSC transfer descriptor macros */ -#define MHI_RSCTRE_DATA_PTR(ptr, len) cpu_to_le64(FIELD_PREP(GENMASK(64, 4= 8), len) | ptr) -#define MHI_RSCTRE_DATA_DWORD0(cookie) cpu_to_le32(cookie) -#define MHI_RSCTRE_DATA_DWORD1 cpu_to_le32(FIELD_PREP(GENMASK(23, 16), \ - MHI_PKT_TYPE_COALESCING)) - -enum mhi_pkt_type { - MHI_PKT_TYPE_INVALID =3D 0x0, - MHI_PKT_TYPE_NOOP_CMD =3D 0x1, - MHI_PKT_TYPE_TRANSFER =3D 0x2, - MHI_PKT_TYPE_COALESCING =3D 0x8, - MHI_PKT_TYPE_RESET_CHAN_CMD =3D 0x10, - MHI_PKT_TYPE_STOP_CHAN_CMD =3D 0x11, - MHI_PKT_TYPE_START_CHAN_CMD =3D 0x12, - MHI_PKT_TYPE_STATE_CHANGE_EVENT =3D 0x20, - MHI_PKT_TYPE_CMD_COMPLETION_EVENT =3D 0x21, - MHI_PKT_TYPE_TX_EVENT =3D 0x22, - MHI_PKT_TYPE_RSC_TX_EVENT =3D 0x28, - MHI_PKT_TYPE_EE_EVENT =3D 0x40, - MHI_PKT_TYPE_TSYNC_EVENT =3D 0x48, - MHI_PKT_TYPE_BW_REQ_EVENT =3D 0x50, - MHI_PKT_TYPE_STALE_EVENT, /* internal event */ -}; - -/* MHI transfer completion events */ -enum mhi_ev_ccs { - MHI_EV_CC_INVALID =3D 0x0, - MHI_EV_CC_SUCCESS =3D 0x1, - MHI_EV_CC_EOT =3D 0x2, /* End of transfer event */ - MHI_EV_CC_OVERFLOW =3D 0x3, - MHI_EV_CC_EOB =3D 0x4, /* End of block event */ - MHI_EV_CC_OOB =3D 0x5, /* Out of block event */ - MHI_EV_CC_DB_MODE =3D 0x6, - MHI_EV_CC_UNDEFINED_ERR =3D 0x10, - MHI_EV_CC_BAD_TRE =3D 0x11, -}; - -enum mhi_ch_state { - MHI_CH_STATE_DISABLED =3D 0x0, - MHI_CH_STATE_ENABLED =3D 0x1, - MHI_CH_STATE_RUNNING =3D 0x2, - MHI_CH_STATE_SUSPENDED =3D 0x3, - MHI_CH_STATE_STOP =3D 0x4, - MHI_CH_STATE_ERROR =3D 0x5, -}; - enum mhi_ch_state_type { MHI_CH_STATE_TYPE_RESET, MHI_CH_STATE_TYPE_STOP, @@ -333,11 +76,6 @@ extern const char * const dev_state_tran_str[DEV_ST_TRA= NSITION_MAX]; #define TO_DEV_STATE_TRANS_STR(state) (((state) >=3D DEV_ST_TRANSITION_MAX= ) ? \ "INVALID_STATE" : dev_state_tran_str[state]) =20 -extern const char * const mhi_state_str[MHI_STATE_MAX]; -#define TO_MHI_STATE_STR(state) ((state >=3D MHI_STATE_MAX || \ - !mhi_state_str[state]) ? \ - "INVALID_STATE" : mhi_state_str[state]) - /* internal power states */ enum mhi_pm_state { MHI_PM_STATE_DISABLE, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57EC3C4332F for ; Mon, 28 Feb 2022 12:45:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236682AbiB1Mpt (ORCPT ); Mon, 28 Feb 2022 07:45:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236660AbiB1Mpe (ORCPT ); Mon, 28 Feb 2022 07:45:34 -0500 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68A1F70CFD for ; Mon, 28 Feb 2022 04:44:47 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id c9so10652088pll.0 for ; Mon, 28 Feb 2022 04:44:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8XW1DXTUUHZ5Z5Syo/ynDiVEDVbCzVzE/LdyTRsVwy8=; b=BFSPOxBUwQ2ic9VQq7Da5uUlpUvg5prCb77ip8BmkHVBsq495LI2S7NxCLjoJgqOgE o+y7EQ8B5gZS7LnWm6ylRuaZSDji/GNzVODGtvWMwagkTi5Wh1hF/opqWKT1FHaHs94f ZE8uBFr6WrF4t+lqf4SvqKvHjeGH576Sa8WNt5BlTQh8nVfCKCh0wwi+bQYLA82vpfbC jI4eBundwdiyjlz3XZV7R2B9U7UHFvIdTrIkl3JDusHqwWljCZOYKltNc+vsPQ86O/4I tN3HLEhe56taK3vNcOjQ8ZDdLbvLmSRLwfsmam2nDN0dBstrLVHRC/yD0xx7PmdOOlpC wXdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8XW1DXTUUHZ5Z5Syo/ynDiVEDVbCzVzE/LdyTRsVwy8=; b=nzwo9WcaxweuVL96BB5/weVhKAnd8jrHCIJZlyez6fryCdYEJrFAuFXA2U3zLRPkan Xz2qnE4EZCD3SyFEWusIcIDBt9iORCXPYFV7mwbDVBlNuqwy1qwMC5I7akMJ0Sy8MLt9 XTWnlUY1Cjc2cbQLyFWcSg2I1uReqFezboKIz9eHRmaSZQYTtkPJOo8ODCK9tPp09pnW 74f+r4QY9zPa7LC4iu9syhz4d7AmhzPSwvqh3daloFDFQUn5TXRb1yQ9HKkulNevcAbR LAb46S6cw1SlnZoOvFLNcTMytCFAUndJS7nG0YIibzf0vzxzviuKcuFEpjVAzbCt43mR Y71w== X-Gm-Message-State: AOAM533XWdxL5fwKH0w8qDEou3ot6uYJxepleiSPnpi0VzaMKbGKfYE8 hFSqNzryezg8gLr51xSZxo+C X-Google-Smtp-Source: ABdhPJxKpp+glzQIp7wyN6o1dTiUL3cT6S2WBnSxDCx4MXU22iqzGE7UczsqWmqcM7XSPn3RX4/Iuw== X-Received: by 2002:a17:902:cf02:b0:14f:e0c2:1514 with SMTP id i2-20020a170902cf0200b0014fe0c21514mr20483417plg.90.1646052286817; Mon, 28 Feb 2022 04:44:46 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:46 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v4 09/27] bus: mhi: Make mhi_state_str[] array static inline and move to common.h Date: Mon, 28 Feb 2022 18:13:26 +0530 Message-Id: <20220228124344.77359-10-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" mhi_state_str[] array could be used by MHI endpoint stack also. So let's make the array as "static inline function" and move it inside the "common.h" header so that the endpoint stack could also make use of it. Reviewed-by: Hemant Kumar Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/common.h | 29 +++++++++++++++++++++++++---- drivers/bus/mhi/host/boot.c | 2 +- drivers/bus/mhi/host/debugfs.c | 6 +++--- drivers/bus/mhi/host/init.c | 12 ------------ drivers/bus/mhi/host/main.c | 8 ++++---- drivers/bus/mhi/host/pm.c | 14 +++++++------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index f2690bf11c99..ec75ba1e6686 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -275,9 +275,30 @@ struct mhi_ring_element { __le32 dword[2]; }; =20 -extern const char * const mhi_state_str[MHI_STATE_MAX]; -#define TO_MHI_STATE_STR(state) ((state >=3D MHI_STATE_MAX || \ - !mhi_state_str[state]) ? \ - "INVALID_STATE" : mhi_state_str[state]) +static inline const char * const mhi_state_str(enum mhi_state state) +{ + switch (state) { + case MHI_STATE_RESET: + return "RESET"; + case MHI_STATE_READY: + return "READY"; + case MHI_STATE_M0: + return "M0"; + case MHI_STATE_M1: + return "M1"; + case MHI_STATE_M2: + return "M2"; + case MHI_STATE_M3: + return "M3"; + case MHI_STATE_M3_FAST: + return "M3 FAST"; + case MHI_STATE_BHI: + return "BHI"; + case MHI_STATE_SYS_ERR: + return "SYS ERROR"; + default: + return "Unknown state"; + } +}; =20 #endif /* _MHI_COMMON_H */ diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index d5ba3c7efb61..b0da7ca4519c 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -67,7 +67,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_contro= ller *mhi_cntrl) =20 dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); =20 /* diff --git a/drivers/bus/mhi/host/debugfs.c b/drivers/bus/mhi/host/debugfs.c index bdc875d7bd4d..cfec7811dfbb 100644 --- a/drivers/bus/mhi/host/debugfs.c +++ b/drivers/bus/mhi/host/debugfs.c @@ -20,7 +20,7 @@ static int mhi_debugfs_states_show(struct seq_file *m, vo= id *d) seq_printf(m, "PM state: %s Device: %s MHI state: %s EE: %s wake: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), mhi_is_active(mhi_cntrl) ? "Active" : "Inactive", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee), mhi_cntrl->wake_set ? "true" : "false"); =20 @@ -206,13 +206,13 @@ static int mhi_debugfs_regdump_show(struct seq_file *= m, void *d) =20 seq_printf(m, "Host PM state: %s Device state: %s EE: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); =20 state =3D mhi_get_mhi_state(mhi_cntrl); ee =3D mhi_get_exec_env(mhi_cntrl); seq_printf(m, "Device EE: %s state: %s\n", TO_MHI_EXEC_STR(ee), - TO_MHI_STATE_STR(state)); + mhi_state_str(state)); =20 for (i =3D 0; regs[i].name; i++) { if (!regs[i].base) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 016dcc35db80..a665b8e92408 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -45,18 +45,6 @@ const char * const dev_state_tran_str[DEV_ST_TRANSITION_= MAX] =3D { [DEV_ST_TRANSITION_DISABLE] =3D "DISABLE", }; =20 -const char * const mhi_state_str[MHI_STATE_MAX] =3D { - [MHI_STATE_RESET] =3D "RESET", - [MHI_STATE_READY] =3D "READY", - [MHI_STATE_M0] =3D "M0", - [MHI_STATE_M1] =3D "M1", - [MHI_STATE_M2] =3D "M2", - [MHI_STATE_M3] =3D "M3", - [MHI_STATE_M3_FAST] =3D "M3 FAST", - [MHI_STATE_BHI] =3D "BHI", - [MHI_STATE_SYS_ERR] =3D "SYS ERROR", -}; - const char * const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX] =3D { [MHI_CH_STATE_TYPE_RESET] =3D "RESET", [MHI_CH_STATE_TYPE_STOP] =3D "STOP", diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index dabf85b92a84..9021be7f2359 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -477,8 +477,8 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number,= void *priv) ee =3D mhi_get_exec_env(mhi_cntrl); dev_dbg(dev, "local ee: %s state: %s device ee: %s state: %s\n", TO_MHI_EXEC_STR(mhi_cntrl->ee), - TO_MHI_STATE_STR(mhi_cntrl->dev_state), - TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); + mhi_state_str(mhi_cntrl->dev_state), + TO_MHI_EXEC_STR(ee), mhi_state_str(state)); =20 if (state =3D=3D MHI_STATE_SYS_ERR) { dev_dbg(dev, "System error detected\n"); @@ -844,7 +844,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi= _cntrl, new_state =3D MHI_TRE_GET_EV_STATE(local_rp); =20 dev_dbg(dev, "State change event to state: %s\n", - TO_MHI_STATE_STR(new_state)); + mhi_state_str(new_state)); =20 switch (new_state) { case MHI_STATE_M0: @@ -871,7 +871,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi= _cntrl, } default: dev_err(dev, "Invalid state: %s\n", - TO_MHI_STATE_STR(new_state)); + mhi_state_str(new_state)); } =20 break; diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index bb8a23e80e19..3d90b8ecd3d9 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -541,7 +541,7 @@ static void mhi_pm_disable_transition(struct mhi_contro= ller *mhi_cntrl) =20 dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); =20 mutex_unlock(&mhi_cntrl->pm_mutex); } @@ -684,7 +684,7 @@ static void mhi_pm_sys_error_transition(struct mhi_cont= roller *mhi_cntrl) exit_sys_error_transition: dev_dbg(dev, "Exiting with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); =20 mutex_unlock(&mhi_cntrl->pm_mutex); } @@ -859,7 +859,7 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { dev_err(dev, "Did not enter M3 state, MHI state: %s, PM state: %s\n", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } @@ -885,7 +885,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_c= ntrl, bool force) =20 dev_dbg(dev, "Entered with PM state: %s, MHI state: %s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), - TO_MHI_STATE_STR(mhi_cntrl->dev_state)); + mhi_state_str(mhi_cntrl->dev_state)); =20 if (mhi_cntrl->pm_state =3D=3D MHI_PM_DISABLE) return 0; @@ -895,7 +895,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_c= ntrl, bool force) =20 if (mhi_get_mhi_state(mhi_cntrl) !=3D MHI_STATE_M3) { dev_warn(dev, "Resuming from non M3 state (%s)\n", - TO_MHI_STATE_STR(mhi_get_mhi_state(mhi_cntrl))); + mhi_state_str(mhi_get_mhi_state(mhi_cntrl))); if (!force) return -EINVAL; } @@ -932,7 +932,7 @@ static int __mhi_pm_resume(struct mhi_controller *mhi_c= ntrl, bool force) if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { dev_err(dev, "Did not enter M0 state, MHI state: %s, PM state: %s\n", - TO_MHI_STATE_STR(mhi_cntrl->dev_state), + mhi_state_str(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); return -EIO; } @@ -1083,7 +1083,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cnt= rl) =20 state =3D mhi_get_mhi_state(mhi_cntrl); dev_dbg(dev, "Attempting power on with EE: %s, state: %s\n", - TO_MHI_EXEC_STR(current_ee), TO_MHI_STATE_STR(state)); + TO_MHI_EXEC_STR(current_ee), mhi_state_str(state)); =20 if (state =3D=3D MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10440C4332F for ; Mon, 28 Feb 2022 12:45:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236609AbiB1Mpv (ORCPT ); Mon, 28 Feb 2022 07:45:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236712AbiB1Mpj (ORCPT ); Mon, 28 Feb 2022 07:45:39 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9093875E7C for ; Mon, 28 Feb 2022 04:44:52 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id p3-20020a17090a680300b001bbfb9d760eso14675913pjj.2 for ; Mon, 28 Feb 2022 04:44:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5ccQT6vj+bq/xoGQcn9v2xz+Y0edwuLMO9kFGRPpvHg=; b=BecJoD29abtDVNdA76bHXNTUWFPTT8Q2ylvU1H4ECKon4Z2oqhuUlpXBYKKKxM4Anq mx1HtRJtC1smxi1rbAdMlXCfAtrvnjUcX8n4t9IdZvMuA7ro2Om8ifoPkyBuPcRUAERp DqVJ2MbJcujeJ9EBhvXnehs63lpVNlK7RleWwbvt2hTnZ6u6AFw74vHR3N2q4sjsFd/9 n8vRv9ZCz4oKvpb/FSufSCYbt02QaZm7oFP1243M2/WT10WUndzFtm/i1AE+goA5uA54 4xafz+QxKC2t6krTG5U6MQ1Wtf4kuXyH8cTzThhXfkJ95R3NutEEMkLgWpzXsGNG4VzU jFwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5ccQT6vj+bq/xoGQcn9v2xz+Y0edwuLMO9kFGRPpvHg=; b=b/A0JmXJWr0KmEx33EiBvAG4c+or2A0caulU90w3URl8J0EaDdMeg7O2qQe710n6jX L1MCss+lSy8A5ZHwNyVG8StMFtTfu81uQovcd/XL2j6jWTQ3Lv5j7u9X0A/3tmgU7Dsr ZICa7KRo1aYpOI2ua3FG88D0XZnfK0+aZLJbWxP6tfSkwObkkxVahMzP7bjGc4vM37sJ XXXcR892DBTey9m/u5tILX+VZodnvxFiPOTkve2+SOoIYq73sDzxZltIX56ZeZ9tQD7M YPK5NiOjFI6yYt3KeZBqI2AeKhTDbELDm+tRlVZkQ5NG+gcwTeYO9V1Wvn3Lrd7zhBT/ LptA== X-Gm-Message-State: AOAM533WCmary324bcPfmFJP4z83vrraPKbDiKQQHR6eGPOxtZBl/QGF lRRwyn7yirvGg4MbT5q7UYzy X-Google-Smtp-Source: ABdhPJyhNXsTfisLkqNfMVmJk+iXIONO79UKjeKU2tbaNPCw6vllgDegryPmmS0Zp6BL1c9qV0zT2w== X-Received: by 2002:a17:90a:8581:b0:1b2:7541:af6c with SMTP id m1-20020a17090a858100b001b27541af6cmr16605365pjn.48.1646052291943; Mon, 28 Feb 2022 04:44:51 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:51 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 10/27] bus: mhi: ep: Add support for registering MHI endpoint controllers Date: Mon, 28 Feb 2022 18:13:27 +0530 Message-Id: <20220228124344.77359-11-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This commit adds support for registering MHI endpoint controller drivers with the MHI endpoint stack. MHI endpoint controller drivers manage the interaction with the host machines (such as x86). They are also the MHI endpoint bus master in charge of managing the physical link between the host and endpoint device. Eventhough the MHI spec is bus agnostic, the current implementation is entirely based on PCIe bus. The endpoint controller driver encloses all information about the underlying physical bus like PCIe. The registration process involves parsing the channel configuration and allocating an MHI EP device. Channels used in the endpoint stack follows the perspective of the MHI host stack. i.e., UL - From host to endpoint DL - From endpoint to host Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/Kconfig | 1 + drivers/bus/mhi/Makefile | 3 + drivers/bus/mhi/ep/Kconfig | 10 ++ drivers/bus/mhi/ep/Makefile | 2 + drivers/bus/mhi/ep/internal.h | 154 ++++++++++++++++++++++ drivers/bus/mhi/ep/main.c | 236 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 143 ++++++++++++++++++++ 7 files changed, 549 insertions(+) create mode 100644 drivers/bus/mhi/ep/Kconfig create mode 100644 drivers/bus/mhi/ep/Makefile create mode 100644 drivers/bus/mhi/ep/internal.h create mode 100644 drivers/bus/mhi/ep/main.c create mode 100644 include/linux/mhi_ep.h diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig index 4748df7f9cd5..b39a11e6c624 100644 --- a/drivers/bus/mhi/Kconfig +++ b/drivers/bus/mhi/Kconfig @@ -6,3 +6,4 @@ # =20 source "drivers/bus/mhi/host/Kconfig" +source "drivers/bus/mhi/ep/Kconfig" diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile index 5f5708a249f5..46981331b38f 100644 --- a/drivers/bus/mhi/Makefile +++ b/drivers/bus/mhi/Makefile @@ -1,2 +1,5 @@ # Host MHI stack obj-y +=3D host/ + +# Endpoint MHI stack +obj-y +=3D ep/ diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig new file mode 100644 index 000000000000..90ab3b040672 --- /dev/null +++ b/drivers/bus/mhi/ep/Kconfig @@ -0,0 +1,10 @@ +config MHI_BUS_EP + tristate "Modem Host Interface (MHI) bus Endpoint implementation" + help + Bus driver for MHI protocol. Modem Host Interface (MHI) is a + communication protocol used by a host processor to control + and communicate a modem device over a high speed peripheral + bus or shared memory. + + MHI_BUS_EP implements the MHI protocol for the endpoint devices, + such as SDX55 modem connected to the host machine over PCIe. diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile new file mode 100644 index 000000000000..64e29252b608 --- /dev/null +++ b/drivers/bus/mhi/ep/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_EP) +=3D mhi_ep.o +mhi_ep-y :=3D main.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h new file mode 100644 index 000000000000..58ec5fdc503f --- /dev/null +++ b/drivers/bus/mhi/ep/internal.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022, Linaro Ltd. + * + */ + +#ifndef _MHI_EP_INTERNAL_ +#define _MHI_EP_INTERNAL_ + +#include + +#include "../common.h" + +extern struct bus_type mhi_ep_bus_type; + +#define MHI_REG_OFFSET 0x100 +#define BHI_REG_OFFSET 0x200 + +/* MHI registers */ +#define EP_MHIREGLEN (MHI_REG_OFFSET + MHIREGLEN) +#define EP_MHIVER (MHI_REG_OFFSET + MHIVER) +#define EP_MHICFG (MHI_REG_OFFSET + MHICFG) +#define EP_CHDBOFF (MHI_REG_OFFSET + CHDBOFF) +#define EP_ERDBOFF (MHI_REG_OFFSET + ERDBOFF) +#define EP_BHIOFF (MHI_REG_OFFSET + BHIOFF) +#define EP_BHIEOFF (MHI_REG_OFFSET + BHIEOFF) +#define EP_DEBUGOFF (MHI_REG_OFFSET + DEBUGOFF) +#define EP_MHICTRL (MHI_REG_OFFSET + MHICTRL) +#define EP_MHISTATUS (MHI_REG_OFFSET + MHISTATUS) +#define EP_CCABAP_LOWER (MHI_REG_OFFSET + CCABAP_LOWER) +#define EP_CCABAP_HIGHER (MHI_REG_OFFSET + CCABAP_HIGHER) +#define EP_ECABAP_LOWER (MHI_REG_OFFSET + ECABAP_LOWER) +#define EP_ECABAP_HIGHER (MHI_REG_OFFSET + ECABAP_HIGHER) +#define EP_CRCBAP_LOWER (MHI_REG_OFFSET + CRCBAP_LOWER) +#define EP_CRCBAP_HIGHER (MHI_REG_OFFSET + CRCBAP_HIGHER) +#define EP_CRDB_LOWER (MHI_REG_OFFSET + CRDB_LOWER) +#define EP_CRDB_HIGHER (MHI_REG_OFFSET + CRDB_HIGHER) +#define EP_MHICTRLBASE_LOWER (MHI_REG_OFFSET + MHICTRLBASE_LOWER) +#define EP_MHICTRLBASE_HIGHER (MHI_REG_OFFSET + MHICTRLBASE_HIGHER) +#define EP_MHICTRLLIMIT_LOWER (MHI_REG_OFFSET + MHICTRLLIMIT_LOWER) +#define EP_MHICTRLLIMIT_HIGHER (MHI_REG_OFFSET + MHICTRLLIMIT_HIGHER) +#define EP_MHIDATABASE_LOWER (MHI_REG_OFFSET + MHIDATABASE_LOWER) +#define EP_MHIDATABASE_HIGHER (MHI_REG_OFFSET + MHIDATABASE_HIGHER) +#define EP_MHIDATALIMIT_LOWER (MHI_REG_OFFSET + MHIDATALIMIT_LOWER) +#define EP_MHIDATALIMIT_HIGHER (MHI_REG_OFFSET + MHIDATALIMIT_HIGHER) + +/* MHI BHI registers */ +#define EP_BHI_INTVEC (BHI_REG_OFFSET + BHI_INTVEC) +#define EP_BHI_EXECENV (BHI_REG_OFFSET + BHI_EXECENV) + +/* MHI Doorbell registers */ +#define CHDB_LOWER_n(n) (0x400 + 0x8 * (n)) +#define CHDB_HIGHER_n(n) (0x404 + 0x8 * (n)) +#define ERDB_LOWER_n(n) (0x800 + 0x8 * (n)) +#define ERDB_HIGHER_n(n) (0x804 + 0x8 * (n)) + +#define MHI_CTRL_INT_STATUS 0x4 +#define MHI_CTRL_INT_STATUS_MSK BIT(0) +#define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1) +#define MHI_CHDB_INT_STATUS_n(n) (0x28 + 0x4 * (n)) +#define MHI_ERDB_INT_STATUS_n(n) (0x38 + 0x4 * (n)) + +#define MHI_CTRL_INT_CLEAR 0x4c +#define MHI_CTRL_INT_MMIO_WR_CLEAR BIT(2) +#define MHI_CTRL_INT_CRDB_CLEAR BIT(1) +#define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR BIT(0) + +#define MHI_CHDB_INT_CLEAR_n(n) (0x70 + 0x4 * (n)) +#define MHI_CHDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_CLEAR_n(n) (0x80 + 0x4 * (n)) +#define MHI_ERDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0) + +/* + * Unlike the usual "masking" convention, writing "1" to a bit in this reg= ister + * enables the interrupt and writing "0" will disable it.. + */ +#define MHI_CTRL_INT_MASK 0x94 +#define MHI_CTRL_INT_MASK_MASK GENMASK(1, 0) +#define MHI_CTRL_MHICTRL_MASK BIT(0) +#define MHI_CTRL_CRDB_MASK BIT(1) + +#define MHI_CHDB_INT_MASK_n(n) (0xb8 + 0x4 * (n)) +#define MHI_CHDB_INT_MASK_n_EN_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_MASK_n(n) (0xc8 + 0x4 * (n)) +#define MHI_ERDB_INT_MASK_n_EN_ALL GENMASK(31, 0) + +#define NR_OF_CMD_RINGS 1 +#define MHI_MASK_ROWS_CH_EV_DB 4 +#define MHI_MASK_CH_EV_LEN 32 + +/* Generic context */ +struct mhi_generic_ctx { + __le32 reserved0; + __le32 reserved1; + __le32 reserved2; + + __le64 rbase __packed __aligned(4); + __le64 rlen __packed __aligned(4); + __le64 rp __packed __aligned(4); + __le64 wp __packed __aligned(4); +}; + +enum mhi_ep_ring_type { + RING_TYPE_CMD, + RING_TYPE_ER, + RING_TYPE_CH, +}; + +/* Ring element */ +union mhi_ep_ring_ctx { + struct mhi_cmd_ctxt cmd; + struct mhi_event_ctxt ev; + struct mhi_chan_ctxt ch; + struct mhi_generic_ctx generic; +}; + +struct mhi_ep_ring { + struct mhi_ep_cntrl *mhi_cntrl; + union mhi_ep_ring_ctx *ring_ctx; + struct mhi_ring_element *ring_cache; + enum mhi_ep_ring_type type; + u64 rbase; + size_t rd_offset; + size_t wr_offset; + size_t ring_size; + u32 db_offset_h; + u32 db_offset_l; + u32 ch_id; +}; + +struct mhi_ep_cmd { + struct mhi_ep_ring ring; +}; + +struct mhi_ep_event { + struct mhi_ep_ring ring; +}; + +struct mhi_ep_chan { + char *name; + struct mhi_ep_device *mhi_dev; + struct mhi_ep_ring ring; + struct mutex lock; + void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result); + enum mhi_ch_state state; + enum dma_data_direction dir; + u64 tre_loc; + u32 tre_size; + u32 tre_bytes_left; + u32 chan; + bool skip_td; +}; + +#endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c new file mode 100644 index 000000000000..87ca42c7b067 --- /dev/null +++ b/drivers/bus/mhi/ep/main.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MHI Endpoint bus stack + * + * Copyright (C) 2022 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +static DEFINE_IDA(mhi_ep_cntrl_ida); + +static void mhi_ep_release_device(struct device *dev) +{ + struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + + if (mhi_dev->dev_type =3D=3D MHI_DEVICE_CONTROLLER) + mhi_dev->mhi_cntrl->mhi_dev =3D NULL; + + /* + * We need to set the mhi_chan->mhi_dev to NULL here since the MHI + * devices for the channels will only get created in mhi_ep_create_device= () + * if the mhi_dev associated with it is NULL. + */ + if (mhi_dev->ul_chan) + mhi_dev->ul_chan->mhi_dev =3D NULL; + + if (mhi_dev->dl_chan) + mhi_dev->dl_chan->mhi_dev =3D NULL; + + kfree(mhi_dev); +} + +static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_= cntrl, + enum mhi_device_type dev_type) +{ + struct mhi_ep_device *mhi_dev; + struct device *dev; + + mhi_dev =3D kzalloc(sizeof(*mhi_dev), GFP_KERNEL); + if (!mhi_dev) + return ERR_PTR(-ENOMEM); + + dev =3D &mhi_dev->dev; + device_initialize(dev); + dev->bus =3D &mhi_ep_bus_type; + dev->release =3D mhi_ep_release_device; + + /* Controller device is always allocated first */ + if (dev_type =3D=3D MHI_DEVICE_CONTROLLER) + /* for MHI controller device, parent is the bus device (e.g. PCI EPF) */ + dev->parent =3D mhi_cntrl->cntrl_dev; + else + /* for MHI client devices, parent is the MHI controller device */ + dev->parent =3D &mhi_cntrl->mhi_dev->dev; + + mhi_dev->mhi_cntrl =3D mhi_cntrl; + mhi_dev->dev_type =3D dev_type; + + return mhi_dev; +} + +static int mhi_ep_chan_init(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config) +{ + const struct mhi_ep_channel_config *ch_cfg; + struct device *dev =3D mhi_cntrl->cntrl_dev; + u32 chan, i; + int ret =3D -EINVAL; + + mhi_cntrl->max_chan =3D config->max_channels; + + /* + * Allocate max_channels supported by the MHI endpoint and populate + * only the defined channels + */ + mhi_cntrl->mhi_chan =3D kcalloc(mhi_cntrl->max_chan, sizeof(*mhi_cntrl->m= hi_chan), + GFP_KERNEL); + if (!mhi_cntrl->mhi_chan) + return -ENOMEM; + + for (i =3D 0; i < config->num_channels; i++) { + struct mhi_ep_chan *mhi_chan; + + ch_cfg =3D &config->ch_cfg[i]; + + chan =3D ch_cfg->num; + if (chan >=3D mhi_cntrl->max_chan) { + dev_err(dev, "Channel (%u) exceeds maximum available channels (%u)\n", + chan, mhi_cntrl->max_chan); + goto error_chan_cfg; + } + + /* Bi-directional and direction less channels are not supported */ + if (ch_cfg->dir =3D=3D DMA_BIDIRECTIONAL || ch_cfg->dir =3D=3D DMA_NONE)= { + dev_err(dev, "Invalid direction (%u) for channel (%u)\n", + ch_cfg->dir, chan); + goto error_chan_cfg; + } + + mhi_chan =3D &mhi_cntrl->mhi_chan[chan]; + mhi_chan->name =3D ch_cfg->name; + mhi_chan->chan =3D chan; + mhi_chan->dir =3D ch_cfg->dir; + mutex_init(&mhi_chan->lock); + } + + return 0; + +error_chan_cfg: + kfree(mhi_cntrl->mhi_chan); + + return ret; +} + +/* + * Allocate channel and command rings here. Event rings will be allocated + * in mhi_ep_power_up() as the config comes from the host. + */ +int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config) +{ + struct mhi_ep_device *mhi_dev; + int ret; + + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev) + return -EINVAL; + + ret =3D mhi_ep_chan_init(mhi_cntrl, config); + if (ret) + return ret; + + mhi_cntrl->mhi_cmd =3D kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cm= d), GFP_KERNEL); + if (!mhi_cntrl->mhi_cmd) { + ret =3D -ENOMEM; + goto err_free_ch; + } + + /* Set controller index */ + mhi_cntrl->index =3D ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); + if (mhi_cntrl->index < 0) { + ret =3D mhi_cntrl->index; + goto err_free_cmd; + } + + /* Allocate the controller device */ + mhi_dev =3D mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_CONTROLLER); + if (IS_ERR(mhi_dev)) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); + ret =3D PTR_ERR(mhi_dev); + goto err_ida_free; + } + + dev_set_name(&mhi_dev->dev, "mhi_ep%u", mhi_cntrl->index); + mhi_dev->name =3D dev_name(&mhi_dev->dev); + mhi_cntrl->mhi_dev =3D mhi_dev; + + ret =3D device_add(&mhi_dev->dev); + if (ret) + goto err_put_dev; + + dev_dbg(&mhi_dev->dev, "MHI EP Controller registered\n"); + + return 0; + +err_put_dev: + put_device(&mhi_dev->dev); +err_ida_free: + ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +err_free_cmd: + kfree(mhi_cntrl->mhi_cmd); +err_free_ch: + kfree(mhi_cntrl->mhi_chan); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_register_controller); + +void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_device *mhi_dev =3D mhi_cntrl->mhi_dev; + + kfree(mhi_cntrl->mhi_cmd); + kfree(mhi_cntrl->mhi_chan); + + device_del(&mhi_dev->dev); + put_device(&mhi_dev->dev); + + ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +} +EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); + +static int mhi_ep_match(struct device *dev, struct device_driver *drv) +{ + struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + + /* + * If the device is a controller type then there is no client driver + * associated with it + */ + if (mhi_dev->dev_type =3D=3D MHI_DEVICE_CONTROLLER) + return 0; + + return 0; +}; + +struct bus_type mhi_ep_bus_type =3D { + .name =3D "mhi_ep", + .dev_name =3D "mhi_ep", + .match =3D mhi_ep_match, +}; + +static int __init mhi_ep_init(void) +{ + return bus_register(&mhi_ep_bus_type); +} + +static void __exit mhi_ep_exit(void) +{ + bus_unregister(&mhi_ep_bus_type); +} + +postcore_initcall(mhi_ep_init); +module_exit(mhi_ep_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MHI Bus Endpoint stack"); +MODULE_AUTHOR("Manivannan Sadhasivam "); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h new file mode 100644 index 000000000000..9c58938371e2 --- /dev/null +++ b/include/linux/mhi_ep.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022, Linaro Ltd. + * + */ +#ifndef _MHI_EP_H_ +#define _MHI_EP_H_ + +#include +#include + +#define MHI_EP_DEFAULT_MTU 0x8000 + +/** + * struct mhi_ep_channel_config - Channel configuration structure for cont= roller + * @name: The name of this channel + * @num: The number assigned to this channel + * @num_elements: The number of elements that can be queued to this channel + * @dir: Direction that data may flow on this channel + */ +struct mhi_ep_channel_config { + char *name; + u32 num; + u32 num_elements; + enum dma_data_direction dir; +}; + +/** + * struct mhi_ep_cntrl_config - MHI Endpoint controller configuration + * @mhi_version: MHI spec version supported by the controller + * @max_channels: Maximum number of channels supported + * @num_channels: Number of channels defined in @ch_cfg + * @ch_cfg: Array of defined channels + */ +struct mhi_ep_cntrl_config { + u32 mhi_version; + u32 max_channels; + u32 num_channels; + const struct mhi_ep_channel_config *ch_cfg; +}; + +/** + * struct mhi_ep_db_info - MHI Endpoint doorbell info + * @mask: Mask of the doorbell interrupt + * @status: Status of the doorbell interrupt + */ +struct mhi_ep_db_info { + u32 mask; + u32 status; +}; + +/** + * struct mhi_ep_cntrl - MHI Endpoint controller structure + * @cntrl_dev: Pointer to the struct device of physical bus acting as the = MHI + * Endpoint controller + * @mhi_dev: MHI Endpoint device instance for the controller + * @mmio: MMIO region containing the MHI registers + * @mhi_chan: Points to the channel configuration table + * @mhi_event: Points to the event ring configurations table + * @mhi_cmd: Points to the command ring configurations table + * @sm: MHI Endpoint state machine + * @raise_irq: CB function for raising IRQ to the host + * @alloc_addr: CB function for allocating memory in endpoint for storing = host context + * @map_addr: CB function for mapping host context to endpoint + * @free_addr: CB function to free the allocated memory in endpoint for st= oring host context + * @unmap_addr: CB function to unmap the host context in endpoint + * @read_from_host: CB function for reading from host memory from endpoint + * @write_to_host: CB function for writing to host memory from endpoint + * @mhi_state: MHI Endpoint state + * @max_chan: Maximum channels supported by the endpoint controller + * @mru: MRU (Maximum Receive Unit) value of the endpoint controller + * @index: MHI Endpoint controller index + */ +struct mhi_ep_cntrl { + struct device *cntrl_dev; + struct mhi_ep_device *mhi_dev; + void __iomem *mmio; + + struct mhi_ep_chan *mhi_chan; + struct mhi_ep_event *mhi_event; + struct mhi_ep_cmd *mhi_cmd; + struct mhi_ep_sm *sm; + + void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); + void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, + size_t size); + int (*map_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr, u6= 4 pci_addr, + size_t size); + void (*free_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr, + void __iomem *virt_addr, size_t size); + void (*unmap_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t phys_addr); + int (*read_from_host)(struct mhi_ep_cntrl *mhi_cntrl, u64 from, void __io= mem *to, + size_t size); + int (*write_to_host)(struct mhi_ep_cntrl *mhi_cntrl, void __iomem *from, = u64 to, + size_t size); + + enum mhi_state mhi_state; + + u32 max_chan; + u32 mru; + u32 index; +}; + +/** + * struct mhi_ep_device - Structure representing an MHI Endpoint device th= at binds + * to channels or is associated with controllers + * @dev: Driver model device node for the MHI Endpoint device + * @mhi_cntrl: Controller the device belongs to + * @id: Pointer to MHI Endpoint device ID struct + * @name: Name of the associated MHI Endpoint device + * @ul_chan: UL channel for the device + * @dl_chan: DL channel for the device + * @dev_type: MHI device type + */ +struct mhi_ep_device { + struct device dev; + struct mhi_ep_cntrl *mhi_cntrl; + const struct mhi_device_id *id; + const char *name; + struct mhi_ep_chan *ul_chan; + struct mhi_ep_chan *dl_chan; + enum mhi_device_type dev_type; +}; + +#define to_mhi_ep_device(dev) container_of(dev, struct mhi_ep_device, dev) + +/** + * mhi_ep_register_controller - Register MHI Endpoint controller + * @mhi_cntrl: MHI Endpoint controller to register + * @config: Configuration to use for the controller + * + * Return: 0 if controller registrations succeeds, a negative error code o= therwise. + */ +int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config); + +/** + * mhi_ep_unregister_controller - Unregister MHI Endpoint controller + * @mhi_cntrl: MHI Endpoint controller to unregister + */ +void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); + +#endif --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 177C5C433EF for ; Mon, 28 Feb 2022 12:45:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236655AbiB1Mpx (ORCPT ); Mon, 28 Feb 2022 07:45:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236676AbiB1Mpr (ORCPT ); Mon, 28 Feb 2022 07:45:47 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68A1277AA6 for ; Mon, 28 Feb 2022 04:44:58 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id k1so543790pfu.2 for ; Mon, 28 Feb 2022 04:44:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZcgB3dsdYiRl3IlyzXkbVRVAGkvq7C0XqoDwm1YpiDY=; b=GhYcbIp8tl+HCeZLLWNLL78a+UBg8ENdh+6DB0LKRKhWzZfGDgw2eo9oVztZXBD0TX RE0GS/MiHefahHVkb1HgC2O7onA79BHR+PoNUfBuFidzwnDbsW212sIeElmxN8rwyQta K4SX3rMEcOXUnDy+ftpC0JgAHS5j5ObaJHh/0UJgPpeRuZ4cr4Gy6f97NfUpjIjdknid FmjwBkkR1xpBANOn72YMH7Xnow266xS0/sI1qvLjVnxQUAPSCUd5s74M2YAAtdvutmI2 uI0mjoUMB3+f4YDdJaCyHukNawwXZKIjDz6+G3StKP9ePZMzFyDxQm7kLiUHGL3pdDtl 1Xbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZcgB3dsdYiRl3IlyzXkbVRVAGkvq7C0XqoDwm1YpiDY=; b=WlGzsWi2KairRaBjlQR7x4VoUDiQOhq9j1MFF6cawt8X9MPdvA33jAwfV5xqTd/LvF GyvnnpUZQsReW5pg8CTzYMgy7SZm9xSjbz0UNN6SC3OGNUpV/hXB2MfySFAm4WhEg7r+ 86d9gJbkLUbg/T0EPbuZa6NHx2qZeZidAHyv86ybTAR8/qx+rv8mxPxgYsJFIdOD1dEq c3kRWOUN3zHBpT8L8nIPs6ngzosnu701SXKQQaw4MZ8xkFfcleI17qSk/heefWFe83DH zu+3QXKuZ4oFGl8BckleHBj8PUMGk7jld7XE7lM7pcfEUd3VeaHc3RknWGnCmIcMx69g O+WA== X-Gm-Message-State: AOAM530udzvlTr78BjavfGj/R7nZ/wh5zbWVjAhTCAJhOlLCYzuSIdEA 3njsrOmyH5xcc9ln6N3aTzfX X-Google-Smtp-Source: ABdhPJwJMnbkJ1SKjLiLJpAn6iKdpFTpYoyXgypL+MzEbarFklFbYBw6RGIkoOEL3J0SOHnBsyJkqg== X-Received: by 2002:a63:6908:0:b0:372:d919:82ed with SMTP id e8-20020a636908000000b00372d91982edmr17305878pgc.104.1646052297522; Mon, 28 Feb 2022 04:44:57 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:44:57 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam , Hemant Kumar Subject: [PATCH v4 11/27] bus: mhi: ep: Add support for registering MHI endpoint client drivers Date: Mon, 28 Feb 2022 18:13:28 +0530 Message-Id: <20220228124344.77359-12-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This commit adds support for registering MHI endpoint client drivers with the MHI endpoint stack. MHI endpoint client drivers bind to one or more MHI endpoint devices inorder to send and receive the upper-layer protocol packets like IP packets, modem control messages, and diagnostics messages over MHI bus. Reviewed-by: Hemant Kumar Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 85 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 57 +++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 87ca42c7b067..2bdcf1657479 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -198,9 +198,88 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl = *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); =20 +static int mhi_ep_driver_probe(struct device *dev) +{ + struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv =3D to_mhi_ep_driver(dev->driver); + struct mhi_ep_chan *ul_chan =3D mhi_dev->ul_chan; + struct mhi_ep_chan *dl_chan =3D mhi_dev->dl_chan; + + ul_chan->xfer_cb =3D mhi_drv->ul_xfer_cb; + dl_chan->xfer_cb =3D mhi_drv->dl_xfer_cb; + + return mhi_drv->probe(mhi_dev, mhi_dev->id); +} + +static int mhi_ep_driver_remove(struct device *dev) +{ + struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv =3D to_mhi_ep_driver(dev->driver); + struct mhi_result result =3D {}; + struct mhi_ep_chan *mhi_chan; + int dir; + + /* Skip if it is a controller device */ + if (mhi_dev->dev_type =3D=3D MHI_DEVICE_CONTROLLER) + return 0; + + /* Disconnect the channels associated with the driver */ + for (dir =3D 0; dir < 2; dir++) { + mhi_chan =3D dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + + if (!mhi_chan) + continue; + + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to the client driver */ + if (mhi_chan->xfer_cb) { + result.transaction_status =3D -ENOTCONN; + result.bytes_xferd =3D 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + mhi_chan->state =3D MHI_CH_STATE_DISABLED; + mhi_chan->xfer_cb =3D NULL; + mutex_unlock(&mhi_chan->lock); + } + + /* Remove the client driver now */ + mhi_drv->remove(mhi_dev); + + return 0; +} + +int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module = *owner) +{ + struct device_driver *driver =3D &mhi_drv->driver; + + if (!mhi_drv->probe || !mhi_drv->remove) + return -EINVAL; + + /* Client drivers should have callbacks defined for both channels */ + if (!mhi_drv->ul_xfer_cb || !mhi_drv->dl_xfer_cb) + return -EINVAL; + + driver->bus =3D &mhi_ep_bus_type; + driver->owner =3D owner; + driver->probe =3D mhi_ep_driver_probe; + driver->remove =3D mhi_ep_driver_remove; + + return driver_register(driver); +} +EXPORT_SYMBOL_GPL(__mhi_ep_driver_register); + +void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv) +{ + driver_unregister(&mhi_drv->driver); +} +EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); + static int mhi_ep_match(struct device *dev, struct device_driver *drv) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv =3D to_mhi_ep_driver(drv); + const struct mhi_device_id *id; =20 /* * If the device is a controller type then there is no client driver @@ -209,6 +288,12 @@ static int mhi_ep_match(struct device *dev, struct dev= ice_driver *drv) if (mhi_dev->dev_type =3D=3D MHI_DEVICE_CONTROLLER) return 0; =20 + for (id =3D mhi_drv->id_table; id->chan[0]; id++) + if (!strcmp(mhi_dev->name, id->chan)) { + mhi_dev->id =3D id; + return 1; + } + return 0; }; =20 diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 9c58938371e2..efcbdc51464f 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -108,8 +108,8 @@ struct mhi_ep_cntrl { * @mhi_cntrl: Controller the device belongs to * @id: Pointer to MHI Endpoint device ID struct * @name: Name of the associated MHI Endpoint device - * @ul_chan: UL channel for the device - * @dl_chan: DL channel for the device + * @ul_chan: UL (from host to endpoint) channel for the device + * @dl_chan: DL (from endpoint to host) channel for the device * @dev_type: MHI device type */ struct mhi_ep_device { @@ -122,7 +122,60 @@ struct mhi_ep_device { enum mhi_device_type dev_type; }; =20 +/** + * struct mhi_ep_driver - Structure representing a MHI Endpoint client dri= ver + * @id_table: Pointer to MHI Endpoint device ID table + * @driver: Device driver model driver + * @probe: CB function for client driver probe function + * @remove: CB function for client driver remove function + * @ul_xfer_cb: CB function for UL (from host to endpoint) data transfer + * @dl_xfer_cb: CB function for DL (from endpoint to host) data transfer + */ +struct mhi_ep_driver { + const struct mhi_device_id *id_table; + struct device_driver driver; + int (*probe)(struct mhi_ep_device *mhi_ep, + const struct mhi_device_id *id); + void (*remove)(struct mhi_ep_device *mhi_ep); + void (*ul_xfer_cb)(struct mhi_ep_device *mhi_dev, + struct mhi_result *result); + void (*dl_xfer_cb)(struct mhi_ep_device *mhi_dev, + struct mhi_result *result); +}; + #define to_mhi_ep_device(dev) container_of(dev, struct mhi_ep_device, dev) +#define to_mhi_ep_driver(drv) container_of(drv, struct mhi_ep_driver, driv= er) + +/* + * module_mhi_ep_driver() - Helper macro for drivers that don't do + * anything special other than using default mhi_ep_driver_register() and + * mhi_ep_driver_unregister(). This eliminates a lot of boilerplate. + * Each module may only use this macro once. + */ +#define module_mhi_ep_driver(mhi_drv) \ + module_driver(mhi_drv, mhi_ep_driver_register, \ + mhi_ep_driver_unregister) + +/* + * Macro to avoid include chaining to get THIS_MODULE + */ +#define mhi_ep_driver_register(mhi_drv) \ + __mhi_ep_driver_register(mhi_drv, THIS_MODULE) + +/** + * __mhi_ep_driver_register - Register a driver with MHI Endpoint bus + * @mhi_drv: Driver to be associated with the device + * @owner: The module owner + * + * Return: 0 if driver registrations succeeds, a negative error code other= wise. + */ +int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module = *owner); + +/** + * mhi_ep_driver_unregister - Unregister a driver from MHI Endpoint bus + * @mhi_drv: Driver associated with the device + */ +void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv); =20 /** * mhi_ep_register_controller - Register MHI Endpoint controller --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6394AC433FE for ; Mon, 28 Feb 2022 12:45:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236697AbiB1MqJ (ORCPT ); Mon, 28 Feb 2022 07:46:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236665AbiB1Mp7 (ORCPT ); Mon, 28 Feb 2022 07:45:59 -0500 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5563278052 for ; Mon, 28 Feb 2022 04:45:03 -0800 (PST) Received: by mail-pj1-x1033.google.com with SMTP id ge19-20020a17090b0e1300b001bcca16e2e7so10255018pjb.3 for ; Mon, 28 Feb 2022 04:45:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qP2EzzC3I2IhCGQAXOgXpj1gBQ3j7ZCObf/XVIEWx3s=; b=JcEYpQ0zDJ3UIVbiXsaNDN4MMDXzrq5SiAQvpz2OPg3jfOOF9LovhRvXeWAsaGLYdP JdUm15Mv1D+sIDdhdCNHnndi6pZUx51tZrYcqYqEnASuXkTUYcyy8a1Z5+BiZe+p+3WI 9X3gh7DqcSlBh+qJ8pfOenf2DFnU/cCFTiuEULnuTA//mJ+m8H4xLt1HSpIklFrktJW5 UbXkVU/vBLutJtre56v0fVBcgBKL2bEnNjgu+w/ZxRCoP67mR/Kg6xu5XiCq3pvW1AIx 204v8S6RGxeYrg/0d32laS01YoRe15FFlqNMUJpjU73MxVqs0BDII77OBy8GwVyNY2P1 DIFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qP2EzzC3I2IhCGQAXOgXpj1gBQ3j7ZCObf/XVIEWx3s=; b=MQdiQpDzVdEgU8k/DqttdMUkhs23LbHzoy0GcO6iARjCU+ZtLOB1iNrQ61hkf3nQ7n AfW29MRpQgTWhwP0yfJCFEtsiJ8m1FZhLQ5FvLJrPEeWmcFqgzMCC2IvPo/D6yDEekAj iBs0pKH94mH6lsEMOYFYZ2pmbN1hW9LUOgc0tk+hIu5O5nkNSXILp+wZffO2GUEDR3oz DCOQ/XVVyhxZe3pmgKFy1HieGzzCwZ2f1G+W0Rg/FNYy8UJyvwDYHeEDdxYBi2w9Yhmy 3cXaCn1rE9ZgFt+5YzHeIZi14UcJLxNw2zY3oTSf3Lc3F3C7g1cYNO5Tiqv2j5Zog6Zb 3DzA== X-Gm-Message-State: AOAM5320ZxnghDrbMYBPMRFfF8JwHGk4LHj/OOB4HwS4qa8SegIavr+L hkTiwwtJpmKoPCTN0oFZsq0G X-Google-Smtp-Source: ABdhPJwQyVkL4rba7nSaauBpAv4yR7PSjssMkQdBhxxd7FmEclSVr8RcF8iY4jXsbH+e1ojm9DDGcQ== X-Received: by 2002:a17:902:ccd2:b0:14f:8182:96c4 with SMTP id z18-20020a170902ccd200b0014f818296c4mr20717147ple.67.1646052302779; Mon, 28 Feb 2022 04:45:02 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.44.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:02 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 12/27] bus: mhi: ep: Add support for creating and destroying MHI EP devices Date: Mon, 28 Feb 2022 18:13:29 +0530 Message-Id: <20220228124344.77359-13-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This commit adds support for creating and destroying MHI endpoint devices. The MHI endpoint devices binds to the MHI endpoint channels and are used to transfer data between MHI host and endpoint device. There is a single MHI EP device for each channel pair. The devices will be created when the corresponding channels has been started by the host and will be destroyed during MHI EP power down and reset. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 2bdcf1657479..3afae0bfd83c 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -68,6 +68,89 @@ static struct mhi_ep_device *mhi_ep_alloc_device(struct = mhi_ep_cntrl *mhi_cntrl, return mhi_dev; } =20 +/* + * MHI channels are always defined in pairs with UL as the even numbered + * channel and DL as odd numbered one. This function gets UL channel (prim= ary) + * as the ch_id and always looks after the next entry in channel list for + * the corresponding DL channel (secondary). + */ +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) +{ + struct mhi_ep_chan *mhi_chan =3D &mhi_cntrl->mhi_chan[ch_id]; + struct device *dev =3D mhi_cntrl->cntrl_dev; + struct mhi_ep_device *mhi_dev; + int ret; + + /* Check if the channel name is same for both UL and DL */ + if (strcmp(mhi_chan->name, mhi_chan[1].name)) { + dev_err(dev, "UL and DL channel names are not same: (%s) !=3D (%s)\n", + mhi_chan->name, mhi_chan[1].name); + return -EINVAL; + } + + mhi_dev =3D mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_XFER); + if (IS_ERR(mhi_dev)) + return PTR_ERR(mhi_dev); + + /* Configure primary channel */ + mhi_dev->ul_chan =3D mhi_chan; + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev =3D mhi_dev; + + /* Configure secondary channel as well */ + mhi_chan++; + mhi_dev->dl_chan =3D mhi_chan; + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev =3D mhi_dev; + + /* Channel name is same for both UL and DL */ + mhi_dev->name =3D mhi_chan->name; + dev_set_name(&mhi_dev->dev, "%s_%s", + dev_name(&mhi_cntrl->mhi_dev->dev), + mhi_dev->name); + + ret =3D device_add(&mhi_dev->dev); + if (ret) + put_device(&mhi_dev->dev); + + return ret; +} + +static int mhi_ep_destroy_device(struct device *dev, void *data) +{ + struct mhi_ep_device *mhi_dev; + struct mhi_ep_cntrl *mhi_cntrl; + struct mhi_ep_chan *ul_chan, *dl_chan; + + if (dev->bus !=3D &mhi_ep_bus_type) + return 0; + + mhi_dev =3D to_mhi_ep_device(dev); + mhi_cntrl =3D mhi_dev->mhi_cntrl; + + /* Only destroy devices created for channels */ + if (mhi_dev->dev_type =3D=3D MHI_DEVICE_CONTROLLER) + return 0; + + ul_chan =3D mhi_dev->ul_chan; + dl_chan =3D mhi_dev->dl_chan; + + if (ul_chan) + put_device(&ul_chan->mhi_dev->dev); + + if (dl_chan) + put_device(&dl_chan->mhi_dev->dev); + + dev_dbg(&mhi_cntrl->mhi_dev->dev, "Destroying device for chan:%s\n", + mhi_dev->name); + + /* Notify the client and remove the device from MHI bus */ + device_del(dev); + put_device(dev); + + return 0; +} + static int mhi_ep_chan_init(struct mhi_ep_cntrl *mhi_cntrl, const struct mhi_ep_cntrl_config *config) { --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E2F8C433FE for ; Mon, 28 Feb 2022 12:45:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236667AbiB1MqM (ORCPT ); Mon, 28 Feb 2022 07:46:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234756AbiB1MqH (ORCPT ); Mon, 28 Feb 2022 07:46:07 -0500 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7B444757F for ; Mon, 28 Feb 2022 04:45:08 -0800 (PST) Received: by mail-pl1-x62e.google.com with SMTP id h17so5043082plc.5 for ; Mon, 28 Feb 2022 04:45:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=F+KBq6RzwgdLLJoe+tsayKrNTKVoiagle0XBxHTtuXw=; b=pTIw9yHH8kas/CWWFcZ9t94WLWakoVSGdbFIA2guoZrzNB47lYdUaIIBQvTT8kxFDc p1gFCVi/RFtYZKSvE/wUWZ8BYw84o27wv1ILF4Y7XlisxsxZs8PAl02t715b+e7kRujn Wk8BHxNWKrDj02t1B3Y36ctTr1vqqNf9AepE9dfgZRVIwmTN7QW33eujKj55eVjJVVX/ TuPf559S3YxBIrh/6tbsY2YF/6gsr/plS7OQ6sjI2Y8pfRAFg130+8qwPjhZYmiZB2nj VpMRE6o5GFyqgUYaunsjTgT3mJefzgJApoaBlEy3qhTgOmIUBun6xM7D60URLd8AkQw1 3wYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=F+KBq6RzwgdLLJoe+tsayKrNTKVoiagle0XBxHTtuXw=; b=StfPjMzsR4leUMICaFRPVThhdI8M0iEQGE1xN17w6UNk5V7WBgq1x4OUil3eM9hvad 1EllRcs3l9K6FSFrf6vG26F/HWMxz+Y/tk9te6n3AmwSicsP9so5/ozVqoaXgUOzyVWz fH0SfOJ3Sgd0DbHwpOawpAhAeSXwiEL7HDuK6lBIc/3wSmaudZSNSQG/C3OW5YD4gp1P pD1gZujYwQbZ2LztyNdyuYMb2eGT3ZbnmBjxbM2TsiEHhD3gLgJCAbJ45Qv59HjIYw5a 6e5x1hyeJjRrjm53aXatZvfMI+2gNEU7YwodMdl0NK+eqNPWCkP8DyJSKFhyeeUunp4R hZHQ== X-Gm-Message-State: AOAM532Y2FQYK9mUZ+OCWMzyeRdFoz4+ifFKF6uvs9CvvT4BkFsh1AFU 86kQqrePSVfLhCSKXaQFZIsQ X-Google-Smtp-Source: ABdhPJwTxfg0csI9uswuYIBC/Ef69Q2hlQj120Qf533tug9N5s+j+UYhUpQa8weUTAZxskFel9ypbA== X-Received: by 2002:a17:902:d888:b0:151:6fe8:6e68 with SMTP id b8-20020a170902d88800b001516fe86e68mr1958933plz.158.1646052308329; Mon, 28 Feb 2022 04:45:08 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:08 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 13/27] bus: mhi: ep: Add support for managing MMIO registers Date: Mon, 28 Feb 2022 18:13:30 +0530 Message-Id: <20220228124344.77359-14-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for managing the Memory Mapped Input Output (MMIO) registers of the MHI bus. All MHI operations are carried out using the MMIO registers by both host and the endpoint device. The MMIO registers reside inside the endpoint device memory (fixed location based on the platform) and the address is passed by the MHI EP controller driver during its registration. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 26 ++++ drivers/bus/mhi/ep/main.c | 6 +- drivers/bus/mhi/ep/mmio.c | 272 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 18 +++ 5 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 drivers/bus/mhi/ep/mmio.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index 64e29252b608..a1555ae287ad 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) +=3D mhi_ep.o -mhi_ep-y :=3D main.o +mhi_ep-y :=3D main.o mmio.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 58ec5fdc503f..139e939fcf57 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -151,4 +151,30 @@ struct mhi_ep_chan { bool skip_td; }; =20 +/* MMIO related functions */ +u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset); +void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val= ); +void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, = u32 mask, u32 val); +u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask= ); +void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); +void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); +void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntr= l); +void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl); +u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring); +void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value); +void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_st= ate *state, + bool *mhi_reset); +void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 3afae0bfd83c..d76387c4d5fa 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -214,7 +214,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, struct mhi_ep_device *mhi_dev; int ret; =20 - if (!mhi_cntrl || !mhi_cntrl->cntrl_dev) + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio) return -EINVAL; =20 ret =3D mhi_ep_chan_init(mhi_cntrl, config); @@ -227,6 +227,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mh= i_cntrl, goto err_free_ch; } =20 + /* Set MHI version and AMSS EE before enumeration */ + mhi_ep_mmio_write(mhi_cntrl, EP_MHIVER, config->mhi_version); + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS); + /* Set controller index */ mhi_cntrl->index =3D ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { diff --git a/drivers/bus/mhi/ep/mmio.c b/drivers/bus/mhi/ep/mmio.c new file mode 100644 index 000000000000..311c5d94c4d2 --- /dev/null +++ b/drivers/bus/mhi/ep/mmio.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include + +#include "internal.h" + +u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset) +{ + return readl(mhi_cntrl->mmio + offset); +} + +void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val) +{ + writel(val, mhi_cntrl->mmio + offset); +} + +void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, = u32 mask, u32 val) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, offset); + regval &=3D ~mask; + regval |=3D (val << __ffs(mask)) & mask; + mhi_ep_mmio_write(mhi_cntrl, offset, regval); +} + +u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(dev, offset); + regval &=3D mask; + regval >>=3D __ffs(mask); + + return regval; +} + +void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_st= ate *state, + bool *mhi_reset) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_MHICTRL); + *state =3D FIELD_GET(MHICTRL_MHISTATE_MASK, regval); + *mhi_reset =3D !!FIELD_GET(MHICTRL_RESET_MASK, regval); +} + +static void mhi_ep_mmio_set_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id= , bool enable) +{ + u32 chid_mask, chid_shift, chdb_idx, val; + + chid_shift =3D ch_id % 32; + chid_mask =3D BIT(chid_shift); + chdb_idx =3D ch_id / 32; + + val =3D enable ? 1 : 0; + + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CHDB_INT_MASK_n(chdb_idx), chid_m= ask, val); + + /* Update the local copy of the channel mask */ + mhi_cntrl->chdb[chdb_idx].mask &=3D ~chid_mask; + mhi_cntrl->chdb[chdb_idx].mask |=3D val << chid_shift; +} + +void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) +{ + mhi_ep_mmio_set_chdb(mhi_cntrl, ch_id, true); +} + +void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) +{ + mhi_ep_mmio_set_chdb(mhi_cntrl, ch_id, false); +} + +static void mhi_ep_mmio_set_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl= , bool enable) +{ + u32 val, i; + + val =3D enable ? MHI_CHDB_INT_MASK_n_EN_ALL : 0; + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_MASK_n(i), val); + mhi_cntrl->chdb[i].mask =3D val; + } +} + +void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_set_chdb_interrupts(mhi_cntrl, true); +} + +static void mhi_ep_mmio_mask_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntr= l) +{ + mhi_ep_mmio_set_chdb_interrupts(mhi_cntrl, false); +} + +bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntr= l) +{ + bool chdb =3D 0; + u32 i; + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + mhi_cntrl->chdb[i].status =3D mhi_ep_mmio_read(mhi_cntrl, MHI_CHDB_INT_S= TATUS_n(i)); + chdb |=3D !!mhi_cntrl->chdb[i].status; + } + + /* Return whether a channel doorbell interrupt occurred or not */ + return chdb; +} + +static void mhi_ep_mmio_set_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl= , bool enable) +{ + u32 val, i; + + val =3D enable ? MHI_ERDB_INT_MASK_n_EN_ALL : 0; + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_MASK_n(i), val); +} + +static void mhi_ep_mmio_mask_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntr= l) +{ + mhi_ep_mmio_set_erdb_interrupts(mhi_cntrl, false); +} + +void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK, + MHI_CTRL_MHICTRL_MASK, 1); +} + +void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK, + MHI_CTRL_MHICTRL_MASK, 0); +} + +void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK, + MHI_CTRL_CRDB_MASK, 1); +} + +void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CTRL_INT_MASK, + MHI_CTRL_CRDB_MASK, 0); +} + +void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_disable_ctrl_interrupt(mhi_cntrl); + mhi_ep_mmio_disable_cmdb_interrupt(mhi_cntrl); + mhi_ep_mmio_mask_chdb_interrupts(mhi_cntrl); + mhi_ep_mmio_mask_erdb_interrupts(mhi_cntrl); +} + +static void mhi_ep_mmio_clear_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 i; + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_n(i), + MHI_CHDB_INT_CLEAR_n_CLEAR_ALL); + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_CLEAR_n(i), + MHI_ERDB_INT_CLEAR_n_CLEAR_ALL); + + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR, + MHI_CTRL_INT_MMIO_WR_CLEAR | + MHI_CTRL_INT_CRDB_CLEAR | + MHI_CTRL_INT_CRDB_MHICTRL_CLEAR); +} + +void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_CCABAP_HIGHER); + mhi_cntrl->ch_ctx_host_pa =3D regval; + mhi_cntrl->ch_ctx_host_pa <<=3D 32; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_CCABAP_LOWER); + mhi_cntrl->ch_ctx_host_pa |=3D regval; +} + +void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_ECABAP_HIGHER); + mhi_cntrl->ev_ctx_host_pa =3D regval; + mhi_cntrl->ev_ctx_host_pa <<=3D 32; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_ECABAP_LOWER); + mhi_cntrl->ev_ctx_host_pa |=3D regval; +} + +void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_CRCBAP_HIGHER); + mhi_cntrl->cmd_ctx_host_pa =3D regval; + mhi_cntrl->cmd_ctx_host_pa <<=3D 32; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_CRCBAP_LOWER); + mhi_cntrl->cmd_ctx_host_pa |=3D regval; +} + +u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D ring->mhi_cntrl; + u64 db_offset; + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_h); + db_offset =3D regval; + db_offset <<=3D 32; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_l); + db_offset |=3D regval; + + return db_offset; +} + +void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value) +{ + mhi_ep_mmio_write(mhi_cntrl, EP_BHI_EXECENV, value); +} + +void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHICTRL, MHICTRL_RESET_MASK, 0); +} + +void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_write(mhi_cntrl, EP_MHICTRL, 0); + mhi_ep_mmio_write(mhi_cntrl, EP_MHISTATUS, 0); + mhi_ep_mmio_clear_interrupts(mhi_cntrl); +} + +void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 regval; + + mhi_cntrl->chdb_offset =3D mhi_ep_mmio_read(mhi_cntrl, EP_CHDBOFF); + mhi_cntrl->erdb_offset =3D mhi_ep_mmio_read(mhi_cntrl, EP_ERDBOFF); + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_MHICFG); + mhi_cntrl->event_rings =3D FIELD_GET(MHICFG_NER_MASK, regval); + mhi_cntrl->hw_event_rings =3D FIELD_GET(MHICFG_NHWER_MASK, regval); + + mhi_ep_mmio_reset(mhi_cntrl); +} + +void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 regval; + + regval =3D mhi_ep_mmio_read(mhi_cntrl, EP_MHICFG); + mhi_cntrl->event_rings =3D FIELD_GET(MHICFG_NER_MASK, regval); + mhi_cntrl->hw_event_rings =3D FIELD_GET(MHICFG_NHWER_MASK, regval); +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index efcbdc51464f..8e1de062f820 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -59,6 +59,10 @@ struct mhi_ep_db_info { * @mhi_event: Points to the event ring configurations table * @mhi_cmd: Points to the command ring configurations table * @sm: MHI Endpoint state machine + * @ch_ctx_host_pa: Physical address of host channel context data structure + * @ev_ctx_host_pa: Physical address of host event context data structure + * @cmd_ctx_host_pa: Physical address of host command context data structu= re + * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -69,6 +73,10 @@ struct mhi_ep_db_info { * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by the endpoint controller * @mru: MRU (Maximum Receive Unit) value of the endpoint controller + * @event_rings: Number of event rings supported by the endpoint controller + * @hw_event_rings: Number of hardware event rings supported by the endpoi= nt controller + * @chdb_offset: Channel doorbell offset set by the host + * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index */ struct mhi_ep_cntrl { @@ -81,6 +89,12 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; =20 + u64 ch_ctx_host_pa; + u64 ev_ctx_host_pa; + u64 cmd_ctx_host_pa; + + struct mhi_ep_db_info chdb[4]; + void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, size_t size); @@ -98,6 +112,10 @@ struct mhi_ep_cntrl { =20 u32 max_chan; u32 mru; + u32 event_rings; + u32 hw_event_rings; + u32 chdb_offset; + u32 erdb_offset; u32 index; }; =20 --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ABAEDC433EF for ; Mon, 28 Feb 2022 12:45:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236648AbiB1MqR (ORCPT ); Mon, 28 Feb 2022 07:46:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236720AbiB1MqH (ORCPT ); Mon, 28 Feb 2022 07:46:07 -0500 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1432F75C20 for ; Mon, 28 Feb 2022 04:45:14 -0800 (PST) Received: by mail-pf1-x42a.google.com with SMTP id u16so11026340pfg.12 for ; Mon, 28 Feb 2022 04:45:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OzxxAcSZ3QzNXpGWZ3mCL6qTxkzBqAQS2IireUric5Y=; b=xgkTzjwKHjrxOUhcXl++/6hx3IKreYJSI//ey+ZlPw03zUhNl2niilRYFaczu95rcW AWuteZKexkELRFd7h0xhW7sqo9DOlfpfvAvARsUlcZ/YBHN3q0t/dcrTw0O37/8e7iSF hPbYqQXEyW2nfsIeOjIP10bavbS73C6NVC3yFZvO4+W/HvZDHYAQB8XQ2fqZUsj6D30G 7QmjoreE/xo7Dqp2H/z6zMb8ndarXQCJPpLsMsW/CZYb41RIO4Ji3EpEB6J1OvrcPpQ2 Eo1TwOsr3+NE8lciVmrAbgAkIiFj2iPljp3Wfn+rCj4DnT1ZQnA/i/zwXNSpv/l0FBCU uLyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OzxxAcSZ3QzNXpGWZ3mCL6qTxkzBqAQS2IireUric5Y=; b=jYbENJ0YQ3Hy8Gu28PvWVhBjP8f+n6C6ae7GBZdjaRrJ8luCWUuvhK0IYdd50qUuZh viHQ6phl5CmmXlB3khgiVsHpFBwwe8s783531eona47eauETd2NgPI+9d6Upr6hv0qpH 4MG9I7ZTfjvAhbv+aNACLmRtfvM4S3G5bFgsi2+tPNhDtZTIad3xTb96GhqnniE/gDtP FWHKzlTQA+Bjqf9+TBOssIrzaKClBhaeIulSTN04/4fbYa4k6PZFSNMSfhI/WIRuSDT7 k3iIHrID+ViWRDw4DEsVVofi6Vo2/Pb4yI2Uoi2OhhXeJCm5RBfMHFT9jp9eB7lMHfOX V5Wg== X-Gm-Message-State: AOAM531O4ue0+eIYjHelSZPYfNcUqRYOo9NuhXHzsePlxLZZBpaWKkmF OUbwh0Zlo4hon3SSYNenFAc7 X-Google-Smtp-Source: ABdhPJz9UF9zFkFSbdhTGwhnqmGMLsMZbC70CUVHi2Y5xxs5dgqdzgDn6e9K6ZsOkObqNKGzTI6Iwg== X-Received: by 2002:a65:52cc:0:b0:374:3ee6:c632 with SMTP id z12-20020a6552cc000000b003743ee6c632mr16912963pgp.91.1646052313523; Mon, 28 Feb 2022 04:45:13 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:13 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 14/27] bus: mhi: ep: Add support for ring management Date: Mon, 28 Feb 2022 18:13:31 +0530 Message-Id: <20220228124344.77359-15-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for managing the MHI ring. The MHI ring is a circular queue of data structures used to pass the information between host and the endpoint. MHI support 3 types of rings: 1. Transfer ring 2. Event ring 3. Command ring All rings reside inside the host memory and the MHI EP device maps it to the device memory using blocks like PCIe iATU. The mapping is handled in the MHI EP controller driver itself. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 18 ++++ drivers/bus/mhi/ep/ring.c | 197 ++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 drivers/bus/mhi/ep/ring.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index a1555ae287ad..7ba0e04801eb 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) +=3D mhi_ep.o -mhi_ep-y :=3D main.o mmio.o +mhi_ep-y :=3D main.o mmio.o ring.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 139e939fcf57..b3b8770f2f4e 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -114,6 +114,11 @@ union mhi_ep_ring_ctx { struct mhi_generic_ctx generic; }; =20 +struct mhi_ep_ring_item { + struct list_head node; + struct mhi_ep_ring *ring; +}; + struct mhi_ep_ring { struct mhi_ep_cntrl *mhi_cntrl; union mhi_ep_ring_ctx *ring_ctx; @@ -126,6 +131,9 @@ struct mhi_ep_ring { u32 db_offset_h; u32 db_offset_l; u32 ch_id; + u32 er_index; + u32 irq_vector; + bool started; }; =20 struct mhi_ep_cmd { @@ -151,6 +159,16 @@ struct mhi_ep_chan { bool skip_td; }; =20 +/* MHI Ring related functions */ +void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type= , u32 id); +void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring = *ring); +int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *= ring, + union mhi_ep_ring_ctx *ctx); +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr); +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_elem= ent *element); +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring); +int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring); + /* MMIO related functions */ u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset); void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val= ); diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c new file mode 100644 index 000000000000..1029eed2cc28 --- /dev/null +++ b/drivers/bus/mhi/ep/ring.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include "internal.h" + +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr) +{ + return (ptr - ring->rbase) / sizeof(struct mhi_ring_element); +} + +static u32 mhi_ep_ring_num_elems(struct mhi_ep_ring *ring) +{ + return le64_to_cpu(ring->ring_ctx->generic.rlen) / sizeof(struct mhi_ring= _element); +} + +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring) +{ + ring->rd_offset =3D (ring->rd_offset + 1) % ring->ring_size; +} + +static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D ring->mhi_cntrl; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + size_t start, copy_size; + int ret; + + /* Don't proceed in the case of event ring. This happens during mhi_ep_ri= ng_start(). */ + if (ring->type =3D=3D RING_TYPE_ER) + return 0; + + /* No need to cache the ring if write pointer is unmodified */ + if (ring->wr_offset =3D=3D end) + return 0; + + start =3D ring->wr_offset; + if (start < end) { + copy_size =3D (end - start) * sizeof(struct mhi_ring_element); + ret =3D mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase + + (start * sizeof(struct mhi_ring_element)), + &ring->ring_cache[start], copy_size); + if (ret < 0) + return ret; + } else { + copy_size =3D (ring->ring_size - start) * sizeof(struct mhi_ring_element= ); + ret =3D mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase + + (start * sizeof(struct mhi_ring_element)), + &ring->ring_cache[start], copy_size); + if (ret < 0) + return ret; + + if (end) { + ret =3D mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase, + &ring->ring_cache[0], + end * sizeof(struct mhi_ring_element)); + if (ret < 0) + return ret; + } + } + + dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, cop= y_size); + + return 0; +} + +static int mhi_ep_cache_ring(struct mhi_ep_ring *ring, u64 wr_ptr) +{ + size_t wr_offset; + int ret; + + wr_offset =3D mhi_ep_ring_addr2offset(ring, wr_ptr); + + /* Cache the host ring till write offset */ + ret =3D __mhi_ep_cache_ring(ring, wr_offset); + if (ret) + return ret; + + ring->wr_offset =3D wr_offset; + + return 0; +} + +int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring) +{ + u64 wr_ptr; + + wr_ptr =3D mhi_ep_mmio_get_db(ring); + + return mhi_ep_cache_ring(ring, wr_ptr); +} + +/* TODO: Support for adding multiple ring elements to the ring */ +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_elem= ent *el) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D ring->mhi_cntrl; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + size_t old_offset =3D 0; + u32 num_free_elem; + int ret; + + ret =3D mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write pointer\n"); + return ret; + } + + if (ring->rd_offset < ring->wr_offset) + num_free_elem =3D (ring->wr_offset - ring->rd_offset) - 1; + else + num_free_elem =3D ((ring->ring_size - ring->rd_offset) + ring->wr_offset= ) - 1; + + /* Check if there is space in ring for adding at least an element */ + if (!num_free_elem) { + dev_err(dev, "No space left in the ring\n"); + return -ENOSPC; + } + + old_offset =3D ring->rd_offset; + mhi_ep_ring_inc_index(ring); + + dev_dbg(dev, "Adding an element to ring at offset (%zu)\n", ring->rd_offs= et); + + /* Update rp in ring context */ + ring->ring_ctx->generic.rp =3D cpu_to_le64((ring->rd_offset * sizeof(*el)= ) + ring->rbase); + + ret =3D mhi_cntrl->write_to_host(mhi_cntrl, el, ring->rbase + (old_offset= * sizeof(*el)), + sizeof(*el)); + if (ret < 0) + return ret; + + return 0; +} + +void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type= , u32 id) +{ + ring->type =3D type; + if (ring->type =3D=3D RING_TYPE_CMD) { + ring->db_offset_h =3D EP_CRDB_HIGHER; + ring->db_offset_l =3D EP_CRDB_LOWER; + } else if (ring->type =3D=3D RING_TYPE_CH) { + ring->db_offset_h =3D CHDB_HIGHER_n(id); + ring->db_offset_l =3D CHDB_LOWER_n(id); + ring->ch_id =3D id; + } else { + ring->db_offset_h =3D ERDB_HIGHER_n(id); + ring->db_offset_l =3D ERDB_LOWER_n(id); + } +} + +int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *= ring, + union mhi_ep_ring_ctx *ctx) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret; + + ring->mhi_cntrl =3D mhi_cntrl; + ring->ring_ctx =3D ctx; + ring->ring_size =3D mhi_ep_ring_num_elems(ring); + ring->rbase =3D le64_to_cpu(ring->ring_ctx->generic.rbase); + + if (ring->type =3D=3D RING_TYPE_CH) + ring->er_index =3D le32_to_cpu(ring->ring_ctx->ch.erindex); + + if (ring->type =3D=3D RING_TYPE_ER) + ring->irq_vector =3D le32_to_cpu(ring->ring_ctx->ev.msivec); + + /* During ring init, both rp and wp are equal */ + ring->rd_offset =3D mhi_ep_ring_addr2offset(ring, le64_to_cpu(ring->ring_= ctx->generic.rp)); + ring->wr_offset =3D mhi_ep_ring_addr2offset(ring, le64_to_cpu(ring->ring_= ctx->generic.rp)); + + /* Allocate ring cache memory for holding the copy of host ring */ + ring->ring_cache =3D kcalloc(ring->ring_size, sizeof(struct mhi_ring_elem= ent), GFP_KERNEL); + if (!ring->ring_cache) + return -ENOMEM; + + ret =3D mhi_ep_cache_ring(ring, le64_to_cpu(ring->ring_ctx->generic.wp)); + if (ret) { + dev_err(dev, "Failed to cache ring\n"); + kfree(ring->ring_cache); + return ret; + } + + ring->started =3D true; + + return 0; +} + +void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring = *ring) +{ + ring->started =3D false; + kfree(ring->ring_cache); + ring->ring_cache =3D NULL; +} --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46D8AC433F5 for ; Mon, 28 Feb 2022 12:45:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236783AbiB1Mqg (ORCPT ); Mon, 28 Feb 2022 07:46:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236710AbiB1MqO (ORCPT ); Mon, 28 Feb 2022 07:46:14 -0500 Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A11A76E38 for ; Mon, 28 Feb 2022 04:45:19 -0800 (PST) Received: by mail-pg1-x529.google.com with SMTP id 132so11271555pga.5 for ; Mon, 28 Feb 2022 04:45:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rZep28DhIdqNfp5J0eB33gO8gDlbZ2SZXLI7+YnFIhM=; b=WPu8k+dZJe8z8MeH8JjrfcoT59S/UDfwx98X+IWC7XEpr2XNjSBeV85wy5Y+oJNr4z yr0bnjDP2RUYqSoIlBuFt+HAmCOglq0dm/iq0OmAWUHyTCFpiBzwFBdhGq+F6frjRfho 3iyv1+jevOwPT8D3cnZdCsO/kslUudma+3SXR5w0bQRuzqqPsfQaEIxmzIPrifdR0xUq jnk56nd2xsQVvgKbbS0Hrx0AAvxiHBhewsCK+qBpkTFiCIva152SOBJDwxc0nKOQelrD P5O0R9BQF/5yoGIa+wK9iekaxVgeUYCSxUsMIqNd6YY3+eXbG4NZQ4pNrOUgGEiuH9aj UQLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rZep28DhIdqNfp5J0eB33gO8gDlbZ2SZXLI7+YnFIhM=; b=h5gcMuIiioymxGHKCDwoR9Y+u21XXlX98bRNaz0iHF9zlueYX44Ft12SA85mq6XFEG XwW5aFJiOXQEgAVxeYUrT8dB0VRU4ojdW0M8ruCvpFf1ktyrAFSXpvtVc4Xd2vvw/+KL wUf4FWAcH+3IHOnHYFPvdlV5oJJUMvtYCKFfEDVclvpIsYrniroUMiGAaCs+iE2+5BeP rcC+owhGLxc4gvTSopoZWZBHsMf3yfCB0TDLguCJIJYhMS4qkQXQvfitrlfYiD1GUBUg 4GrMqCID8SEAwGmOUoUPEHxJVsi7DaEAZDUOEhntx5RvbZMcyILg0qNdvhs/IZbzXVWI pAjQ== X-Gm-Message-State: AOAM530KqcmA5+qAudmYP990ZKHYLxWbjMJ9D9uIAiMQE1qzSILcM4kM 2D+ourxT6gbbxw9UV3/j6oFo X-Google-Smtp-Source: ABdhPJxndLbOp3LP+7nUx5QdEZPg44A4JMetsCaOc6fbLOuPvRrNcq38XJH01Lkbm9LtfA9AkQ+WmQ== X-Received: by 2002:a05:6a00:b92:b0:4f1:4b2:737f with SMTP id g18-20020a056a000b9200b004f104b2737fmr21511709pfj.31.1646052318829; Mon, 28 Feb 2022 04:45:18 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:18 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 15/27] bus: mhi: ep: Add support for sending events to the host Date: Mon, 28 Feb 2022 18:13:32 +0530 Message-Id: <20220228124344.77359-16-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for sending the events to the host over MHI bus from the endpoint. Following events are supported: 1. Transfer completion event 2. Command completion event 3. State change event 4. Execution Environment (EE) change event An event is sent whenever an operation has been completed in the MHI EP device. Event is sent using the MHI event ring and additionally the host is notified using an IRQ if required. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/common.h | 22 +++++++++ drivers/bus/mhi/ep/internal.h | 4 ++ drivers/bus/mhi/ep/main.c | 90 +++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 8 ++++ 4 files changed, 124 insertions(+) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index ec75ba1e6686..5b30e2d0832e 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -165,6 +165,22 @@ #define MHI_TRE_GET_EV_LINKSPEED(tre) FIELD_GET(GENMASK(31, 24), (MHI_TRE_= GET_DWORD(tre, 1))) #define MHI_TRE_GET_EV_LINKWIDTH(tre) FIELD_GET(GENMASK(7, 0), (MHI_TRE_GE= T_DWORD(tre, 0))) =20 +/* State change event */ +#define MHI_SC_EV_PTR 0 +#define MHI_SC_EV_DWORD0(state) cpu_to_le32(FIELD_PREP(GENMASK(31, 24), s= tate)) +#define MHI_SC_EV_DWORD1(type) cpu_to_le32(FIELD_PREP(GENMASK(23, 16), ty= pe)) + +/* EE event */ +#define MHI_EE_EV_PTR 0 +#define MHI_EE_EV_DWORD0(ee) cpu_to_le32(FIELD_PREP(GENMASK(31, 24), ee)) +#define MHI_EE_EV_DWORD1(type) cpu_to_le32(FIELD_PREP(GENMASK(23, 16), ty= pe)) + + +/* Command Completion event */ +#define MHI_CC_EV_PTR(ptr) cpu_to_le64(ptr) +#define MHI_CC_EV_DWORD0(code) cpu_to_le32(FIELD_PREP(GENMASK(31, 24), co= de)) +#define MHI_CC_EV_DWORD1(type) cpu_to_le32(FIELD_PREP(GENMASK(23, 16), ty= pe)) + /* Transfer descriptor macros */ #define MHI_TRE_DATA_PTR(ptr) cpu_to_le64(ptr) #define MHI_TRE_DATA_DWORD0(len) cpu_to_le32(FIELD_PREP(GENMASK(15, 0), le= n)) @@ -175,6 +191,12 @@ FIELD_PREP(BIT(9), ieot) | \ FIELD_PREP(BIT(8), ieob) | \ FIELD_PREP(BIT(0), chain)) +#define MHI_TRE_DATA_GET_PTR(tre) le64_to_cpu((tre)->ptr) +#define MHI_TRE_DATA_GET_LEN(tre) FIELD_GET(GENMASK(15, 0), MHI_TRE_GET_DW= ORD(tre, 0)) +#define MHI_TRE_DATA_GET_CHAIN(tre) FIELD_GET(BIT(0), MHI_TRE_GET_DWORD(tr= e, 1)) +#define MHI_TRE_DATA_GET_IEOB(tre) FIELD_GET(BIT(8), MHI_TRE_GET_DWORD(tre= , 1)) +#define MHI_TRE_DATA_GET_IEOT(tre) FIELD_GET(BIT(9), MHI_TRE_GET_DWORD(tre= , 1)) +#define MHI_TRE_DATA_GET_BEI(tre) FIELD_GET(BIT(10), MHI_TRE_GET_DWORD(tre= , 1)) =20 /* RSC transfer descriptor macros */ #define MHI_RSCTRE_DATA_PTR(ptr, len) cpu_to_le64(FIELD_PREP(GENMASK(64, 4= 8), len) | ptr) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index b3b8770f2f4e..8753ae93eda3 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -195,4 +195,8 @@ void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi= _cntrl, enum mhi_state *s void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl); void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); =20 +/* MHI EP core functions */ +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mh= i_state state); +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type = exec_env); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index d76387c4d5fa..903f9bd3e03d 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -18,6 +18,94 @@ =20 static DEFINE_IDA(mhi_ep_cntrl_ida); =20 +static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, + struct mhi_ring_element *el, bool bei) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + union mhi_ep_ring_ctx *ctx; + struct mhi_ep_ring *ring; + int ret; + + mutex_lock(&mhi_cntrl->event_lock); + ring =3D &mhi_cntrl->mhi_event[ring_idx].ring; + ctx =3D (union mhi_ep_ring_ctx *)&mhi_cntrl->ev_ctx_cache[ring_idx]; + if (!ring->started) { + ret =3D mhi_ep_ring_start(mhi_cntrl, ring, ctx); + if (ret) { + dev_err(dev, "Error starting event ring (%u)\n", ring_idx); + goto err_unlock; + } + } + + /* Add element to the event ring */ + ret =3D mhi_ep_ring_add_element(ring, el); + if (ret) { + dev_err(dev, "Error adding element to event ring (%u)\n", ring_idx); + goto err_unlock; + } + + mutex_unlock(&mhi_cntrl->event_lock); + + /* + * Raise IRQ to host only if the BEI flag is not set in TRE. Host might + * set this flag for interrupt moderation as per MHI protocol. + */ + if (!bei) + mhi_cntrl->raise_irq(mhi_cntrl, ring->irq_vector); + + return 0; + +err_unlock: + mutex_unlock(&mhi_cntrl->event_lock); + + return ret; +} + +static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, st= ruct mhi_ep_ring *ring, + struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code) +{ + struct mhi_ring_element event =3D {}; + + event.ptr =3D cpu_to_le64(ring->rbase + (ring->rd_offset * (sizeof(*tre))= )); + event.dword[0] =3D MHI_TRE_EV_DWORD0(code, len); + event.dword[1] =3D MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); + + return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event, !!MHI_TRE_DAT= A_GET_BEI(tre)); +} + +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mh= i_state state) +{ + struct mhi_ring_element event =3D {}; + + event.dword[0] =3D MHI_SC_EV_DWORD0(state); + event.dword[1] =3D MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); + + return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); +} + +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type = exec_env) +{ + struct mhi_ring_element event =3D {}; + + event.dword[0] =3D MHI_EE_EV_DWORD0(exec_env); + event.dword[1] =3D MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); + + return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); +} + +static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum= mhi_ev_ccs code) +{ + struct mhi_ep_ring *ring =3D &mhi_cntrl->mhi_cmd->ring; + struct mhi_ring_element event =3D {}; + + event.ptr =3D cpu_to_le64(ring->rbase + (ring->rd_offset * + (sizeof(struct mhi_ring_element)))); + event.dword[0] =3D MHI_CC_EV_DWORD0(code); + event.dword[1] =3D MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); + + return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); @@ -227,6 +315,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, goto err_free_ch; } =20 + mutex_init(&mhi_cntrl->event_lock); + /* Set MHI version and AMSS EE before enumeration */ mhi_ep_mmio_write(mhi_cntrl, EP_MHIVER, config->mhi_version); mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 8e1de062f820..44a4669382ad 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -59,10 +59,14 @@ struct mhi_ep_db_info { * @mhi_event: Points to the event ring configurations table * @mhi_cmd: Points to the command ring configurations table * @sm: MHI Endpoint state machine + * @ch_ctx_cache: Cache of host channel context data structure + * @ev_ctx_cache: Cache of host event context data structure + * @cmd_ctx_cache: Cache of host command context data structure * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structu= re * @chdb: Array of channel doorbell interrupt info + * @event_lock: Lock for protecting event rings * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -89,11 +93,15 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; =20 + struct mhi_chan_ctxt *ch_ctx_cache; + struct mhi_event_ctxt *ev_ctx_cache; + struct mhi_cmd_ctxt *cmd_ctx_cache; u64 ch_ctx_host_pa; u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; =20 struct mhi_ep_db_info chdb[4]; + struct mutex event_lock; =20 void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9D25C433FE for ; Mon, 28 Feb 2022 12:46:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234983AbiB1Mqi (ORCPT ); Mon, 28 Feb 2022 07:46:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236731AbiB1Mqd (ORCPT ); Mon, 28 Feb 2022 07:46:33 -0500 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EFE5677ABE for ; Mon, 28 Feb 2022 04:45:24 -0800 (PST) Received: by mail-pl1-x62f.google.com with SMTP id z11so2218072pla.7 for ; Mon, 28 Feb 2022 04:45:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Vcl92fz3+irxD9KCaDd8YUarALcd3Z7fRorGjh01hG0=; b=zgAuBXJFRp+yRZEaovoE+pIg2W1Z/kfpBeR5FtbxhfZVVO7CZ9sce8bsu8VsHlRZsM tibWSdo8In69EkbbaS7GK4zm86aE3K0OYjL2fS2Ge9Ek5pe5lX4U5pQmo++S9R6y+OqA QOq86PV/Rz3zhBH9FYrh1zuChKmXAxJqzm26n/8Ye2m+fgIjZ7yBReWjBWLFQE8CuPGW ///nMTo+2Axboo/sOiUgMH5mEb9gNiOZPusMZMcjSpNK4PDhi8yKFfMDP2t7nPbrZsaJ Crm+c9+c2vh5wP8ck+DjJPqMlN/MzqzfvygT6j8Tx6GkErjhjiiTTS5eipdaoF5fKrBC Hryw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Vcl92fz3+irxD9KCaDd8YUarALcd3Z7fRorGjh01hG0=; b=PtMk00c/41XZxazLO7cMDfDqIGIT5qmId32vK/Os0dgcwvXvar3t7fTIpInRB1loBw +q6CkL/R+OOEimNxsL+72XIrm8p8pKuOtml+0rJTUocGnV18bgIQgmpZawqhPXyEGsI8 FNsADvMq+u+wuOYfzAvi3ebkHyxrPcLM74+s2lO94wZGE+T14QKEvvMXtBqGrwjb9NEK zvLRJo6QMCMSbHkaG5jYWynf17Jr68/WIiFYUTR5m49hw60kcgTyMBuQrrBXz1MFlXN9 U7G9xm4ddYNDdisiQghJHgbCffTxZhOytZbVfY6oppHI4XqNq6XK9Vd7wihpNPo+HS7e IOAQ== X-Gm-Message-State: AOAM532vVJlIStDYr85K4xisSf4VPeERyNBc+mL4HRDa7RR/t9+qEslo NFCnIINj8RaXTQtEKN6VEeYj X-Google-Smtp-Source: ABdhPJzPm5xtwFQ7yaaEOGCvtLKdMEubwWzR8zddxKevGDreGfG6H4SnD4rvQVEauEKhaHpeg9xdkw== X-Received: by 2002:a17:90a:dac2:b0:1bd:fecf:6bd1 with SMTP id g2-20020a17090adac200b001bdfecf6bd1mr760205pjx.113.1646052324410; Mon, 28 Feb 2022 04:45:24 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:24 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 16/27] bus: mhi: ep: Add support for managing MHI state machine Date: Mon, 28 Feb 2022 18:13:33 +0530 Message-Id: <20220228124344.77359-17-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for managing the MHI state machine by controlling the state transitions. Only the following MHI state transitions are supported: 1. Ready state 2. M0 state 3. M3 state 4. SYS_ERR state Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder mhi_dev->dev; + struct mhi_ep_state_transition *itr, *tmp; + unsigned long flags; + LIST_HEAD(head); + int ret; + + spin_lock_irqsave(&mhi_cntrl->list_lock, flags); + list_splice_tail_init(&mhi_cntrl->st_transition_list, &head); + spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); + + list_for_each_entry_safe(itr, tmp, &head, node) { + list_del(&itr->node); + dev_dbg(dev, "Handling MHI state transition to %s\n", + mhi_state_str(itr->state)); + + switch (itr->state) { + case MHI_STATE_M0: + ret =3D mhi_ep_set_m0_state(mhi_cntrl); + if (ret) + dev_err(dev, "Failed to transition to M0 state\n"); + break; + case MHI_STATE_M3: + ret =3D mhi_ep_set_m3_state(mhi_cntrl); + if (ret) + dev_err(dev, "Failed to transition to M3 state\n"); + break; + default: + dev_err(dev, "Invalid MHI state transition: %d\n", itr->state); + break; + } + kfree(itr); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); @@ -315,6 +352,17 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mh= i_cntrl, goto err_free_ch; } =20 + INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); + + mhi_cntrl->wq =3D alloc_workqueue("mhi_ep_wq", 0, 0); + if (!mhi_cntrl->wq) { + ret =3D -ENOMEM; + goto err_free_cmd; + } + + INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); + spin_lock_init(&mhi_cntrl->state_lock); + spin_lock_init(&mhi_cntrl->list_lock); mutex_init(&mhi_cntrl->event_lock); =20 /* Set MHI version and AMSS EE before enumeration */ @@ -325,7 +373,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, mhi_cntrl->index =3D ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { ret =3D mhi_cntrl->index; - goto err_free_cmd; + goto err_destroy_wq; } =20 /* Allocate the controller device */ @@ -352,6 +400,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, put_device(&mhi_dev->dev); err_ida_free: ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); +err_destroy_wq: + destroy_workqueue(mhi_cntrl->wq); err_free_cmd: kfree(mhi_cntrl->mhi_cmd); err_free_ch: @@ -365,6 +415,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *= mhi_cntrl) { struct mhi_ep_device *mhi_dev =3D mhi_cntrl->mhi_dev; =20 + destroy_workqueue(mhi_cntrl->wq); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); =20 diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c new file mode 100644 index 000000000000..ad49276ec044 --- /dev/null +++ b/drivers/bus/mhi/ep/sm.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include "internal.h" + +bool __must_check mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_state cur_mhi_state, + enum mhi_state mhi_state) +{ + if (mhi_state =3D=3D MHI_STATE_SYS_ERR) + return true; /* Allowed in any state */ + + if (mhi_state =3D=3D MHI_STATE_READY) + return cur_mhi_state =3D=3D MHI_STATE_RESET; + + if (mhi_state =3D=3D MHI_STATE_M0) + return (cur_mhi_state =3D=3D MHI_STATE_M3 || cur_mhi_state =3D=3D MHI_ST= ATE_READY); + + if (mhi_state =3D=3D MHI_STATE_M3) + return cur_mhi_state =3D=3D MHI_STATE_M0; + + return false; +} + +int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mh= i_state) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + + if (!mhi_ep_check_mhi_state(mhi_cntrl, mhi_cntrl->mhi_state, mhi_state)) { + dev_err(dev, "MHI state change to %s from %s is not allowed!\n", + mhi_state_str(mhi_state), + mhi_state_str(mhi_cntrl->mhi_state)); + return -EACCES; + } + + /* TODO */ + if (mhi_state =3D=3D MHI_STATE_M1 || mhi_state =3D=3D MHI_STATE_M2) { + dev_err(dev, "MHI state (%s) not supported\n", mhi_state_str(mhi_state)); + return -EOPNOTSUPP; + } + + mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_MHISTATE_MASK= , mhi_state); + mhi_cntrl->mhi_state =3D mhi_state; + + if (mhi_state =3D=3D MHI_STATE_READY) + mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_READY_MASK, = 1); + + if (mhi_state =3D=3D MHI_STATE_SYS_ERR) + mhi_ep_mmio_masked_write(mhi_cntrl, EP_MHISTATUS, MHISTATUS_SYSERR_MASK,= 1); + + return 0; +} + +int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + enum mhi_state old_state; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + old_state =3D mhi_cntrl->mhi_state; + + ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); + spin_unlock_bh(&mhi_cntrl->state_lock); + + if (ret) + return ret; + + /* Signal host that the device moved to M0 */ + ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M0); + if (ret) { + dev_err(dev, "Failed sending M0 state change event\n"); + return ret; + } + + if (old_state =3D=3D MHI_STATE_READY) { + /* Send AMSS EE event to host */ + ret =3D mhi_ep_send_ee_event(mhi_cntrl, MHI_EE_AMSS); + if (ret) { + dev_err(dev, "Failed sending AMSS EE event\n"); + return ret; + } + } + + return 0; +} + +int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); + spin_unlock_bh(&mhi_cntrl->state_lock); + + if (ret) + return ret; + + /* Signal host that the device moved to M3 */ + ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); + if (ret) { + dev_err(dev, "Failed sending M3 state change event\n"); + return ret; + } + + return 0; +} + +int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + enum mhi_state mhi_state; + int ret, is_ready; + + spin_lock_bh(&mhi_cntrl->state_lock); + /* Ensure that the MHISTATUS is set to RESET by host */ + mhi_state =3D mhi_ep_mmio_masked_read(mhi_cntrl, EP_MHISTATUS, MHISTATUS_= MHISTATE_MASK); + is_ready =3D mhi_ep_mmio_masked_read(mhi_cntrl, EP_MHISTATUS, MHISTATUS_R= EADY_MASK); + + if (mhi_state !=3D MHI_STATE_RESET || is_ready) { + dev_err(dev, "READY state transition failed. MHI host not in RESET state= \n"); + spin_unlock_bh(&mhi_cntrl->state_lock); + return -EIO; + } + + ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_READY); + spin_unlock_bh(&mhi_cntrl->state_lock); + + return ret; +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 44a4669382ad..dc27a5de7d3c 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -67,6 +67,11 @@ struct mhi_ep_db_info { * @cmd_ctx_host_pa: Physical address of host command context data structu= re * @chdb: Array of channel doorbell interrupt info * @event_lock: Lock for protecting event rings + * @list_lock: Lock for protecting state transition and channel doorbell l= ists + * @state_lock: Lock for protecting state transitions + * @st_transition_list: List of state transitions + * @wq: Dedicated workqueue for handling rings and state changes + * @state_work: State transition worker * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -102,6 +107,13 @@ struct mhi_ep_cntrl { =20 struct mhi_ep_db_info chdb[4]; struct mutex event_lock; + spinlock_t list_lock; + spinlock_t state_lock; + + struct list_head st_transition_list; + + struct workqueue_struct *wq; + struct work_struct state_work; =20 void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F6DDC433F5 for ; Mon, 28 Feb 2022 12:46:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236705AbiB1Mqn (ORCPT ); Mon, 28 Feb 2022 07:46:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236726AbiB1Mqe (ORCPT ); Mon, 28 Feb 2022 07:46:34 -0500 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5120F48322 for ; Mon, 28 Feb 2022 04:45:30 -0800 (PST) Received: by mail-pj1-x1033.google.com with SMTP id ge19-20020a17090b0e1300b001bcca16e2e7so10255983pjb.3 for ; Mon, 28 Feb 2022 04:45:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Ej1D8HLsv04U7QukbTs3p1AIbD/62Sh8puI8DJPJEkY=; b=bBgliBFlkBbvTYvj6tpRDcNbYBxod3WqOiO84lLw3sxlEJDjSx0XHUcdtVsXNtwfCG v/Zb0fl7Yke5JzEwoOXifiiItvV3zqoi19jrWF5U1qWkpyMbiQGvUjQ+YRtxXrk8HcPk dxaz7tIzgP+VvcrrEJz1qDPaacQ6km9Z3fhFpXWeIc1b97c/jONcoW9ZQ8YML9Pv5Wb/ TbMQuAEM+jckVZFXekK5KdjD6zdzBlrOsFkvh9IVm5zGWpEbyuEvJ9bnipQdz+rR0X/S GPcfl6jidi2L+pr+GwGKiRqEW014zpLDGpWQSsc6m8LeRh3x3ndTGbh1stk6i0qHw7Gz vxXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Ej1D8HLsv04U7QukbTs3p1AIbD/62Sh8puI8DJPJEkY=; b=xn4jNCBYcwDx65zOBZ3SIOdzJEVNnHQK14hDl6C0YDQ59HCk1p+9/5CVwAnsALSp38 tPDrQM3AYymRhDER+H+hoNi7f3nD9bI5mkrJtr/xl26Mlho1EMcBg9V9nSwGqCXp9I9t Y2nNXhnyadg60ms39OCVnHZnxBuumsXxkJsPZgTmCgHhSCfCZX4V2v/Dxq0KXclF5QPa +oTwZmAPPbPlIvc8K3EZ3Urmg/Q4zTad+Nwzv4BIDHrT5b/rfNC7wG7Ogpsb6O1zCYrc BUrBhkJJMakRPW5T+5LAF62X7HR7G2gRSO7qGu7oUhGhbLvPZHwIG78cu41L2e1W2fip cqMg== X-Gm-Message-State: AOAM531z4CgBGN+eH7NH5M/AWUmfFbY2IjpQ7/v5X8Tfu+8ZTk0Av3Ar Tz/XqYcqDkeVPrxGEC3czGw/SWvCnmyf X-Google-Smtp-Source: ABdhPJxEz5VBeplv3KEj6tbfJCgClNbmGwIr99meJK1WJULhN7rwgZAjZW54ZpSj/xflwuF7fJ51IQ== X-Received: by 2002:a17:902:7b8d:b0:14f:f1c2:9ff4 with SMTP id w13-20020a1709027b8d00b0014ff1c29ff4mr20222499pll.54.1646052329701; Mon, 28 Feb 2022 04:45:29 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:29 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 17/27] bus: mhi: ep: Add support for processing MHI endpoint interrupts Date: Mon, 28 Feb 2022 18:13:34 +0530 Message-Id: <20220228124344.77359-18-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for processing MHI endpoint interrupts such as control interrupt, command interrupt and channel interrupt from the host. The interrupts will be generated in the endpoint device whenever host writes to the corresponding doorbell registers. The doorbell logic is handled inside the hardware internally. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 123 +++++++++++++++++++++++++++++++++++++- include/linux/mhi_ep.h | 4 ++ 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 7a29543586d0..ce690b1aeace 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -143,6 +143,112 @@ static void mhi_ep_state_worker(struct work_struct *w= ork) } } =20 +static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, unsign= ed long ch_int, + u32 ch_idx) +{ + struct mhi_ep_ring_item *item; + struct mhi_ep_ring *ring; + bool work =3D !!ch_int; + LIST_HEAD(head); + u32 i; + + /* First add the ring items to a local list */ + for_each_set_bit(i, &ch_int, 32) { + /* Channel index varies for each register: 0, 32, 64, 96 */ + u32 ch_id =3D ch_idx + i; + + ring =3D &mhi_cntrl->mhi_chan[ch_id].ring; + item =3D kzalloc(sizeof(*item), GFP_ATOMIC); + if (!item) + return; + + item->ring =3D ring; + list_add_tail(&item->node, &head); + } + + /* Now, splice the local list into ch_db_list and queue the work item */ + if (work) { + spin_lock(&mhi_cntrl->list_lock); + list_splice_tail_init(&head, &mhi_cntrl->ch_db_list); + spin_unlock(&mhi_cntrl->list_lock); + } +} + +/* + * Channel interrupt statuses are contained in 4 registers each of 32bit l= ength. + * For checking all interrupts, we need to loop through each registers and= then + * check for bits set. + */ +static void mhi_ep_check_channel_interrupt(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 ch_int, ch_idx, i; + + /* Bail out if there is no channel doorbell interrupt */ + if (!mhi_ep_mmio_read_chdb_status_interrupts(mhi_cntrl)) + return; + + for (i =3D 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + ch_idx =3D i * MHI_MASK_CH_EV_LEN; + + /* Only process channel interrupt if the mask is enabled */ + ch_int =3D mhi_cntrl->chdb[i].status & mhi_cntrl->chdb[i].mask; + if (ch_int) { + mhi_ep_queue_channel_db(mhi_cntrl, ch_int, ch_idx); + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_n(i), + mhi_cntrl->chdb[i].status); + } + } +} + +static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_state state) +{ + struct mhi_ep_state_transition *item; + + item =3D kzalloc(sizeof(*item), GFP_ATOMIC); + if (!item) + return; + + item->state =3D state; + spin_lock(&mhi_cntrl->list_lock); + list_add_tail(&item->node, &mhi_cntrl->st_transition_list); + spin_unlock(&mhi_cntrl->list_lock); + + queue_work(mhi_cntrl->wq, &mhi_cntrl->state_work); +} + +/* + * Interrupt handler that services interrupts raised by the host writing to + * MHICTRL and Command ring doorbell (CRDB) registers for state change and + * channel interrupts. + */ +static irqreturn_t mhi_ep_irq(int irq, void *data) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D data; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 int_value; + + /* Acknowledge the ctrl interrupt */ + int_value =3D mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS); + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR, int_value); + + /* Check for ctrl interrupt */ + if (FIELD_GET(MHI_CTRL_INT_STATUS_MSK, int_value)) { + dev_dbg(dev, "Processing ctrl interrupt\n"); + mhi_ep_process_ctrl_interrupt(mhi_cntrl, state); + } + + /* Check for command doorbell interrupt */ + if (FIELD_GET(MHI_CTRL_INT_STATUS_CRDB_MSK, int_value)) + dev_dbg(dev, "Processing command doorbell interrupt\n"); + + /* Check for channel interrupts */ + mhi_ep_check_channel_interrupt(mhi_cntrl); + + return IRQ_HANDLED; +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); @@ -339,7 +445,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, struct mhi_ep_device *mhi_dev; int ret; =20 - if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio) + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio || !mhi_cntrl= ->irq) return -EINVAL; =20 ret =3D mhi_ep_chan_init(mhi_cntrl, config); @@ -361,6 +467,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, } =20 INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); + INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); spin_lock_init(&mhi_cntrl->state_lock); spin_lock_init(&mhi_cntrl->list_lock); mutex_init(&mhi_cntrl->event_lock); @@ -376,12 +483,20 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *m= hi_cntrl, goto err_destroy_wq; } =20 + irq_set_status_flags(mhi_cntrl->irq, IRQ_NOAUTOEN); + ret =3D request_irq(mhi_cntrl->irq, mhi_ep_irq, IRQF_TRIGGER_HIGH, + "doorbell_irq", mhi_cntrl); + if (ret) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to request Doorbell IRQ\n"); + goto err_ida_free; + } + /* Allocate the controller device */ mhi_dev =3D mhi_ep_alloc_device(mhi_cntrl, MHI_DEVICE_CONTROLLER); if (IS_ERR(mhi_dev)) { dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); ret =3D PTR_ERR(mhi_dev); - goto err_ida_free; + goto err_free_irq; } =20 dev_set_name(&mhi_dev->dev, "mhi_ep%u", mhi_cntrl->index); @@ -398,6 +513,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, =20 err_put_dev: put_device(&mhi_dev->dev); +err_free_irq: + free_irq(mhi_cntrl->irq, mhi_cntrl); err_ida_free: ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); err_destroy_wq: @@ -417,6 +534,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *= mhi_cntrl) =20 destroy_workqueue(mhi_cntrl->wq); =20 + free_irq(mhi_cntrl->irq, mhi_cntrl); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); =20 diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index dc27a5de7d3c..43aa9b133db4 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -70,6 +70,7 @@ struct mhi_ep_db_info { * @list_lock: Lock for protecting state transition and channel doorbell l= ists * @state_lock: Lock for protecting state transitions * @st_transition_list: List of state transitions + * @ch_db_list: List of queued channel doorbells * @wq: Dedicated workqueue for handling rings and state changes * @state_work: State transition worker * @raise_irq: CB function for raising IRQ to the host @@ -87,6 +88,7 @@ struct mhi_ep_db_info { * @chdb_offset: Channel doorbell offset set by the host * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index + * @irq: IRQ used by the endpoint controller */ struct mhi_ep_cntrl { struct device *cntrl_dev; @@ -111,6 +113,7 @@ struct mhi_ep_cntrl { spinlock_t state_lock; =20 struct list_head st_transition_list; + struct list_head ch_db_list; =20 struct workqueue_struct *wq; struct work_struct state_work; @@ -137,6 +140,7 @@ struct mhi_ep_cntrl { u32 chdb_offset; u32 erdb_offset; u32 index; + int irq; }; =20 /** --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC655C433EF for ; Mon, 28 Feb 2022 12:46:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236734AbiB1Mqq (ORCPT ); Mon, 28 Feb 2022 07:46:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236756AbiB1Mqe (ORCPT ); Mon, 28 Feb 2022 07:46:34 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD54E4B439 for ; Mon, 28 Feb 2022 04:45:35 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id j10-20020a17090a94ca00b001bc2a9596f6so11221749pjw.5 for ; Mon, 28 Feb 2022 04:45:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tOKWOiXPdIu4E+xI1dskhzwHubmEMAPM1rfQtzt3OWk=; b=kaYZgUDCVuCj/avIuDWBO2IozU6r/iapJjT8ZrZLe6Jal7igSHxFOCMqt2PBkrXXqu g3+97G7iiQ+36dBNbKB4FU6aX76gHQswYS9ASI6+ex9lNu5uFtWdasRcNT/x56l1Myjp 38jvmo8rwtzH1Jx0kg2tV0E85kj7DQoGF6LGQH4yCoSzcEQLHBow0zg6mw5qsVPN7PBz 4HkxdHABFNURx0ryd6coeZ/swOadzd8TDpFh+5at2qvbB0DqktlXXWSvHCNXFSaTYOaM +03uC4CfJ132IOYuwzkAcmHAmXKw+Th5SMIkuzw7a++b3X6h38U9KIEDoenZrwUreqlM SLJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tOKWOiXPdIu4E+xI1dskhzwHubmEMAPM1rfQtzt3OWk=; b=f6rf50Ok1jhhciWz1J4kiYImHVugUUVTITpALiQwYehlR9++GsH42ijTaqw5R7Tss5 6EVtF4dMPGbKAWZqyOLeN6gVhbvnk0LEVP9JbjdtHSxelBFAVPF/YgrPp4p6RmY4Kl9Z BNssRNaM9uc0TwzMD1XqMs9bIRN0r/vR+x379t95fKXG4vhDW3hjcDsUw1/ik8pPTnkV lt9QaJmwJbofHBOzQ+oRfN5Jd1OJJsb4eLRIRNKAUaIN6yBNKqcxJNkDzQT0jSz7foKn r0At01r2ulJTQEACBdzJD19KjFbzSDjh4AHgkzBVPU/O9qsmvu68t076jrtYc95CA6Vo KUdg== X-Gm-Message-State: AOAM530QY5atDA089NoaoHAA20RNsjf5SDdUnvoXJmPNSmJHbgEB4/QH 6p87dOABrhKW6IrxfxyVvC1v X-Google-Smtp-Source: ABdhPJzR39ku1h3++ACWDSHI+9yf++jektrBKyCYSG06RXV6bUpvl2yrdEPjVgpXQc+vi0eAGf+Xbw== X-Received: by 2002:a17:902:76c7:b0:14f:cbb1:71da with SMTP id j7-20020a17090276c700b0014fcbb171damr20276336plt.39.1646052335040; Mon, 28 Feb 2022 04:45:35 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:34 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 18/27] bus: mhi: ep: Add support for powering up the MHI endpoint stack Date: Mon, 28 Feb 2022 18:13:35 +0530 Message-Id: <20220228124344.77359-19-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for MHI endpoint power_up that includes initializing the MMIO and rings, caching the host MHI registers, and setting the MHI state to M0. After registering the MHI EP controller, the stack has to be powered up for usage. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/internal.h | 6 + drivers/bus/mhi/ep/main.c | 237 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 16 +++ 3 files changed, 259 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 536351218685..a2ec4169a4b2 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -210,4 +210,10 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl= ); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); =20 +/* MHI EP memory management functions */ +int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t = size, + phys_addr_t *phys_ptr, void __iomem **virt); +void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_= addr_t phys, + void __iomem *virt, size_t size); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index ce690b1aeace..47807102baad 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -16,6 +16,9 @@ #include #include "internal.h" =20 +#define MHI_SUSPEND_MIN 100 +#define MHI_SUSPEND_TIMEOUT 600 + static DEFINE_IDA(mhi_ep_cntrl_ida); =20 static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, @@ -106,6 +109,186 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_c= ntrl *mhi_cntrl, enum mhi_e return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); } =20 +int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t = size, + phys_addr_t *phys_ptr, void __iomem **virt) +{ + size_t offset =3D pci_addr % 0x1000; + void __iomem *buf; + phys_addr_t phys; + int ret; + + size +=3D offset; + + buf =3D mhi_cntrl->alloc_addr(mhi_cntrl, &phys, size); + if (!buf) + return -ENOMEM; + + ret =3D mhi_cntrl->map_addr(mhi_cntrl, phys, pci_addr - offset, size); + if (ret) { + mhi_cntrl->free_addr(mhi_cntrl, phys, buf, size); + return ret; + } + + *phys_ptr =3D phys + offset; + *virt =3D buf + offset; + + return 0; +} + +void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_= addr_t phys, + void __iomem *virt, size_t size) +{ + size_t offset =3D pci_addr % 0x1000; + + size +=3D offset; + + mhi_cntrl->unmap_addr(mhi_cntrl, phys - offset); + mhi_cntrl->free_addr(mhi_cntrl, phys - offset, virt - offset, size); +} + +static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret; + + /* Update the number of event rings (NER) programmed by the host */ + mhi_ep_mmio_update_ner(mhi_cntrl); + + dev_dbg(dev, "Number of Event rings: %u, HW Event rings: %u\n", + mhi_cntrl->event_rings, mhi_cntrl->hw_event_rings); + + ch_ctx_host_size =3D sizeof(struct mhi_chan_ctxt) * mhi_cntrl->max_chan; + ev_ctx_host_size =3D sizeof(struct mhi_event_ctxt) * mhi_cntrl->event_rin= gs; + cmd_ctx_host_size =3D sizeof(struct mhi_cmd_ctxt) * NR_OF_CMD_RINGS; + + /* Get the channel context base pointer from host */ + mhi_ep_mmio_get_chc_base(mhi_cntrl); + + /* Allocate and map memory for caching host channel context */ + ret =3D mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, ch_ctx_hos= t_size, + &mhi_cntrl->ch_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->ch_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map ch_ctx_cache\n"); + return ret; + } + + /* Get the event context base pointer from host */ + mhi_ep_mmio_get_erc_base(mhi_cntrl); + + /* Allocate and map memory for caching host event context */ + ret =3D mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, ev_ctx_hos= t_size, + &mhi_cntrl->ev_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->ev_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map ev_ctx_cache\n"); + goto err_ch_ctx; + } + + /* Get the command context base pointer from host */ + mhi_ep_mmio_get_crc_base(mhi_cntrl); + + /* Allocate and map memory for caching host command context */ + ret =3D mhi_ep_alloc_map(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, cmd_ctx_h= ost_size, + &mhi_cntrl->cmd_ctx_cache_phys, + (void __iomem **)&mhi_cntrl->cmd_ctx_cache); + if (ret) { + dev_err(dev, "Failed to allocate and map cmd_ctx_cache\n"); + goto err_ev_ctx; + } + + /* Initialize command ring */ + ret =3D mhi_ep_ring_start(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring, + (union mhi_ep_ring_ctx *)mhi_cntrl->cmd_ctx_cache); + if (ret) { + dev_err(dev, "Failed to start the command ring\n"); + goto err_cmd_ctx; + } + + return ret; + +err_cmd_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_c= tx_cache_phys, + mhi_cntrl->cmd_ctx_cache, cmd_ctx_host_size); + +err_ev_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx= _cache_phys, + mhi_cntrl->ev_ctx_cache, ev_ctx_host_size); + +err_ch_ctx: + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx= _cache_phys, + mhi_cntrl->ch_ctx_cache, ch_ctx_host_size); + + return ret; +} + +static void mhi_ep_free_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; + + ch_ctx_host_size =3D sizeof(struct mhi_chan_ctxt) * mhi_cntrl->max_chan; + ev_ctx_host_size =3D sizeof(struct mhi_event_ctxt) * mhi_cntrl->event_rin= gs; + cmd_ctx_host_size =3D sizeof(struct mhi_cmd_ctxt) * NR_OF_CMD_RINGS; + + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_c= tx_cache_phys, + mhi_cntrl->cmd_ctx_cache, cmd_ctx_host_size); + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx= _cache_phys, + mhi_cntrl->ev_ctx_cache, ev_ctx_host_size); + mhi_ep_unmap_free(mhi_cntrl, mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx= _cache_phys, + mhi_cntrl->ch_ctx_cache, ch_ctx_host_size); +} + +static void mhi_ep_enable_int(struct mhi_ep_cntrl *mhi_cntrl) +{ + /* + * Doorbell interrupts are enabled when the corresponding channel gets st= arted. + * Enabling all interrupts here triggers spurious irqs as some of the int= errupts + * associated with hw channels always get triggered. + */ + mhi_ep_mmio_enable_ctrl_interrupt(mhi_cntrl); + mhi_ep_mmio_enable_cmdb_interrupt(mhi_cntrl); +} + +static int mhi_ep_enable(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 max_cnt =3D 0; + bool mhi_reset; + int ret; + + /* Wait for Host to set the M0 state */ + do { + msleep(MHI_SUSPEND_MIN); + mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset); + if (mhi_reset) { + /* Clear the MHI reset if host is in reset state */ + mhi_ep_mmio_clear_reset(mhi_cntrl); + dev_dbg(dev, "Host initiated reset while waiting for M0\n"); + } + max_cnt++; + } while (state !=3D MHI_STATE_M0 && max_cnt < MHI_SUSPEND_TIMEOUT); + + if (state !=3D MHI_STATE_M0) { + dev_err(dev, "Host failed to enter M0\n"); + return -ETIMEDOUT; + } + + ret =3D mhi_ep_cache_host_cfg(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to cache host config\n"); + return ret; + } + + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS); + + /* Enable all interrupts now */ + mhi_ep_enable_int(mhi_cntrl); + + return 0; +} + static void mhi_ep_state_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , state_work); @@ -249,6 +432,60 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } =20 +int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret, i; + + /* + * Mask all interrupts until the state machine is ready. Interrupts will + * be enabled later with mhi_ep_enable(). + */ + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + mhi_ep_mmio_init(mhi_cntrl); + + mhi_cntrl->mhi_event =3D kzalloc(mhi_cntrl->event_rings * (sizeof(*mhi_cn= trl->mhi_event)), + GFP_KERNEL); + if (!mhi_cntrl->mhi_event) + return -ENOMEM; + + /* Initialize command, channel and event rings */ + mhi_ep_ring_init(&mhi_cntrl->mhi_cmd->ring, RING_TYPE_CMD, 0); + for (i =3D 0; i < mhi_cntrl->max_chan; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_chan[i].ring, RING_TYPE_CH, i); + for (i =3D 0; i < mhi_cntrl->event_rings; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_event[i].ring, RING_TYPE_ER, i); + + mhi_cntrl->mhi_state =3D MHI_STATE_RESET; + + /* Set AMSS EE before signaling ready state */ + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS); + + /* All set, notify the host that we are ready */ + ret =3D mhi_ep_set_ready_state(mhi_cntrl); + if (ret) + goto err_free_event; + + dev_dbg(dev, "READY state notification sent to the host\n"); + + ret =3D mhi_ep_enable(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to enable MHI endpoint\n"); + goto err_free_event; + } + + enable_irq(mhi_cntrl->irq); + mhi_cntrl->enabled =3D true; + + return 0; + +err_free_event: + kfree(mhi_cntrl->mhi_event); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_power_up); + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 43aa9b133db4..1b7dec859a5e 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -65,6 +65,9 @@ struct mhi_ep_db_info { * @ch_ctx_host_pa: Physical address of host channel context data structure * @ev_ctx_host_pa: Physical address of host event context data structure * @cmd_ctx_host_pa: Physical address of host command context data structu= re + * @ch_ctx_cache_phys: Physical address of the host channel context cache + * @ev_ctx_cache_phys: Physical address of the host event context cache + * @cmd_ctx_cache_phys: Physical address of the host command context cache * @chdb: Array of channel doorbell interrupt info * @event_lock: Lock for protecting event rings * @list_lock: Lock for protecting state transition and channel doorbell l= ists @@ -89,6 +92,7 @@ struct mhi_ep_db_info { * @erdb_offset: Event ring doorbell offset set by the host * @index: MHI Endpoint controller index * @irq: IRQ used by the endpoint controller + * @enabled: Check if the endpoint controller is enabled or not */ struct mhi_ep_cntrl { struct device *cntrl_dev; @@ -106,6 +110,9 @@ struct mhi_ep_cntrl { u64 ch_ctx_host_pa; u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + phys_addr_t ch_ctx_cache_phys; + phys_addr_t ev_ctx_cache_phys; + phys_addr_t cmd_ctx_cache_phys; =20 struct mhi_ep_db_info chdb[4]; struct mutex event_lock; @@ -141,6 +148,7 @@ struct mhi_ep_cntrl { u32 erdb_offset; u32 index; int irq; + bool enabled; }; =20 /** @@ -235,4 +243,12 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mh= i_cntrl, */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); =20 +/** + * mhi_ep_power_up - Power up the MHI endpoint stack + * @mhi_cntrl: MHI Endpoint controller + * + * Return: 0 if power up succeeds, a negative error code otherwise. + */ +int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); + #endif --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9F602C433F5 for ; Mon, 28 Feb 2022 12:46:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236791AbiB1Mqw (ORCPT ); Mon, 28 Feb 2022 07:46:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236702AbiB1Mqf (ORCPT ); Mon, 28 Feb 2022 07:46:35 -0500 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02FF475C04 for ; Mon, 28 Feb 2022 04:45:41 -0800 (PST) Received: by mail-pl1-x629.google.com with SMTP id h17so5044372plc.5 for ; Mon, 28 Feb 2022 04:45:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cjaL3c5klwAaHR8oe+s8/ml8ybVCH/8EnrQChldlR1Y=; b=kMfFqpGcZ16z9fckg+IrxDNk3IZnNuqRPsKzp2J9kPuwZcz5F0NMDfiOj0jdPjn0mK IZJIrT5iZXWPjxrH9/WgTBUB3jk2xDhGVJfYU5EtABapv8fDljKOsIz0lfpf/QBst99s ABD57UmIain2MmSmdSIXUM0tFkMoqgTiXmESqE+1uGR+V7qC8+m2vGJQ3/ukoZMiwI2z WWw/gOcdjp+lzdsQ/LKdlZ+/ULud9XSVBBzkd/KSGTPSK5e3o/oN2DhKjBZj3hL83uY9 z2hzbz7VJ5fHdwVIZ57f3QhQd+tL8unut5YobYFGsogiiC/1FnmYvZK0B2UrwNchu/Di E2xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cjaL3c5klwAaHR8oe+s8/ml8ybVCH/8EnrQChldlR1Y=; b=VgKvRvnXDZBcO99g8MexYs+hzZ9xUAMiHQABVfdRymu6Dm0C7k3Juh8/hjNms14/I6 5fs1MS7MY1HBf4vw7zSdT7860AMX/uueuIDToS5ttOWxNz1rLU6pxhzFwbiGTtXz/bLD mI7Hudv93yzvb0RPphpT8GfiZyVhQGzhdZMhuc4e6XdIAaPTjoDOdzTAnpzGQaMSn8x6 eQcryUPm7WWjlun+jJhcRS8gah/2EYzYtsvHFaeE0VydOo0KqNj51B3hCJe+iP8OUpIh S9qdabo4dnlrU6bwugTnHwznaCasANC3Y05moG9rnySG3WgUiG7yYsAnfbuO/mnXc4Vg XYSQ== X-Gm-Message-State: AOAM531R/OUcptpYbOqwywBTxcD/3/3G95eSYjqZE0Dgxuh/1TXOHYU+ dHTZRKSnSlV9M0tceSE0minO X-Google-Smtp-Source: ABdhPJxn6BH5XcZrDldD+MNlK8a9NI2jBN4rh0f9vIHncrIHRucwSBFjti0EbEgr0IQkjNzPpQdSpQ== X-Received: by 2002:a17:902:ab4c:b0:14f:bb61:ef0a with SMTP id ij12-20020a170902ab4c00b0014fbb61ef0amr20267134plb.84.1646052340421; Mon, 28 Feb 2022 04:45:40 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:40 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 19/27] bus: mhi: ep: Add support for powering down the MHI endpoint stack Date: Mon, 28 Feb 2022 18:13:36 +0530 Message-Id: <20220228124344.77359-20-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for MHI endpoint power_down that includes stopping all available channels, destroying the channels, resetting the event and transfer rings and freeing the host cache. The stack will be powered down whenever the physical bus link goes down. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 78 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 +++ 2 files changed, 84 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 47807102baad..4956440273ad 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,8 @@ =20 static DEFINE_IDA(mhi_ep_cntrl_ida); =20 +static int mhi_ep_destroy_device(struct device *dev, void *data); + static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, struct mhi_ring_element *el, bool bei) { @@ -432,6 +434,68 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } =20 +static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_ring *ch_ring, *ev_ring; + struct mhi_result result =3D {}; + struct mhi_ep_chan *mhi_chan; + int i; + + /* Stop all the channels */ + for (i =3D 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan =3D &mhi_cntrl->mhi_chan[i]; + if (!mhi_chan->ring.started) + continue; + + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to client drivers */ + if (mhi_chan->xfer_cb) { + result.transaction_status =3D -ENOTCONN; + result.bytes_xferd =3D 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + mhi_chan->state =3D MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + } + + flush_workqueue(mhi_cntrl->wq); + + /* Destroy devices associated with all channels */ + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_ep_destroy_devi= ce); + + /* Stop and reset the transfer rings */ + for (i =3D 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan =3D &mhi_cntrl->mhi_chan[i]; + if (!mhi_chan->ring.started) + continue; + + ch_ring =3D &mhi_cntrl->mhi_chan[i].ring; + mutex_lock(&mhi_chan->lock); + mhi_ep_ring_reset(mhi_cntrl, ch_ring); + mutex_unlock(&mhi_chan->lock); + } + + /* Stop and reset the event rings */ + for (i =3D 0; i < mhi_cntrl->event_rings; i++) { + ev_ring =3D &mhi_cntrl->mhi_event[i].ring; + if (!ev_ring->started) + continue; + + mutex_lock(&mhi_cntrl->event_lock); + mhi_ep_ring_reset(mhi_cntrl, ev_ring); + mutex_unlock(&mhi_cntrl->event_lock); + } + + /* Stop and reset the command ring */ + mhi_ep_ring_reset(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring); + + mhi_ep_free_host_cfg(mhi_cntrl); + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + + mhi_cntrl->enabled =3D false; +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev =3D &mhi_cntrl->mhi_dev->dev; @@ -486,6 +550,16 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_up); =20 +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) +{ + if (mhi_cntrl->enabled) + mhi_ep_abort_transfer(mhi_cntrl); + + kfree(mhi_cntrl->mhi_event); + disable_irq(mhi_cntrl->irq); +} +EXPORT_SYMBOL_GPL(mhi_ep_power_down); + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); @@ -765,6 +839,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mh= i_cntrl, } EXPORT_SYMBOL_GPL(mhi_ep_register_controller); =20 +/* + * It is expected that the controller drivers will power down the MHI EP s= tack + * using "mhi_ep_power_down()" before calling this function to unregister = themselves. + */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev =3D mhi_cntrl->mhi_dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 1b7dec859a5e..8e062a4c84f4 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -251,4 +251,10 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl = *mhi_cntrl); */ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); =20 +/** + * mhi_ep_power_down - Power down the MHI endpoint stack + * @mhi_cntrl: MHI controller + */ +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); + #endif --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDEF6C433F5 for ; Mon, 28 Feb 2022 12:46:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234616AbiB1MrC (ORCPT ); Mon, 28 Feb 2022 07:47:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236802AbiB1Mqh (ORCPT ); Mon, 28 Feb 2022 07:46:37 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 561FB7806F for ; Mon, 28 Feb 2022 04:45:46 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id bx5so11033744pjb.3 for ; Mon, 28 Feb 2022 04:45:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qAd5tuICBA/mz38+wQcupcTon68tNTjrPLc0vh+jMAQ=; b=qQxVfAVEFMExkMvXsS7AHxIKwhYGmsWPRMGG9908BwLekSgNvfP2V2u5nkHV52YqBE pnpAaKGWzfdtuXxAYcndXjnVkXhSWLHJdGRCedZUSzMlbJ6o7qrpnWbO5tCvA2jDeQcE /+KBaLAuQzO/QYQ+azxkqOqn4HA8E9Q865zjo31g+63yuLQiIqjGMod0MmVgeG6ae+WO P9Ku2e7YAy9cjcMYqQnPPqXwtCXHd2T5zSTpRpUqki/n40RVKxBMA1BuoIF6GEn7b6O8 nmxatfLFConM34h744jzMJeghseJQlHJp99F4IIxeb//xzCT9fFE+THCs6Ls2fn9EHzI PqUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qAd5tuICBA/mz38+wQcupcTon68tNTjrPLc0vh+jMAQ=; b=h8iwpXhuHJtvjm5kHOLQBRWYBkSL2WR8JSgceXA3RdLI1kDT/eKaPm78OukGyhx6Cu prVEWJaJeJdo/fWfd8TBqLtyCFSUdIOgoNUYT+gwITju70BNOQs8dps/h8ejy0x2bTo/ lL4NZgPL30MLhlqv9rz/eDOXM5vc/SlMxaNlMVq0N7lTDuLRYxuluQihTJcO8djWxGlO ZGoS+D6JN6KYk1/JiMHDr8trarlxSeDRQh698rMjPJ9Opz7iI3j8Fe9bfhBb3v8jggf9 FfAuFKyuhNNaoU3YmntL5k0jGMusbt4yk/dme8o4s8obTZD0ybVoZKTkTfRpEk9NbwyE FqLQ== X-Gm-Message-State: AOAM533hLtBFLVZKjWLcC4n3GLq0yyF3zKk5wrSbkK2kGFYrVZ16OqOo PUqYwwJUiDZMzVoUFD6QVSTR X-Google-Smtp-Source: ABdhPJzma/V9/rO3NWuMTq3gWTCShWlgDB6cj601A3a/dFpa8yDSYz4T7+l6rPRRv1oK27mCIfVe/A== X-Received: by 2002:a17:902:f606:b0:14b:4c2d:e1fa with SMTP id n6-20020a170902f60600b0014b4c2de1famr20168442plg.24.1646052345672; Mon, 28 Feb 2022 04:45:45 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:45 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 20/27] bus: mhi: ep: Add support for handling MHI_RESET Date: Mon, 28 Feb 2022 18:13:37 +0530 Message-Id: <20220228124344.77359-21-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for handling MHI_RESET in MHI endpoint stack. MHI_RESET will be issued by the host during shutdown and during error scenario so that it can recover the endpoint device without restarting the whole device. MHI_RESET handling involves resetting the internal MHI registers, data structures, state machines, resetting all channels/rings and setting MHICTRL.RESET bit to 0. Additionally the device will also move to READY state if the reset was due to SYS_ERR. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 53 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 2 ++ 2 files changed, 55 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 4956440273ad..99cbad2a94c9 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -413,6 +413,7 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) struct device *dev =3D &mhi_cntrl->mhi_dev->dev; enum mhi_state state; u32 int_value; + bool mhi_reset; =20 /* Acknowledge the ctrl interrupt */ int_value =3D mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS); @@ -421,6 +422,14 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) /* Check for ctrl interrupt */ if (FIELD_GET(MHI_CTRL_INT_STATUS_MSK, int_value)) { dev_dbg(dev, "Processing ctrl interrupt\n"); + mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset); + if (mhi_reset) { + dev_info(dev, "Host triggered MHI reset!\n"); + disable_irq_nosync(mhi_cntrl->irq); + schedule_work(&mhi_cntrl->reset_work); + return IRQ_HANDLED; + } + mhi_ep_process_ctrl_interrupt(mhi_cntrl, state); } =20 @@ -496,6 +505,49 @@ static void mhi_ep_abort_transfer(struct mhi_ep_cntrl = *mhi_cntrl) mhi_cntrl->enabled =3D false; } =20 +static void mhi_ep_reset_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , reset_work); + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + enum mhi_state cur_state; + int ret; + + mhi_ep_abort_transfer(mhi_cntrl); + + spin_lock_bh(&mhi_cntrl->state_lock); + /* Reset MMIO to signal host that the MHI_RESET is completed in endpoint = */ + mhi_ep_mmio_reset(mhi_cntrl); + cur_state =3D mhi_cntrl->mhi_state; + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* + * Only proceed further if the reset is due to SYS_ERR. The host will + * issue reset during shutdown also and we don't need to do re-init in + * that case. + */ + if (cur_state =3D=3D MHI_STATE_SYS_ERR) { + mhi_ep_mmio_init(mhi_cntrl); + + /* Set AMSS EE before signaling ready state */ + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EE_AMSS); + + /* All set, notify the host that we are ready */ + ret =3D mhi_ep_set_ready_state(mhi_cntrl); + if (ret) + return; + + dev_dbg(dev, "READY state notification sent to the host\n"); + + ret =3D mhi_ep_enable(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to enable MHI endpoint: %d\n", ret); + return; + } + + enable_irq(mhi_cntrl->irq); + } +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev =3D &mhi_cntrl->mhi_dev->dev; @@ -770,6 +822,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi= _cntrl, } =20 INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); + INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); =20 mhi_cntrl->wq =3D alloc_workqueue("mhi_ep_wq", 0, 0); if (!mhi_cntrl->wq) { diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 8e062a4c84f4..e77a7b025430 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -76,6 +76,7 @@ struct mhi_ep_db_info { * @ch_db_list: List of queued channel doorbells * @wq: Dedicated workqueue for handling rings and state changes * @state_work: State transition worker + * @reset_work: Worker for MHI Endpoint reset * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -124,6 +125,7 @@ struct mhi_ep_cntrl { =20 struct workqueue_struct *wq; struct work_struct state_work; + struct work_struct reset_work; =20 void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FF0FC433EF for ; Mon, 28 Feb 2022 12:46:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236822AbiB1MrK (ORCPT ); Mon, 28 Feb 2022 07:47:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236758AbiB1Mqk (ORCPT ); Mon, 28 Feb 2022 07:46:40 -0500 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFD077807E for ; Mon, 28 Feb 2022 04:45:51 -0800 (PST) Received: by mail-pj1-x102c.google.com with SMTP id d15so7698550pjg.1 for ; Mon, 28 Feb 2022 04:45:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2C1yMFxjGjTvy7CTcaK951xmErKjxy0jIgFxKiOd2x8=; b=uCgxUvlhbxXapqigUVqcFyuP9S9KjvbT0yXIw8/FPCsDoaD2hNpa2y3PJzNSNdODAr 5zDhcTr/ij16AhJmkGPyizu6m6bHhQtfS97/5nHbtJQseebt0KAS6FLY4CCg6gC7/GTf iyjobFHGeV21HdU7eOby0Tea6CfGSsJfeWDeDl3oCR1xiOu3s7FSnjpcdUs5NeDiWN/t RAa3QRflTim0C2fmA1sq61+lzsoSO7KF93OI2xS4bVUftnprdOuV2W+odrUxJ0VYZsLa NUXmK0AdFC7VlAvXxN3XZA/TOwzt3c2y3gvZdz6wgL8Qsw8qq9G+9N2X55tNsbIOD8n7 kvTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2C1yMFxjGjTvy7CTcaK951xmErKjxy0jIgFxKiOd2x8=; b=2AIj5ZUM3w9hUO926/N3TQkJV0pgn+q0HBeYvV9hxJQ3vbMuW+LM3l+4dD0ETeviQY uPRayAPGnOPjsUu4pQji4fULtnXk7ijZKW0cAyu/XLJ6DYFIQtXRS+/opgZnjySDE7aO EfUILildZlkuekxESQ4S1VVJoH8xIecl8GN5uctEjPNlBzqrSwqQLphd8U4HGbzKlBvU j7DxDP6l8pEWi7BW0G/VJ2jE6zFHP2NiktwUOZCI2J+z9Wz2ihC3jzebWI3OjtF/64PU 3VqpMoX/LiTOZRkspOi6w4vD/KqJSGLNNqyiFh62hMaotQCtKe1cMmXfk3J8qIVud/Om pi6Q== X-Gm-Message-State: AOAM532np0E/MrwGdPUKakHI8XBz8pDFLPdqL0hAq3bSrt9cV9Yj3hI1 vfRZ0naZZ9u3/8aY/hy9LxlP X-Google-Smtp-Source: ABdhPJyf1eJc3IYDKvt+eJAGN6QzUWzHYipo4VQoUgN4Kv11Lx10mYz/Jhw5zCXCPZ2W0XVnJStrSQ== X-Received: by 2002:a17:902:6b0a:b0:14d:8ee9:3298 with SMTP id o10-20020a1709026b0a00b0014d8ee93298mr20252851plk.125.1646052351008; Mon, 28 Feb 2022 04:45:51 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:50 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 21/27] bus: mhi: ep: Add support for handling SYS_ERR condition Date: Mon, 28 Feb 2022 18:13:38 +0530 Message-Id: <20220228124344.77359-22-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for handling SYS_ERR (System Error) condition in the MHI endpoint stack. The SYS_ERR flag will be asserted by the endpoint device when it detects an internal error. The host will then issue reset and reinitializes MHI to recover from the error state. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/internal.h | 1 + drivers/bus/mhi/ep/main.c | 20 ++++++++++++++++++++ drivers/bus/mhi/ep/sm.c | 11 +++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index a2ec4169a4b2..a229d8b70227 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -209,6 +209,7 @@ int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl= , enum mhi_state mhi_stat int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl); =20 /* MHI EP memory management functions */ int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t = size, diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 99cbad2a94c9..132fd9f51a1f 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -548,6 +548,26 @@ static void mhi_ep_reset_worker(struct work_struct *wo= rk) } } =20 +/* + * We don't need to do anything special other than setting the MHI SYS_ERR + * state. The host will reset all contexts and issue MHI RESET so that we + * could also recover from error state. + */ +void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + int ret; + + ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); + if (ret) + return; + + /* Signal host that the device went to SYS_ERR state */ + ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_SYS_ERR); + if (ret) + dev_err(dev, "Failed sending SYS_ERR state change event: %d\n", ret); +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev =3D &mhi_cntrl->mhi_dev->dev; diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index ad49276ec044..4d6e8c2d615c 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -68,8 +68,10 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); spin_unlock_bh(&mhi_cntrl->state_lock); =20 - if (ret) + if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); return ret; + } =20 /* Signal host that the device moved to M0 */ ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M0); @@ -99,8 +101,10 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); spin_unlock_bh(&mhi_cntrl->state_lock); =20 - if (ret) + if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); return ret; + } =20 /* Signal host that the device moved to M3 */ ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); @@ -132,5 +136,8 @@ int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cnt= rl) ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_READY); spin_unlock_bh(&mhi_cntrl->state_lock); =20 + if (ret) + mhi_ep_handle_syserr(mhi_cntrl); + return ret; } --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA439C433FE for ; Mon, 28 Feb 2022 12:46:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236814AbiB1MrJ (ORCPT ); Mon, 28 Feb 2022 07:47:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236821AbiB1Mqv (ORCPT ); Mon, 28 Feb 2022 07:46:51 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4B5477A99 for ; Mon, 28 Feb 2022 04:45:56 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id gb21so11022745pjb.5 for ; Mon, 28 Feb 2022 04:45:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QjlXVyn2SFmUp4Vpbp1tqUjYVeuv+B4+SU1FNvhrxEY=; b=U3tFyZYIOctncWfQvyZWlNKuyR19c0QFA+6A9rAGeGY9VWIn1HLSvmz0iHfAHVMZ6f Wwv8bmnBuFb8SL0gB5zk68bWuRFPomOEBc4nZ8XLW98dIedQhP/ccnlA27L5QL3qVqn7 xe1UqKNtkocWPFrPgYAqCbCuqPdSqYA7B2mdsLmIdKmxLGDv6d8q1iV4DGl0+XYdGpaa tACE9Wqw0g/seyUaE2dBsKTFN8JXaGH76Dd9ufzRIrgEGyJF3ZBilu4JmSHwE8pad4JD T1LmnMOtfipJfozO0PLilDlpa3xcAEliyER/q7w/gcqznQNdwjx25e31F121gSgVktoC ANJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QjlXVyn2SFmUp4Vpbp1tqUjYVeuv+B4+SU1FNvhrxEY=; b=YbQpURR038/I6viz8yjEi59kDmAQmnVGJ0u/EiyzgKTKQ6p+KpvV9lkpBL6W8wDQW+ U1h8hDeJ+jgUmV43WhBSiAV/8W+l8iO0OBIxOCuXdFSQ1FBiPWhggdXXLnkQJtWVuOT5 IXHdb9IHZ2Xb80QOHdXsms/q5tQdfTQEG6sB6BFyuMIEUutrH5z/RGmdZitD53wsxctg 59VmtVZMEFfF17Qh710D+NO76g5GG4rEwGj/mIEe/DoL+xGDmIhb48YtMqswCW9zsR5W Q2+y03gSp5ETFDJB5uehe8j5oAnSNAmnuDo9//4lSStibOLphB7OboQdnFH/bYOGgk21 +LPQ== X-Gm-Message-State: AOAM530iCOHIdLkqlprwhm3yg3rT1kw9WMsNby2CEzA1cIvIzISiQawv Am8YjfriYBQxGjHB6h+36teB X-Google-Smtp-Source: ABdhPJwK3k1GMV0Qha6To81soExvk1cabhNK9Gc3J777AMcibozPpplWTCf55xADy4eoSrkN+rr8rg== X-Received: by 2002:a17:903:32c2:b0:151:3e13:a33b with SMTP id i2-20020a17090332c200b001513e13a33bmr13892024plr.104.1646052356110; Mon, 28 Feb 2022 04:45:56 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:45:55 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 22/27] bus: mhi: ep: Add support for processing command rings Date: Mon, 28 Feb 2022 18:13:39 +0530 Message-Id: <20220228124344.77359-23-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for processing the command rings. Command ring is used by the host to issue channel specific commands to the ep device. Following commands are supported: 1. Start channel 2. Stop channel 3. Reset channel Once the device receives the command doorbell interrupt from host, it executes the command and generates a command completion event to the host in the primary event ring. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 190 +++++++++++++++++++++++++++++++++++++- include/linux/mhi_ep.h | 2 + 2 files changed, 191 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 132fd9f51a1f..1d4a9f6db8a3 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,7 @@ =20 static DEFINE_IDA(mhi_ep_cntrl_ida); =20 +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id); static int mhi_ep_destroy_device(struct device *dev, void *data); =20 static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, @@ -148,6 +149,156 @@ void mhi_ep_unmap_free(struct mhi_ep_cntrl *mhi_cntrl= , u64 pci_addr, phys_addr_t mhi_cntrl->free_addr(mhi_cntrl, phys - offset, virt - offset, size); } =20 +int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem= ent *el) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D ring->mhi_cntrl; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + struct mhi_result result =3D {}; + struct mhi_ep_chan *mhi_chan; + struct mhi_ep_ring *ch_ring; + u32 tmp, ch_id; + int ret; + + ch_id =3D MHI_TRE_GET_CMD_CHID(el); + mhi_chan =3D &mhi_cntrl->mhi_chan[ch_id]; + ch_ring =3D &mhi_cntrl->mhi_chan[ch_id].ring; + + switch (MHI_TRE_GET_CMD_TYPE(el)) { + case MHI_PKT_TYPE_START_CHAN_CMD: + dev_dbg(dev, "Received START command for channel (%u)\n", ch_id); + + mutex_lock(&mhi_chan->lock); + /* Initialize and configure the corresponding channel ring */ + if (!ch_ring->started) { + ret =3D mhi_ep_ring_start(mhi_cntrl, ch_ring, + (union mhi_ep_ring_ctx *)&mhi_cntrl->ch_ctx_cache[ch_id]); + if (ret) { + dev_err(dev, "Failed to start ring for channel (%u)\n", ch_id); + ret =3D mhi_ep_send_cmd_comp_event(mhi_cntrl, + MHI_EV_CC_UNDEFINED_ERR); + if (ret) + dev_err(dev, "Error sending completion event: %d\n", ret); + + goto err_unlock; + } + } + + /* Set channel state to RUNNING */ + mhi_chan->state =3D MHI_CH_STATE_RUNNING; + tmp =3D le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &=3D ~CHAN_CTX_CHSTATE_MASK; + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg =3D cpu_to_le32(tmp); + + ret =3D mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%u)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + + /* + * Create MHI device only during UL channel start. Since the MHI + * channels operate in a pair, we'll associate both UL and DL + * channels to the same device. + * + * We also need to check for mhi_dev !=3D NULL because, the host + * will issue START_CHAN command during resume and we don't + * destroy the device during suspend. + */ + if (!(ch_id % 2) && !mhi_chan->mhi_dev) { + ret =3D mhi_ep_create_device(mhi_cntrl, ch_id); + if (ret) { + dev_err(dev, "Error creating device for channel (%u)\n", ch_id); + mhi_ep_handle_syserr(mhi_cntrl); + return ret; + } + } + + /* Finally, enable DB for the channel */ + mhi_ep_mmio_enable_chdb(mhi_cntrl, ch_id); + + break; + case MHI_PKT_TYPE_STOP_CHAN_CMD: + dev_dbg(dev, "Received STOP command for channel (%u)\n", ch_id); + if (!ch_ring->started) { + dev_err(dev, "Channel (%u) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Disable DB for the channel */ + mhi_ep_mmio_disable_chdb(mhi_cntrl, ch_id); + + /* Send channel disconnect status to client drivers */ + result.transaction_status =3D -ENOTCONN; + result.bytes_xferd =3D 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to STOP */ + mhi_chan->state =3D MHI_CH_STATE_STOP; + tmp =3D le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &=3D ~CHAN_CTX_CHSTATE_MASK; + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_STOP); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg =3D cpu_to_le32(tmp); + + ret =3D mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%u)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + break; + case MHI_PKT_TYPE_RESET_CHAN_CMD: + dev_dbg(dev, "Received STOP command for channel (%u)\n", ch_id); + if (!ch_ring->started) { + dev_err(dev, "Channel (%u) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Stop and reset the transfer ring */ + mhi_ep_ring_reset(mhi_cntrl, ch_ring); + + /* Send channel disconnect status to client driver */ + result.transaction_status =3D -ENOTCONN; + result.bytes_xferd =3D 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to DISABLED */ + mhi_chan->state =3D MHI_CH_STATE_DISABLED; + tmp =3D le32_to_cpu(mhi_cntrl->ch_ctx_cache[ch_id].chcfg); + tmp &=3D ~CHAN_CTX_CHSTATE_MASK; + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_DISABLED); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg =3D cpu_to_le32(tmp); + + ret =3D mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event (%u)\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + + mutex_unlock(&mhi_chan->lock); + break; + default: + dev_err(dev, "Invalid command received: %lu for channel (%u)\n", + MHI_TRE_GET_CMD_TYPE(el), ch_id); + return -EINVAL; + } + + return 0; + +err_unlock: + mutex_unlock(&mhi_chan->lock); + + return ret; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; @@ -291,6 +442,40 @@ static int mhi_ep_enable(struct mhi_ep_cntrl *mhi_cntr= l) return 0; } =20 +static void mhi_ep_cmd_ring_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , cmd_ring_work); + struct mhi_ep_ring *ring =3D &mhi_cntrl->mhi_cmd->ring; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + struct mhi_ring_element *el; + int ret; + + /* Update the write offset for the ring */ + ret =3D mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write offset for ring\n"); + return; + } + + /* Sanity check to make sure there are elements in the ring */ + if (ring->rd_offset =3D=3D ring->wr_offset) + return; + + /* + * Process command ring element till write offset. In case of an error, j= ust try to + * process next element. + */ + while (ring->rd_offset !=3D ring->wr_offset) { + el =3D &ring->ring_cache[ring->rd_offset]; + + ret =3D mhi_ep_process_cmd_ring(ring, el); + if (ret) + dev_err(dev, "Error processing cmd ring element: %zu\n", ring->rd_offse= t); + + mhi_ep_ring_inc_index(ring); + } +} + static void mhi_ep_state_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , state_work); @@ -434,8 +619,10 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) } =20 /* Check for command doorbell interrupt */ - if (FIELD_GET(MHI_CTRL_INT_STATUS_CRDB_MSK, int_value)) + if (FIELD_GET(MHI_CTRL_INT_STATUS_CRDB_MSK, int_value)) { dev_dbg(dev, "Processing command doorbell interrupt\n"); + queue_work(mhi_cntrl->wq, &mhi_cntrl->cmd_ring_work); + } =20 /* Check for channel interrupts */ mhi_ep_check_channel_interrupt(mhi_cntrl); @@ -843,6 +1030,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mh= i_cntrl, =20 INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); + INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker); =20 mhi_cntrl->wq =3D alloc_workqueue("mhi_ep_wq", 0, 0); if (!mhi_cntrl->wq) { diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index e77a7b025430..681c638833ff 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -77,6 +77,7 @@ struct mhi_ep_db_info { * @wq: Dedicated workqueue for handling rings and state changes * @state_work: State transition worker * @reset_work: Worker for MHI Endpoint reset + * @cmd_ring_work: Worker for processing command rings * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -126,6 +127,7 @@ struct mhi_ep_cntrl { struct workqueue_struct *wq; struct work_struct state_work; struct work_struct reset_work; + struct work_struct cmd_ring_work; =20 void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 596A0C433FE for ; Mon, 28 Feb 2022 12:46:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236775AbiB1MrV (ORCPT ); Mon, 28 Feb 2022 07:47:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40432 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236795AbiB1MrA (ORCPT ); Mon, 28 Feb 2022 07:47:00 -0500 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F4E64C404 for ; Mon, 28 Feb 2022 04:46:01 -0800 (PST) Received: by mail-pg1-x530.google.com with SMTP id o23so11244814pgk.13 for ; Mon, 28 Feb 2022 04:46:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cdY8ebW46Eg2Uu7gUrvw5885hZGTnaEinwVDglEao2Y=; b=P1/zByji5YWV1+kZsgzHTWj0JBDLVEhw5bt0I/jL3oKqpa96BEBq87nvqFL5k8C2QT YJWDCazQoWowB7mqAjrqGCRUEQT0uC+Y+UCxMSHM/rLbt9obCt0ZLijBANbRVuGLWFYy ZQCHjTlnuvdNsM4qjDES3YNR9pIAOGQU1wy7bsNLFp9PtqQuKN4CokQil86vNqJQ/SPw yIjPtYHf4kfDlIJBXTHDpamnVG2QFjbIVYHKwq3gIiC+NUY35W2JQnUvjU3260aP5Gnl 5x66QCsbQg1XD4xnqN5F0zvhSP2oL4Kpx4OwO7rSeab8hMugc6Irv5p9t0VZ+UDF6n+o hlgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cdY8ebW46Eg2Uu7gUrvw5885hZGTnaEinwVDglEao2Y=; b=1gobEGbfd7cn/DcFipuTuEyUqkZ7lmPIAcgIe2iZqunsEgUEM37GB9yZmZzMSXovYD em61rCF7l92vt3jSWAoZTBgcuJ9F7XHMQQMaTkb3QPvE99MmvCUOchs2a6S/yABL4PAj 9kj9ut7wAeDByurrPLg8c4/EDQ/b33l4ZEfmcf4Nseb+M6C7GX6GtJSh0N6B2WXRo5fh hg8G9bXP5dABBGrXvTHrA0oEI3l29kaZAembmZ+QDtBI9eg/V+K3jxuwKPudo7Jh03iK 8NIKsJ1KNG5wNwDHG10Sp/E52j0x4lcKoIkJY+qsr3Yus0tuFqACjuFHbE+dWEO5+O1o l0WA== X-Gm-Message-State: AOAM531pobiVXVAV7K7JJE8nQwMrpJ/abNd64tPo//OqtLnfsMDfRxcl yzy0c240q3A/LGcGNhAbCR9d X-Google-Smtp-Source: ABdhPJwOw5sGNZgPsQfg6sD6KkzfLrZcGQr0LHx5hJMN5GXvEO4W0oGHIXy1zc70ey4PsiIF+Jo/Fw== X-Received: by 2002:a63:d23:0:b0:364:f37b:947d with SMTP id c35-20020a630d23000000b00364f37b947dmr17131138pgl.263.1646052361244; Mon, 28 Feb 2022 04:46:01 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.45.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:46:00 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 23/27] bus: mhi: ep: Add support for reading from the host Date: Mon, 28 Feb 2022 18:13:40 +0530 Message-Id: <20220228124344.77359-24-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Data transfer between host and the ep device happens over the transfer ring associated with each bi-directional channel pair. Host defines the transfer ring by allocating memory for it. The read and write pointer addresses of the transfer ring are stored in the channel context. Once host places the elements in the transfer ring, it increments the write pointer and rings the channel doorbell. Device will receive the doorbell interrupt and will process the transfer ring elements. This commit adds support for reading the transfer ring elements from the transfer ring till write pointer, incrementing the read pointer and finally sending the completion event to the host through corresponding event ring. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 121 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 9 +++ 2 files changed, 130 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 1d4a9f6db8a3..e7c0ef9f281b 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -299,6 +299,127 @@ int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring,= struct mhi_ring_element *e return ret; } =20 +bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_di= rection dir) +{ + struct mhi_ep_chan *mhi_chan =3D (dir =3D=3D DMA_FROM_DEVICE) ? mhi_dev->= dl_chan : + mhi_dev->ul_chan; + struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; + struct mhi_ep_ring *ring =3D &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + return !!(ring->rd_offset =3D=3D ring->wr_offset); +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_is_empty); + +static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl, + struct mhi_ep_ring *ring, + struct mhi_result *result, + u32 len) +{ + struct mhi_ep_chan *mhi_chan =3D &mhi_cntrl->mhi_chan[ring->ch_id]; + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + size_t tr_len, read_offset, write_offset; + struct mhi_ring_element *el; + bool tr_done =3D false; + void *write_addr; + u64 read_addr; + u32 buf_left; + int ret; + + buf_left =3D len; + + do { + /* Don't process the transfer ring if the channel is not in RUNNING stat= e */ + if (mhi_chan->state !=3D MHI_CH_STATE_RUNNING) { + dev_err(dev, "Channel not available\n"); + return -ENODEV; + } + + el =3D &ring->ring_cache[ring->rd_offset]; + + /* Check if there is data pending to be read from previous read operatio= n */ + if (mhi_chan->tre_bytes_left) { + dev_dbg(dev, "TRE bytes remaining: %u\n", mhi_chan->tre_bytes_left); + tr_len =3D min(buf_left, mhi_chan->tre_bytes_left); + } else { + mhi_chan->tre_loc =3D MHI_TRE_DATA_GET_PTR(el); + mhi_chan->tre_size =3D MHI_TRE_DATA_GET_LEN(el); + mhi_chan->tre_bytes_left =3D mhi_chan->tre_size; + + tr_len =3D min(buf_left, mhi_chan->tre_size); + } + + read_offset =3D mhi_chan->tre_size - mhi_chan->tre_bytes_left; + write_offset =3D len - buf_left; + read_addr =3D mhi_chan->tre_loc + read_offset; + write_addr =3D result->buf_addr + write_offset; + + dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_i= d); + ret =3D mhi_cntrl->read_from_host(mhi_cntrl, read_addr, write_addr, tr_l= en); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n"); + return ret; + } + + buf_left -=3D tr_len; + mhi_chan->tre_bytes_left -=3D tr_len; + + /* + * Once the TRE (Transfer Ring Element) of a TD (Transfer Descriptor) ha= s been + * read completely: + * + * 1. Send completion event to the host based on the flags set in TRE. + * 2. Increment the local read offset of the transfer ring. + */ + if (!mhi_chan->tre_bytes_left) { + /* + * The host will split the data packet into multiple TREs if it can't f= it + * the packet in a single TRE. In that case, CHAIN flag will be set by = the + * host for all TREs except the last one. + */ + if (MHI_TRE_DATA_GET_CHAIN(el)) { + /* + * IEOB (Interrupt on End of Block) flag will be set by the host if + * it expects the completion event for all TREs of a TD. + */ + if (MHI_TRE_DATA_GET_IEOB(el)) { + ret =3D mhi_ep_send_completion_event(mhi_cntrl, ring, el, + MHI_TRE_DATA_GET_LEN(el), + MHI_EV_CC_EOB); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, + "Error sending transfer compl. event\n"); + return ret; + } + } + } else { + /* + * IEOT (Interrupt on End of Transfer) flag will be set by the host + * for the last TRE of the TD and expects the completion event for + * the same. + */ + if (MHI_TRE_DATA_GET_IEOT(el)) { + ret =3D mhi_ep_send_completion_event(mhi_cntrl, ring, el, + MHI_TRE_DATA_GET_LEN(el), + MHI_EV_CC_EOT); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, + "Error sending transfer compl. event\n"); + return ret; + } + } + + tr_done =3D true; + } + + mhi_ep_ring_inc_index(ring); + } + + result->bytes_xferd +=3D tr_len; + } while (buf_left && !tr_done); + + return 0; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 681c638833ff..45d12a55b435 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -261,4 +261,13 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); */ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); =20 +/** + * mhi_ep_queue_is_empty - Determine whether the transfer queue is empty + * @mhi_dev: Device associated with the channels + * @dir: DMA direction for the channel + * + * Return: true if the queue is empty, false otherwise. + */ +bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_di= rection dir); + #endif --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C47CCC433F5 for ; Mon, 28 Feb 2022 12:46:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236781AbiB1Mr3 (ORCPT ); Mon, 28 Feb 2022 07:47:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236762AbiB1MrC (ORCPT ); Mon, 28 Feb 2022 07:47:02 -0500 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1E917804E for ; Mon, 28 Feb 2022 04:46:06 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id e13so10628056plh.3 for ; Mon, 28 Feb 2022 04:46:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IIhQUhN2ZaDMAjZZvol3L7EWmR5Y0sj1KhKNQowC/Jw=; b=o6qcAWSguSaU8j/pHUtIBOMLMjbt74TrxHnGx2JCVYfk7+vHSId5QIfaJHCQhIn6LB iQzY/Nam/NKb9FQLgn0lfMknrA9vCvN/fyRktweXYoJeC0bhKPEh9H7Urhc2xfQxw7Cn LS7HiAlKK4vyWeo5U2iSX3W7q4MwOa1LO23SMUYXI7NWOKkV0ykEB54phsnEJx1Vtyob u10LuLHFA2Np1DPSUYEMfd/8JmeKnRw8F8eOdIEpQLm/xoBkjqdufU5I82G9UPq/Slhk FRNYufFzaPDvCD0pD5WyD3frbcBYYVU8IR//bErDxK4RdtHgbQpB251HJcVLiuPgylx9 sJQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IIhQUhN2ZaDMAjZZvol3L7EWmR5Y0sj1KhKNQowC/Jw=; b=lJopuxdorE+zlewKmzbTs+7ussZ0c1frG64PtwHUQcZh4v8/vpYfpu172LLCPijQ+g OaV4/IYD0ZBAk9k10j3F2VE8Jp2YqLkB3MFh9DZVykNoLTn7ZGWHyC9t/xVAAkO59hzh f7jP+wOl0iz6NfOMsvgLJ402iTJpC2Fdw81Gc7E9LRjotD22wgzZTyJcnwDXmkA4mn7Y AQgKHp8Vn998+jCswNlFT97lUC3BLcanu8Em4IX1XWfWvs30/h1Gn8oipGKFmRpSA1LR mXb99yriziZ/xPS0zm+aVL5ZFILLUH67fJlJRbuYxuKXYBvJLxv4oPiulubwmDeSj/HI YCPg== X-Gm-Message-State: AOAM53214HQYoQNvB+WIgsr0iNK+EjcR6HIeb0PzXtFr7JcVpTsKPVU1 Pcvg1cF7rYnh7DNfONPfsblE X-Google-Smtp-Source: ABdhPJzArRZdWJkaALITB+q29+YN6aJkdB+QK8z2+neQLJJMFtfpl1OL86kOTkFjwScD2E1Ds7b9pg== X-Received: by 2002:a17:90a:ac09:b0:1bc:3e9d:158 with SMTP id o9-20020a17090aac0900b001bc3e9d0158mr16328504pjq.235.1646052366361; Mon, 28 Feb 2022 04:46:06 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.46.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:46:06 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 24/27] bus: mhi: ep: Add support for processing channel rings Date: Mon, 28 Feb 2022 18:13:41 +0530 Message-Id: <20220228124344.77359-25-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for processing the channel rings from host. For the channel ring associated with DL channel, the xfer callback will simply invoked. For the case of UL channel, the ring elements will be read in a buffer till the write pointer and later passed to the client driver using the xfer callback. The client drivers should provide the callbacks for both UL and DL channels during registration. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 108 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 2 + 2 files changed, 110 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index e7c0ef9f281b..63e14d55aa06 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -420,6 +420,57 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mh= i_cntrl, return 0; } =20 +int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_eleme= nt *el) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D ring->mhi_cntrl; + struct mhi_result result =3D {}; + u32 len =3D MHI_EP_DEFAULT_MTU; + struct mhi_ep_chan *mhi_chan; + int ret; + + mhi_chan =3D &mhi_cntrl->mhi_chan[ring->ch_id]; + + /* + * Bail out if transfer callback is not registered for the channel. + * This is most likely due to the client driver not loaded at this point. + */ + if (!mhi_chan->xfer_cb) { + dev_err(&mhi_chan->mhi_dev->dev, "Client driver not available\n"); + return -ENODEV; + } + + if (ring->ch_id % 2) { + /* DL channel */ + result.dir =3D mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } else { + /* UL channel */ + result.buf_addr =3D kzalloc(len, GFP_KERNEL); + if (!result.buf_addr) + return -ENOMEM; + + do { + ret =3D mhi_ep_read_channel(mhi_cntrl, ring, &result, len); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); + kfree(result.buf_addr); + return ret; + } + + result.dir =3D mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + result.bytes_xferd =3D 0; + memset(result.buf_addr, 0, len); + + /* Read until the ring becomes empty */ + } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); + + kfree(result.buf_addr); + } + + return 0; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; @@ -597,6 +648,60 @@ static void mhi_ep_cmd_ring_worker(struct work_struct = *work) } } =20 +static void mhi_ep_ch_ring_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , ch_ring_work); + struct device *dev =3D &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_item *itr, *tmp; + struct mhi_ring_element *el; + struct mhi_ep_ring *ring; + struct mhi_ep_chan *chan; + unsigned long flags; + LIST_HEAD(head); + int ret; + + spin_lock_irqsave(&mhi_cntrl->list_lock, flags); + list_splice_tail_init(&mhi_cntrl->ch_db_list, &head); + spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); + + /* Process each queued channel ring. In case of an error, just process ne= xt element. */ + list_for_each_entry_safe(itr, tmp, &head, node) { + list_del(&itr->node); + ring =3D itr->ring; + + /* Update the write offset for the ring */ + ret =3D mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write offset for ring\n"); + kfree(itr); + continue; + } + + /* Sanity check to make sure there are elements in the ring */ + if (ring->rd_offset =3D=3D ring->wr_offset) { + kfree(itr); + continue; + } + + el =3D &ring->ring_cache[ring->rd_offset]; + chan =3D &mhi_cntrl->mhi_chan[ring->ch_id]; + + mutex_lock(&chan->lock); + dev_dbg(dev, "Processing the ring for channel (%u)\n", ring->ch_id); + ret =3D mhi_ep_process_ch_ring(ring, el); + if (ret) { + dev_err(dev, "Error processing ring for channel (%u): %d\n", + ring->ch_id, ret); + mutex_unlock(&chan->lock); + kfree(itr); + continue; + } + + mutex_unlock(&chan->lock); + kfree(itr); + } +} + static void mhi_ep_state_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl =3D container_of(work, struct mhi_ep_cntrl= , state_work); @@ -662,6 +767,8 @@ static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl= *mhi_cntrl, unsigned lon spin_lock(&mhi_cntrl->list_lock); list_splice_tail_init(&head, &mhi_cntrl->ch_db_list); spin_unlock(&mhi_cntrl->list_lock); + + queue_work(mhi_cntrl->wq, &mhi_cntrl->ch_ring_work); } } =20 @@ -1152,6 +1259,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *m= hi_cntrl, INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker); + INIT_WORK(&mhi_cntrl->ch_ring_work, mhi_ep_ch_ring_worker); =20 mhi_cntrl->wq =3D alloc_workqueue("mhi_ep_wq", 0, 0); if (!mhi_cntrl->wq) { diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 45d12a55b435..74170dad09f6 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -78,6 +78,7 @@ struct mhi_ep_db_info { * @state_work: State transition worker * @reset_work: Worker for MHI Endpoint reset * @cmd_ring_work: Worker for processing command rings + * @ch_ring_work: Worker for processing channel rings * @raise_irq: CB function for raising IRQ to the host * @alloc_addr: CB function for allocating memory in endpoint for storing = host context * @map_addr: CB function for mapping host context to endpoint @@ -128,6 +129,7 @@ struct mhi_ep_cntrl { struct work_struct state_work; struct work_struct reset_work; struct work_struct cmd_ring_work; + struct work_struct ch_ring_work; =20 void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *= phys_addr, --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A936C433F5 for ; Mon, 28 Feb 2022 12:46:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236370AbiB1Mrc (ORCPT ); Mon, 28 Feb 2022 07:47:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40604 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236702AbiB1MrQ (ORCPT ); Mon, 28 Feb 2022 07:47:16 -0500 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16EC979C4D for ; Mon, 28 Feb 2022 04:46:13 -0800 (PST) Received: by mail-pf1-x430.google.com with SMTP id g21so4730792pfj.11 for ; Mon, 28 Feb 2022 04:46:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OJYdTNp5Gg/lOgcfWY4Qq4TIlRlc1oamUz2dj4AjBfk=; b=qIzffofDKqZnIYKZBrvcvld9xY59Jed2+kjKTQSYZjX3jlWFMQq0v0SM2kxtlIpkO0 JsW4sujrunw6Yy5aMGAlO0iry6llnHZ5NaxTF347FJsMj7VNjh363hhjfZf4k8HmsSBA TPQEwjwekuGC05vx1X08/ndD3hLpS5ptHwv41t+6KTXfvsdmZtiVeZ//GlsJwdq6zZ8Q LaF9dg2Znwur3CZ5dxgeqC56gwbGVtrW5sJ9DrAEiSPFJQR887u/gYcsF3Ko746TK7+O Qs5VvfdWvkhz7S7HC+D0n0NDrctAMj+Zc97kq3ZGyvUTiAtEwDIELaVbBG30NC5DsWbD micA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OJYdTNp5Gg/lOgcfWY4Qq4TIlRlc1oamUz2dj4AjBfk=; b=XLTIIemp+nKZ4R1R2kQ2BRMGY+AJjyXdT+i/Q2t51lUmt1IA/MR+knqtjzJHN/iAKv C7AdgDJnitTpAlaEsku5Rz1q03CnfJU6aNf8lTyntWoyzZna/VQV6ke/UI+fuwh6/Ooh DOHSnAg9iTyy3ARTL8SaZuADHyeuUq5vpT8AIA+p8f0R0LkE+fC1Ski52lBnAyxwzylQ qx+JHiklhKfwe+VG+RkIXPsbmn5iMtY1I18P2EbaJnAB1ISKKL1dwWYrJLMqUq4cIfKi UIgwadBJK+dNwZaay20aqDf10zgfhbUZb4cwRoI3NHDsvXLwRz5jv4jeWLwLYE+YIXPp dC6w== X-Gm-Message-State: AOAM531QRhmWI0T5QL3wKhO/oPIqeD/tIlG1mWH8Wpjq1gy2y8Om5SAr ZB2Dwzn4p/4udy10YFX9rAS+ X-Google-Smtp-Source: ABdhPJyGvXFHht1Ju98VcuXWZ+wA7qZaQRE+UQ7ts69fGULz/vaYta9lNRr3of+W9cWQdsMXkpBGkg== X-Received: by 2002:a05:6a00:1991:b0:4e1:a7dd:96e5 with SMTP id d17-20020a056a00199100b004e1a7dd96e5mr21800624pfl.2.1646052371636; Mon, 28 Feb 2022 04:46:11 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.46.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:46:11 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 25/27] bus: mhi: ep: Add support for queueing SKBs to the host Date: Mon, 28 Feb 2022 18:13:42 +0530 Message-Id: <20220228124344.77359-26-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for queueing SKBs to the host over the transfer ring of the relevant channel. The mhi_ep_queue_skb() API will be used by the client networking drivers to queue the SKBs to the host over MHI bus. The host will add ring elements to the transfer ring periodically for the device and the device will write SKBs to the ring elements. If a single SKB doesn't fit in a ring element (TRE), it will be placed in multiple ring elements and the overflow event will be sent for all ring elements except the last one. For the last ring element, the EOT event will be sent indicating the packet boundary. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Alex Elder --- drivers/bus/mhi/ep/main.c | 82 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 9 +++++ 2 files changed, 91 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 63e14d55aa06..25d34cf26fd7 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -471,6 +471,88 @@ int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, s= truct mhi_ring_element *el return 0; } =20 +/* TODO: Handle partially formed TDs */ +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) +{ + struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; + struct mhi_ep_chan *mhi_chan =3D mhi_dev->dl_chan; + struct device *dev =3D &mhi_chan->mhi_dev->dev; + struct mhi_ring_element *el; + u32 buf_left, read_offset; + struct mhi_ep_ring *ring; + enum mhi_ev_ccs code; + void *read_addr; + u64 write_addr; + size_t tr_len; + u32 tre_len; + int ret; + + buf_left =3D skb->len; + ring =3D &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + mutex_lock(&mhi_chan->lock); + + do { + /* Don't process the transfer ring if the channel is not in RUNNING stat= e */ + if (mhi_chan->state !=3D MHI_CH_STATE_RUNNING) { + dev_err(dev, "Channel not available\n"); + ret =3D -ENODEV; + goto err_exit; + } + + if (mhi_ep_queue_is_empty(mhi_dev, DMA_FROM_DEVICE)) { + dev_err(dev, "TRE not available!\n"); + ret =3D -ENOSPC; + goto err_exit; + } + + el =3D &ring->ring_cache[ring->rd_offset]; + tre_len =3D MHI_TRE_DATA_GET_LEN(el); + + tr_len =3D min(buf_left, tre_len); + read_offset =3D skb->len - buf_left; + read_addr =3D skb->data + read_offset; + write_addr =3D MHI_TRE_DATA_GET_PTR(el); + + dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id); + ret =3D mhi_cntrl->write_to_host(mhi_cntrl, read_addr, write_addr, tr_le= n); + if (ret < 0) { + dev_err(dev, "Error writing to the channel\n"); + goto err_exit; + } + + buf_left -=3D tr_len; + /* + * For all TREs queued by the host for DL channel, only the EOT flag wil= l be set. + * If the packet doesn't fit into a single TRE, send the OVERFLOW event = to + * the host so that the host can adjust the packet boundary to next TREs= . Else send + * the EOT event to the host indicating the packet boundary. + */ + if (buf_left) + code =3D MHI_EV_CC_OVERFLOW; + else + code =3D MHI_EV_CC_EOT; + + ret =3D mhi_ep_send_completion_event(mhi_cntrl, ring, el, tr_len, code); + if (ret) { + dev_err(dev, "Error sending transfer completion event\n"); + goto err_exit; + } + + mhi_ep_ring_inc_index(ring); + } while (buf_left); + + mutex_unlock(&mhi_chan->lock); + + return 0; + +err_exit: + mutex_unlock(&mhi_chan->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_skb); + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 74170dad09f6..bd3ffde01f04 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -272,4 +272,13 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); */ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_di= rection dir); =20 +/** + * mhi_ep_queue_skb - Send SKBs to host over MHI Endpoint + * @mhi_dev: Device associated with the DL channel + * @skb: SKBs to be queued + * + * Return: 0 if the SKBs has been sent successfully, a negative error code= otherwise. + */ +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb); + #endif --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 586EAC433F5 for ; Mon, 28 Feb 2022 12:47:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236740AbiB1Mri (ORCPT ); Mon, 28 Feb 2022 07:47:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236797AbiB1MrR (ORCPT ); Mon, 28 Feb 2022 07:47:17 -0500 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CCF479C52 for ; Mon, 28 Feb 2022 04:46:17 -0800 (PST) Received: by mail-pf1-x433.google.com with SMTP id z15so11050566pfe.7 for ; Mon, 28 Feb 2022 04:46:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DfwzfNqq6vq0SsTnjLEp+6L4UBQXfn7xq4uvXb2A4qw=; b=bA1BWSLFNpCciGnGldmGs1g305ey7gWYd43oNQc5VxwUczAgrbRw2sleyGyaQ+yTks KIoWCdmI4qVwT2R/y+CkuyNPTHKpcHZxECpjxvZh8d6+KuF2Nh4tEiHZVcmH+kf8VXpn wdDr+0npYRU+vCHEevPo6oY1GTStiukGcKmfZfC4F9ay6enSEPHLTHpZ0Ap6OxDBtkXX u2q1+qlM5qRf1SyzfLkTqEaKaGWxqq47wcYzBNSTshELUZQzOFs8bpZXDhS/fybJxCDU sFnHzByYu3ZTkLQUYCFBHbQvA8kqGS8PheXsfV1lVHZ7E9XR2/Tdc7kE6HCOwnW9+2/b 5vNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DfwzfNqq6vq0SsTnjLEp+6L4UBQXfn7xq4uvXb2A4qw=; b=CPYyGQPSoKPWZyOhR9KIWejELbuNSc9vz6sptD9FIrLHCrYf3rr9sG66hmi/BmLyyE I+CVuBsj2kVjduf3lCmojJ/dyjpDPcr01Sa5857iU05OXkoqn6BLt0aCvT5WonCFaxMf OiiAqeMQPSl9P2obhnv1rZoo2h73QpV9yeagS6ZHLgMi3amBllJNtSwciTf7tn0ZtVMo z0PXP054Hn+xx7NITbrxkdGOXxbXJm1Iw2zSdxaLanpIC6V78fgCVx/IOyhwVU3zxune SlmRoDBu76H427nWeCQ7Kx7RCxeJDSQL7IZ0M6f9K0Mv8gCoKNu8gWo8dzxFz7yR5RFe JKpw== X-Gm-Message-State: AOAM531tTTiPCWxSv9oVNAI5n/FX3WRElNYJ6o9nIuuKa0SliPVDMRfw C/4dYkPbUFaQxoKjayODpF4x X-Google-Smtp-Source: ABdhPJyoDhxnyLLhiXj3FVUBCTzye9LuIHWe8nXli2d39+oXfn3otagNBKy+7n1ttyR5IGl84g15pQ== X-Received: by 2002:a05:6a00:8d5:b0:4e1:77c9:def8 with SMTP id s21-20020a056a0008d500b004e177c9def8mr21504500pfu.55.1646052376709; Mon, 28 Feb 2022 04:46:16 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.46.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:46:16 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 26/27] bus: mhi: ep: Add support for suspending and resuming channels Date: Mon, 28 Feb 2022 18:13:43 +0530 Message-Id: <20220228124344.77359-27-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for suspending and resuming the channels in MHI endpoint stack. The channels will be moved to the suspended state during M3 state transition and will be resumed during M0 transition. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/internal.h | 2 ++ drivers/bus/mhi/ep/main.c | 58 +++++++++++++++++++++++++++++++++++ drivers/bus/mhi/ep/sm.c | 5 +++ 3 files changed, 65 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index a229d8b70227..14fbf4e41ebf 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -210,6 +210,8 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl); int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl); void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl); =20 /* MHI EP memory management functions */ int mhi_ep_alloc_map(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, size_t = size, diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 25d34cf26fd7..3efdbf924076 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1129,6 +1129,64 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntr= l) } EXPORT_SYMBOL_GPL(mhi_ep_power_down); =20 +void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_chan *mhi_chan; + u32 tmp; + int i; + + for (i =3D 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan =3D &mhi_cntrl->mhi_chan[i]; + + if (!mhi_chan->mhi_dev) + continue; + + mutex_lock(&mhi_chan->lock); + /* Skip if the channel is not currently running */ + tmp =3D le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg); + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) !=3D MHI_CH_STATE_RUNNING) { + mutex_unlock(&mhi_chan->lock); + continue; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Suspending channel\n"); + /* Set channel state to SUSPENDED */ + tmp &=3D ~CHAN_CTX_CHSTATE_MASK; + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_SUSPENDED); + mhi_cntrl->ch_ctx_cache[i].chcfg =3D cpu_to_le32(tmp); + mutex_unlock(&mhi_chan->lock); + } +} + +void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_chan *mhi_chan; + u32 tmp; + int i; + + for (i =3D 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan =3D &mhi_cntrl->mhi_chan[i]; + + if (!mhi_chan->mhi_dev) + continue; + + mutex_lock(&mhi_chan->lock); + /* Skip if the channel is not currently suspended */ + tmp =3D le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg); + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) !=3D MHI_CH_STATE_SUSPENDED) { + mutex_unlock(&mhi_chan->lock); + continue; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Resuming channel\n"); + /* Set channel state to RUNNING */ + tmp &=3D ~CHAN_CTX_CHSTATE_MASK; + tmp |=3D FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING); + mhi_cntrl->ch_ctx_cache[i].chcfg =3D cpu_to_le32(tmp); + mutex_unlock(&mhi_chan->lock); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index 4d6e8c2d615c..22b578bd851b 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -62,8 +62,11 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) enum mhi_state old_state; int ret; =20 + /* If MHI is in M3, resume suspended channels */ spin_lock_bh(&mhi_cntrl->state_lock); old_state =3D mhi_cntrl->mhi_state; + if (old_state =3D=3D MHI_STATE_M3) + mhi_ep_resume_channels(mhi_cntrl); =20 ret =3D mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); spin_unlock_bh(&mhi_cntrl->state_lock); @@ -106,6 +109,8 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) return ret; } =20 + mhi_ep_suspend_channels(mhi_cntrl); + /* Signal host that the device moved to M3 */ ret =3D mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); if (ret) { --=20 2.25.1 From nobody Tue Jun 23 19:26:51 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5A7AC433F5 for ; Mon, 28 Feb 2022 12:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236896AbiB1Mrq (ORCPT ); Mon, 28 Feb 2022 07:47:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236780AbiB1MrV (ORCPT ); Mon, 28 Feb 2022 07:47:21 -0500 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3C5D77A98 for ; Mon, 28 Feb 2022 04:46:26 -0800 (PST) Received: by mail-pj1-x1029.google.com with SMTP id h17-20020a17090acf1100b001bc68ecce4aso14665808pju.4 for ; Mon, 28 Feb 2022 04:46:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QFXLiL0cwfTscTFGdegC8jG7wPHkkmACZCaIlJcMC4g=; b=uzElxq1Co02OjZSETgAp4AlzySZjyNblnTFSlL6ekEy2Jd+SYgQjYwySYZULAQ7q2x 8ZiFV6Cy+0OSBZnvRjTjOKqS7pEykVqaaj4UyeRYCEsn38pCIU/up2IWhy7HVzLPiPn3 EPCp/22b8zYfInCnTEp8RFODkrUhClj3vhG0XN73OSdiYlKYdjbZlTljavaUez3WwyQa WIb4pfGWNRgOU23cpCL5KI6wV94q1UvV98RP7k2QkvvYRlWDxa3KmvXFCUU3/l3U4ALX EPZJGDY4CVabi3WzRpEopru76oAs5ypeAU/527dDy0DnyXcJh/YlCZNHEiLtDGOR2Fbn oSNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QFXLiL0cwfTscTFGdegC8jG7wPHkkmACZCaIlJcMC4g=; b=agruv5yv532nygqYY6f0qUwFhmSo3v1UwumDxKJIWxIBnexgjQ7XDbHJfInFp5xfAa Ju/pFYpm48W2DOlBSUBug4VrowkHi0SDFfkaufPwuYD5TawqKJatyLG0sAd/VhjOM+Dt AcH6+tMZxi4a8zs1jBwv2vRwjLYTjywqvUSDuMbP44A8Qv0A7w9w/0oOdxl4DZl/KVtO Vm0zGf/Dunsi+lDIJ809x9e86BQ/wGaAELuVdSSrI70RAO92JXU7bRNgf1MEX4sTZ8jD nAiMPku6N3oDis+ejAu+2TD8Q0CftC7t9QTqSmQVzLaQu+/Dhd2J0yzivQYiaGeYGryN txOw== X-Gm-Message-State: AOAM533U76FNzOivfDvsXclRcvVc8n0jL93Pya6ZnNQX0xgOJtG0rLgF 5Nxa6iNnlHjSuBBuwLTNaUpU X-Google-Smtp-Source: ABdhPJz/l4Rjc3SB1CTovpEU0dkPgKs8YNHZfoD96r0SBLyth0Gw6PheAT7YlRKYUk769a7WkNkUSQ== X-Received: by 2002:a17:90a:241:b0:1bc:1def:a8c5 with SMTP id t1-20020a17090a024100b001bc1defa8c5mr16469088pje.105.1646052382269; Mon, 28 Feb 2022 04:46:22 -0800 (PST) Received: from localhost.localdomain ([117.207.25.37]) by smtp.gmail.com with ESMTPSA id y12-20020a056a00190c00b004f39e28fb87sm14256737pfi.98.2022.02.28.04.46.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 04:46:21 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, quic_vbadigan@quicinc.com, quic_cang@quicinc.com, quic_skananth@quicinc.com, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, Manivannan Sadhasivam Subject: [PATCH v4 27/27] bus: mhi: ep: Add uevent support for module autoloading Date: Mon, 28 Feb 2022 18:13:44 +0530 Message-Id: <20220228124344.77359-28-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> References: <20220228124344.77359-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add uevent support to MHI endpoint bus so that the client drivers can be autoloaded by udev when the MHI endpoint devices gets created. The client drivers are expected to provide MODULE_DEVICE_TABLE with the MHI id_table struct so that the alias can be exported. The MHI endpoint reused the mhi_device_id structure of the MHI bus. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 9 +++++++++ include/linux/mod_devicetable.h | 2 ++ scripts/mod/file2alias.c | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 3efdbf924076..ce59f38b59a7 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1568,6 +1568,14 @@ void mhi_ep_driver_unregister(struct mhi_ep_driver *= mhi_drv) } EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); =20 +static int mhi_ep_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); + + return add_uevent_var(env, "MODALIAS=3D" MHI_EP_DEVICE_MODALIAS_FMT, + mhi_dev->name); +} + static int mhi_ep_match(struct device *dev, struct device_driver *drv) { struct mhi_ep_device *mhi_dev =3D to_mhi_ep_device(dev); @@ -1594,6 +1602,7 @@ struct bus_type mhi_ep_bus_type =3D { .name =3D "mhi_ep", .dev_name =3D "mhi_ep", .match =3D mhi_ep_match, + .uevent =3D mhi_ep_uevent, }; =20 static int __init mhi_ep_init(void) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetabl= e.h index 4bb71979a8fd..0cff19bd72bf 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -835,6 +835,8 @@ struct wmi_device_id { #define MHI_DEVICE_MODALIAS_FMT "mhi:%s" #define MHI_NAME_SIZE 32 =20 +#define MHI_EP_DEVICE_MODALIAS_FMT "mhi_ep:%s" + /** * struct mhi_device_id - MHI device identification * @chan: MHI channel name diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 5258247d78ac..d9d6a31446ea 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1391,6 +1391,15 @@ static int do_mhi_entry(const char *filename, void *= symval, char *alias) return 1; } =20 +/* Looks like: mhi_ep:S */ +static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) +{ + DEF_FIELD_ADDR(symval, mhi_device_id, chan); + sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); + + return 1; +} + /* Looks like: ishtp:{guid} */ static int do_ishtp_entry(const char *filename, void *symval, char *alias) { @@ -1519,6 +1528,7 @@ static const struct devtable devtable[] =3D { {"tee", SIZE_tee_client_device_id, do_tee_entry}, {"wmi", SIZE_wmi_device_id, do_wmi_entry}, {"mhi", SIZE_mhi_device_id, do_mhi_entry}, + {"mhi_ep", SIZE_mhi_device_id, do_mhi_ep_entry}, {"auxiliary", SIZE_auxiliary_device_id, do_auxiliary_entry}, {"ssam", SIZE_ssam_device_id, do_ssam_entry}, {"dfl", SIZE_dfl_device_id, do_dfl_entry}, --=20 2.25.1