From patchwork Thu Dec 2 11:35:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519859 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 9E297C433EF for ; Thu, 2 Dec 2021 11:37:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357385AbhLBLkj (ORCPT ); Thu, 2 Dec 2021 06:40:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357366AbhLBLk1 (ORCPT ); Thu, 2 Dec 2021 06:40:27 -0500 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79880C06175A for ; Thu, 2 Dec 2021 03:37:05 -0800 (PST) Received: by mail-pg1-x52f.google.com with SMTP id r5so26670839pgi.6 for ; Thu, 02 Dec 2021 03:37:05 -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=zSQrFvVjHTaJzL0gVsjBGoHAOZWg6l8th+FI3kjqXKs=; b=bSXW428wdtdO9DwH49nfULKN1eDbS3z5aL2gUUjQsOaWe5OSNWFM/pPqtH9Q7U9Wtb OvL0FBuC2bVXtaZ4LFi4DVGlolMcQ3hqr/eJZPhJzczOAmHY6DxaTklwWB9N4HKz3h0i eTPH6k++lrzkifiwXONxsB6NYI5gz9QrzsYPfHK0QW2ddzlRLXurXAEQgvE0jVRPh7L6 tGk2nDcztFnbYVIGdwMsBxeYgUHFJM+P/+ONv2ua1YIFjcjOqqp6d13mZae8HKqnmEML 7dO86wb65prolayYcQQuNfiLDijmJyyybw5yzKt07qGHMKKGcJSWAit3eBsctrPUfPJ7 RtSA== 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=zSQrFvVjHTaJzL0gVsjBGoHAOZWg6l8th+FI3kjqXKs=; b=1ul8ZpvH0KuJsu47xroay+FwVCcE8VdZa5JgJyBVPSEUEvuFTizBGamZt431IEhCMb 7oOmS86/kIRXe77lYC3pzFylNkAQMkACMLShL3I7+zs/gw9DXr31aKekS2F86xC/tGfK uKee3oFdXAJMkRTvMI0lDW+nYKzcf7TzgnwL1i+WsxBSadpYWryDSd9u6xsZ9CHLwz4v tfCNE9iLfv2jm6zXOVwPSLi/1OQx53KqINLtLv+TXN4/bIBxwLnrc7SiiMJ151yGn36n fHM9v8y5FD1z1w7BZKZ9xFFwoeOuEKBUOUZ/56+iCxlSzoKkIdn8vRN1AgRA4u38h1W8 Umbw== X-Gm-Message-State: AOAM530PUnc598cRbYQBTRNcjMvjHyXv1pBi3bcnCE6dN6NgrZGYvele ESOhklXWfyGPdEyLjeEAyPVF X-Google-Smtp-Source: ABdhPJwPYU/CzBLKi+m9HOdJnKuAuitwHFGyiI5pJkWdv4Kd+Rzlz4zqnY/O6TLn9G4OCyjDBG1XvA== X-Received: by 2002:a63:e50:: with SMTP id 16mr9177720pgo.619.1638445024952; Thu, 02 Dec 2021 03:37:04 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:04 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 01/20] bus: mhi: Move host MHI code to "host" directory Date: Thu, 2 Dec 2021 17:05:33 +0530 Message-Id: <20211202113553.238011-2-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. 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 => host}/Makefile | 4 ++- drivers/bus/mhi/{core => host}/boot.c | 0 drivers/bus/mhi/{core => host}/debugfs.c | 0 drivers/bus/mhi/{core => host}/init.c | 0 drivers/bus/mhi/{core => host}/internal.h | 0 drivers/bus/mhi/{core => host}/main.c | 0 drivers/bus/mhi/{ => host}/pci_generic.c | 0 drivers/bus/mhi/{core => host}/pm.c | 0 12 files changed, 39 insertions(+), 33 deletions(-) create mode 100644 drivers/bus/mhi/host/Kconfig rename drivers/bus/mhi/{core => host}/Makefile (54%) rename drivers/bus/mhi/{core => host}/boot.c (100%) rename drivers/bus/mhi/{core => host}/debugfs.c (100%) rename drivers/bus/mhi/{core => host}/init.c (100%) rename drivers/bus/mhi/{core => host}/internal.h (100%) rename drivers/bus/mhi/{core => host}/main.c (100%) rename drivers/bus/mhi/{ => host}/pci_generic.c (100%) rename drivers/bus/mhi/{core => 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) += vexpress-config.o obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o # MHI -obj-$(CONFIG_MHI_BUS) += mhi/ +obj-y += 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. # -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 += core/ - -obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o -mhi_pci_generic-y += pci_generic.o - +# Host MHI stack +obj-y += 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) += mhi.o - mhi-y := init.o main.o pm.o boot.o mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o + +obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o +mhi_pci_generic-y += 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/internal.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_generic.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 From patchwork Thu Dec 2 11:35:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519858 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 3A20AC433FE for ; Thu, 2 Dec 2021 11:37:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357382AbhLBLkl (ORCPT ); Thu, 2 Dec 2021 06:40:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357375AbhLBLkj (ORCPT ); Thu, 2 Dec 2021 06:40:39 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9A2BC061761 for ; Thu, 2 Dec 2021 03:37:09 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id 133so8595725pgc.12 for ; Thu, 02 Dec 2021 03:37:09 -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=NXz2Nme4PADwb/24qgvdumlpERSiGKFVsXsd62vLlsA=; b=cisksCOP5msegeUQEIqtUG4mcQFciW/n6szlsumHkv4o6ZOjOQ3u+z4/egOC3r+Q7u UXA0OAxFvCZface5eVl6tXOgGGKcjKb9aEAO0N6/ItwClKqN9XcJfcYPc6FARQ4O2JyH GNuV0+MB6nfdsBNAzSVSkB2FpDAFJqW+T1mfgGRtH0b2PnI4lDEbR0+3gPeyUqzFPW+2 EZs535wpFL6v7Kg0SFveCzWMjv8eINnfxYKsBBQW/Qz6sxohm/VA51/6JymTVI8CwHTf khFO9vhRNs+1KuLgSsGfeL3uubI3mfTv4QeryqoIX5tmlgqz314M4XZ3vsjZn3fc+nmK IrzQ== 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=NXz2Nme4PADwb/24qgvdumlpERSiGKFVsXsd62vLlsA=; b=M9RjRn7Sz1mJ7ljym0HiTp+kNn1BQtYiusObUE7XRa9/9wFqGF52ZFHp5z3Mi8qJsO /yIKnF1miYSYwPFXJWUdbI77FL4fOSR/ebkdnvuoi52x27tTgGAR+WPWDAnddwuR8gLn mcsEQzdE5ci60RtCmvKODbjEAwjN3Wc2j57MpBDA5NyXasj7PpirKJ0L1xJET3vg01SU YwnBYtVOinXJZ9jVg+vf7IeUfxCTab3FTpd/HYRa2ypOdAZnfJuyLMIz1qYuceAOb01h FDqPQirOwW3KMvfNsL2Df21TnYeIMms4jtzvzBgvXhQZjxZjLmb1KECH1iqYRKE4li3K gfiQ== X-Gm-Message-State: AOAM5338U/Aa9WMS/OLSpDQPPhS3AdAr6sO6et64PI1yWGMY7/TxigJE EZ5SEGMxfOZSbAL+qMKgaShx X-Google-Smtp-Source: ABdhPJy5uDZgdx3A/+s7eg5KSQSD0syY7NusVOg9oMoJ7bhOAfifYbPtEXPdIFW60GIKBeA3Aewncg== X-Received: by 2002:a05:6a00:1396:b0:4a4:ca76:bc0f with SMTP id t22-20020a056a00139600b004a4ca76bc0fmr12146221pfg.5.1638445029299; Thu, 02 Dec 2021 03:37:09 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:08 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 02/20] bus: mhi: Move common MHI definitions out of host directory Date: Thu, 2 Dec 2021 17:05:34 +0530 Message-Id: <20211202113553.238011-3-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. Still, the MHI register definitions are not moved since the offsets vary between host and endpoint. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/common.h | 182 ++++++++++++++++++++++++++++++++ drivers/bus/mhi/host/internal.h | 154 +-------------------------- 2 files changed, 183 insertions(+), 153 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..0f4f3b9f3027 --- /dev/null +++ b/drivers/bus/mhi/common.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ + +#ifndef _MHI_COMMON_H +#define _MHI_COMMON_H + +#include + +/* 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 (MHI_CMD_NOP << 16) + +/* 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)) + +/* 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)) + +/* 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_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) +#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) + +/* Event descriptor macros */ +/* Transfer completion event */ +#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) + +/* State change event */ +#define MHI_SC_EV_PTR 0 +#define MHI_SC_EV_DWORD0(state) (state << 24) +#define MHI_SC_EV_DWORD1(type) (type << 16) + +/* EE event */ +#define MHI_EE_EV_PTR 0 +#define MHI_EE_EV_DWORD0(ee) (ee << 24) +#define MHI_EE_EV_DWORD1(type) (type << 16) + +/* Command Completion event */ +#define MHI_CC_EV_PTR(ptr) (ptr) +#define MHI_CC_EV_DWORD0(code) (code << 24) +#define MHI_CC_EV_DWORD1(type) (type << 16) + +/* 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 << 10) \ + | (ieot << 9) | (ieob << 8) | chain) + +/* 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) + +enum mhi_pkt_type { + MHI_PKT_TYPE_INVALID = 0x0, + MHI_PKT_TYPE_NOOP_CMD = 0x1, + MHI_PKT_TYPE_TRANSFER = 0x2, + MHI_PKT_TYPE_COALESCING = 0x8, + MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10, + MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11, + MHI_PKT_TYPE_START_CHAN_CMD = 0x12, + MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20, + MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, + MHI_PKT_TYPE_TX_EVENT = 0x22, + MHI_PKT_TYPE_RSC_TX_EVENT = 0x28, + MHI_PKT_TYPE_EE_EVENT = 0x40, + MHI_PKT_TYPE_TSYNC_EVENT = 0x48, + MHI_PKT_TYPE_BW_REQ_EVENT = 0x50, + MHI_PKT_TYPE_STALE_EVENT, /* internal event */ +}; + +/* MHI transfer completion events */ +enum mhi_ev_ccs { + MHI_EV_CC_INVALID = 0x0, + MHI_EV_CC_SUCCESS = 0x1, + MHI_EV_CC_EOT = 0x2, /* End of transfer event */ + MHI_EV_CC_OVERFLOW = 0x3, + MHI_EV_CC_EOB = 0x4, /* End of block event */ + MHI_EV_CC_OOB = 0x5, /* Out of block event */ + MHI_EV_CC_DB_MODE = 0x6, + MHI_EV_CC_UNDEFINED_ERR = 0x10, + MHI_EV_CC_BAD_TRE = 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 = 1, + MHI_CMD_RESET_CHAN = 16, + MHI_CMD_STOP_CHAN = 17, + MHI_CMD_START_CHAN = 18, +}; + +#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 { + __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); +}; + +#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 { + __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); +}; + +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); +}; + +extern const char * const mhi_state_str[MHI_STATE_MAX]; +#define TO_MHI_STATE_STR(state) ((state >= 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/internal.h index 3a732afaf73e..a324a76684d0 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -7,7 +7,7 @@ #ifndef _MHI_INT_H #define _MHI_INT_H -#include +#include "../common.h" extern struct bus_type mhi_bus_type; @@ -203,51 +203,6 @@ extern struct bus_type mhi_bus_type; #define SOC_HW_VERSION_MINOR_VER_BMSK (0x000000FF) #define SOC_HW_VERSION_MINOR_VER_SHFT (0) -#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 { - __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); -}; - -#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 { - __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); -}; - -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); -}; - struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; struct mhi_chan_ctxt *chan_ctxt; @@ -267,108 +222,6 @@ struct bhi_vec_entry { u64 size; }; -enum mhi_cmd_type { - MHI_CMD_NOP = 1, - MHI_CMD_RESET_CHAN = 16, - MHI_CMD_STOP_CHAN = 17, - MHI_CMD_START_CHAN = 18, -}; - -/* 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) - -/* 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)) - -/* 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)) - -/* 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_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) -#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) - -/* 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) - -/* 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 << 10) \ - | (ieot << 9) | (ieob << 8) | chain) - -/* 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) - -enum mhi_pkt_type { - MHI_PKT_TYPE_INVALID = 0x0, - MHI_PKT_TYPE_NOOP_CMD = 0x1, - MHI_PKT_TYPE_TRANSFER = 0x2, - MHI_PKT_TYPE_COALESCING = 0x8, - MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10, - MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11, - MHI_PKT_TYPE_START_CHAN_CMD = 0x12, - MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20, - MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21, - MHI_PKT_TYPE_TX_EVENT = 0x22, - MHI_PKT_TYPE_RSC_TX_EVENT = 0x28, - MHI_PKT_TYPE_EE_EVENT = 0x40, - MHI_PKT_TYPE_TSYNC_EVENT = 0x48, - MHI_PKT_TYPE_BW_REQ_EVENT = 0x50, - MHI_PKT_TYPE_STALE_EVENT, /* internal event */ -}; - -/* MHI transfer completion events */ -enum mhi_ev_ccs { - MHI_EV_CC_INVALID = 0x0, - MHI_EV_CC_SUCCESS = 0x1, - MHI_EV_CC_EOT = 0x2, /* End of transfer event */ - MHI_EV_CC_OVERFLOW = 0x3, - MHI_EV_CC_EOB = 0x4, /* End of block event */ - MHI_EV_CC_OOB = 0x5, /* Out of block event */ - MHI_EV_CC_DB_MODE = 0x6, - MHI_EV_CC_UNDEFINED_ERR = 0x10, - MHI_EV_CC_BAD_TRE = 0x11, -}; - -enum mhi_ch_state { - MHI_CH_STATE_DISABLED = 0x0, - MHI_CH_STATE_ENABLED = 0x1, - MHI_CH_STATE_RUNNING = 0x2, - MHI_CH_STATE_SUSPENDED = 0x3, - MHI_CH_STATE_STOP = 0x4, - MHI_CH_STATE_ERROR = 0x5, -}; - enum mhi_ch_state_type { MHI_CH_STATE_TYPE_RESET, MHI_CH_STATE_TYPE_STOP, @@ -409,11 +262,6 @@ extern const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX]; #define TO_DEV_STATE_TRANS_STR(state) (((state) >= DEV_ST_TRANSITION_MAX) ? \ "INVALID_STATE" : dev_state_tran_str[state]) -extern const char * const mhi_state_str[MHI_STATE_MAX]; -#define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \ - !mhi_state_str[state]) ? \ - "INVALID_STATE" : mhi_state_str[state]) - /* internal power states */ enum mhi_pm_state { MHI_PM_STATE_DISABLE, From patchwork Thu Dec 2 11:35:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520279 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 DC6DCC4332F for ; Thu, 2 Dec 2021 11:37:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357397AbhLBLkl (ORCPT ); Thu, 2 Dec 2021 06:40:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357404AbhLBLkj (ORCPT ); Thu, 2 Dec 2021 06:40:39 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 246EFC0613D7 for ; Thu, 2 Dec 2021 03:37:14 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id iq11so20339308pjb.3 for ; Thu, 02 Dec 2021 03:37: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=44MPCPkBWKMOTQLD9ThY64nAkhMI2QaAg6Wgp+sfo/8=; b=IznxiP5PA7KR8x7WUe0P/ZvJ5sCBzbLkVcwePoGjFS5WsaWqfxF9L0vKlJveOBds7k 6XooxnjtD98qLmNatbTyjBUNR8ybrMSub8Z8CYQLlM8b73jMyhh4XFZgx6/9IjnzS+Nl aYvzninfZJ6iiT65YqRPEuWC11jEiT4We6fyIuJDLSTjf7DhEpw0eNS5qNBcmP8il8Wf FgOod9MUxPf6lXQFqX3RVsXyW9n9LJWW3WDkcOrKMlHt2By4AIoEb0w3fYbrGEhD9F88 XE+ZJzuaNgfHvVG1IkHGd0fwxvY+q9v3FdsBllLGRf3EZ3sJmMnugJszJMX/+katu/dn heNw== 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=44MPCPkBWKMOTQLD9ThY64nAkhMI2QaAg6Wgp+sfo/8=; b=Zb0MRWoPsolQxjo4tlLFxUiqissWsW3GVTvEi/BJLmBQ2PEqNLCwiXaFCNx5Mt9NBx zN10DBPZkIMxFpIfncEGjS2RpMWRxuzkbMbzoc/QDlDuWThfG1zlSo12pxYyR4uTC5sx 5o2O9HbVKy3AsKKH6CCTtp3/GaCKcrpoqYKNnEfq/qYv+dvaSW9GklEdwaWlzRPc9G2W 0d4LUcwVvPiN0mXxerk+lhZTG8rthVYso7N5EhT7v6HAwymNK4dmSyxePm6IC1RalWmW Xt/AJMMzOQNtu6in/YhcsrEodpdS6bExno3hYrJrDIQlv81TZrB+su9D5CT2f+6jT8zj F3sw== X-Gm-Message-State: AOAM531ywHOK9WnaGNzaQ10eiLl4Rrcu+ELbKBjs/+E8iSipV3FBArhz IyigdSaOl1FC89k78OpPoBbD X-Google-Smtp-Source: ABdhPJyEhQ+TkSI2P9Sio8xgTrStr+8mfjRSDmp7hoptpHUOilhSy2VxO3E8eRg9Qrh54/IYmrXqGw== X-Received: by 2002:a17:90b:4c4c:: with SMTP id np12mr5348018pjb.68.1638445033651; Thu, 02 Dec 2021 03:37:13 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:13 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 03/20] bus: mhi: Make mhi_state_str[] array static const and move to common.h Date: Thu, 2 Dec 2021 17:05:35 +0530 Message-Id: <20211202113553.238011-4-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org mhi_state_str[] array could be used by MHI endpoint stack also. So let's make the array as "static const" and move it inside the "common.h" header so that the endpoint stack could also make use of it. Otherwise, the structure definition should be present in both host and endpoint stack and that'll result in duplication. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/common.h | 13 ++++++++++++- drivers/bus/mhi/host/init.c | 12 ------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 0f4f3b9f3027..2ea438205617 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -174,7 +174,18 @@ struct mhi_cmd_ctxt { __u64 wp __packed __aligned(4); }; -extern const char * const mhi_state_str[MHI_STATE_MAX]; +static const char * const mhi_state_str[MHI_STATE_MAX] = { + [MHI_STATE_RESET] = "RESET", + [MHI_STATE_READY] = "READY", + [MHI_STATE_M0] = "M0", + [MHI_STATE_M1] = "M1", + [MHI_STATE_M2] = "M2", + [MHI_STATE_M3] = "M3", + [MHI_STATE_M3_FAST] = "M3 FAST", + [MHI_STATE_BHI] = "BHI", + [MHI_STATE_SYS_ERR] = "SYS ERROR", +}; + #define TO_MHI_STATE_STR(state) ((state >= MHI_STATE_MAX || \ !mhi_state_str[state]) ? \ "INVALID_STATE" : mhi_state_str[state]) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 5aaca6d0f52b..fa904e7468d8 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -44,18 +44,6 @@ const char * const dev_state_tran_str[DEV_ST_TRANSITION_MAX] = { [DEV_ST_TRANSITION_DISABLE] = "DISABLE", }; -const char * const mhi_state_str[MHI_STATE_MAX] = { - [MHI_STATE_RESET] = "RESET", - [MHI_STATE_READY] = "READY", - [MHI_STATE_M0] = "M0", - [MHI_STATE_M1] = "M1", - [MHI_STATE_M2] = "M2", - [MHI_STATE_M3] = "M3", - [MHI_STATE_M3_FAST] = "M3 FAST", - [MHI_STATE_BHI] = "BHI", - [MHI_STATE_SYS_ERR] = "SYS ERROR", -}; - const char * const mhi_ch_state_type_str[MHI_CH_STATE_TYPE_MAX] = { [MHI_CH_STATE_TYPE_RESET] = "RESET", [MHI_CH_STATE_TYPE_STOP] = "STOP", From patchwork Thu Dec 2 11:35:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520278 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 179DCC433EF for ; Thu, 2 Dec 2021 11:37:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357405AbhLBLkm (ORCPT ); Thu, 2 Dec 2021 06:40:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357396AbhLBLkl (ORCPT ); Thu, 2 Dec 2021 06:40:41 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D54DEC06174A for ; Thu, 2 Dec 2021 03:37:18 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id h24so20352655pjq.2 for ; Thu, 02 Dec 2021 03:37:18 -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=+rgjlIFZQkRh7GP5Q8bdJ0KysvgTv10BpYJ2a+ktomI=; b=poLWnZNG7X3up4RqrkA3yKvQlM8HOOeTS+Ui0f4oZUusWrW6M8yguDIRtbXfqdTgCu jMqRmywHwn94/O/GQM/5wFpidBxJQDnOjofZFh51HLQiLUT31t9Z5AInKLf49KXNOs0O yx+udMhTLAvvRApfkslRbsL+V+lhx0AlAEMDe6oJE7J4s2maGhJZ3zFCMLCgrca0bif+ 9kuKyF/dWLdB9l9vkYRVs2v+bwUmhatgNh1guGgkYOCD9vxPVqMMrdsIw4GtL3f2vg8p ywwFYNAh6exTnsJo9eIsD0V99lTMvfGZMMFSauuzaD49ZmA8wdW/BuFfufa2qhi1dRnC Wbzw== 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=+rgjlIFZQkRh7GP5Q8bdJ0KysvgTv10BpYJ2a+ktomI=; b=SP3T3pXDXjLxj2c3hZM+hZS97Zum3jHCQXvDvrQ1nHyzhSRmp1IuX5Q7Cus71VD19B lQX2zAmg7oDd/rXHIRwb9qX9FFAd9Rog5Zj8lXYzly2cApsnJHYDvi4rA9e7W0AnhTQ2 st7UPJwbZMTJ8m/msCrsCd2BGhCbIRqy8tWuZdqgSYumdxIi9QonmvnECrm8ruazAExw 0bsyXbQVCHUD7k9oGQY78mFLh9TCavFLSQxMpucysxIFm9IN8hWk2eL00HISeUEDeogI Mu+Ooip+nPebKC+gfV74mF1WHSmqiUlLfp8xJIPRwuaNEqBlStqwY3dSRvu3tATpB1SX +Iew== X-Gm-Message-State: AOAM5324s+ZR8veI2x8vUmxptjsBOxC6+xN0pvJEjpVt129c9oZr2kjV e04b7KqL6Scv7nmp4ssKOcj7 X-Google-Smtp-Source: ABdhPJycthqRiQJYUCiNautpEHyMOnHDRBBg1ODAfWfzlyQ8UALXECmlmFNItdai2dwXy9Ds0w1AlQ== X-Received: by 2002:a17:90a:1a55:: with SMTP id 21mr5384068pjl.240.1638445038256; Thu, 02 Dec 2021 03:37:18 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:17 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 04/20] bus: mhi: Cleanup the register definitions used in headers Date: Thu, 2 Dec 2021 17:05:36 +0530 Message-Id: <20211202113553.238011-5-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Cleanup includes: 1. Moving the MHI register bit definitions to common.h header (only the register offsets differ between host and ep not the bit definitions) 2. Using the GENMASK macro for masks 3. Removing brackets for single values 4. Using lowercase for hex values Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/common.h | 129 ++++++++++++--- drivers/bus/mhi/host/internal.h | 282 +++++++++++--------------------- 2 files changed, 207 insertions(+), 204 deletions(-) diff --git a/drivers/bus/mhi/common.h b/drivers/bus/mhi/common.h index 2ea438205617..c1272d61e54e 100644 --- a/drivers/bus/mhi/common.h +++ b/drivers/bus/mhi/common.h @@ -9,32 +9,123 @@ #include +/* MHI register bits */ +#define MHIREGLEN_MHIREGLEN_MASK GENMASK(31, 0) +#define MHIREGLEN_MHIREGLEN_SHIFT 0 + +#define MHIVER_MHIVER_MASK GENMASK(31, 0) +#define MHIVER_MHIVER_SHIFT 0 + +#define MHICFG_NHWER_MASK GENMASK(31, 24) +#define MHICFG_NHWER_SHIFT 24 +#define MHICFG_NER_MASK GENMASK(23, 16) +#define MHICFG_NER_SHIFT 16 +#define MHICFG_NHWCH_MASK GENMASK(15, 8) +#define MHICFG_NHWCH_SHIFT 8 +#define MHICFG_NCH_MASK GENMASK(7, 0) +#define MHICFG_NCH_SHIFT 0 + +#define CHDBOFF_CHDBOFF_MASK GENMASK(31, 0) +#define CHDBOFF_CHDBOFF_SHIFT 0 + +#define ERDBOFF_ERDBOFF_MASK GENMASK(31, 0) +#define ERDBOFF_ERDBOFF_SHIFT 0 + +#define BHIOFF_BHIOFF_MASK GENMASK(31, 0) +#define BHIOFF_BHIOFF_SHIFT 0 + +#define BHIEOFF_BHIEOFF_MASK GENMASK(31, 0) +#define BHIEOFF_BHIEOFF_SHIFT 0 + +#define DEBUGOFF_DEBUGOFF_MASK GENMASK(31, 0) +#define DEBUGOFF_DEBUGOFF_SHIFT 0 + +#define MHICTRL_MHISTATE_MASK GENMASK(15, 8) +#define MHICTRL_MHISTATE_SHIFT 8 +#define MHICTRL_RESET_MASK 2 +#define MHICTRL_RESET_SHIFT 1 + +#define MHISTATUS_MHISTATE_MASK GENMASK(15, 8) +#define MHISTATUS_MHISTATE_SHIFT 8 +#define MHISTATUS_SYSERR_MASK 4 +#define MHISTATUS_SYSERR_SHIFT 2 +#define MHISTATUS_READY_MASK 1 +#define MHISTATUS_READY_SHIFT 0 + +#define CCABAP_LOWER_CCABAP_LOWER_MASK GENMASK(31, 0) +#define CCABAP_LOWER_CCABAP_LOWER_SHIFT 0 + +#define CCABAP_HIGHER_CCABAP_HIGHER_MASK GENMASK(31, 0) +#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT 0 + +#define ECABAP_LOWER_ECABAP_LOWER_MASK GENMASK(31, 0) +#define ECABAP_LOWER_ECABAP_LOWER_SHIFT 0 + +#define ECABAP_HIGHER_ECABAP_HIGHER_MASK GENMASK(31, 0) +#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT 0 + +#define CRCBAP_LOWER_CRCBAP_LOWER_MASK GENMASK(31, 0) +#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT 0 + +#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK GENMASK(31, 0) +#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT 0 + +#define CRDB_LOWER_CRDB_LOWER_MASK GENMASK(31, 0) +#define CRDB_LOWER_CRDB_LOWER_SHIFT 0 + +#define CRDB_HIGHER_CRDB_HIGHER_MASK GENMASK(31, 0) +#define CRDB_HIGHER_CRDB_HIGHER_SHIFT 0 + +#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK GENMASK(31, 0) +#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT 0 + +#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK GENMASK(31, 0) +#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT 0 + +#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK GENMASK(31, 0) +#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT 0 + +#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK GENMASK(31, 0) +#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT 0 + +#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK GENMASK(31, 0) +#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT 0 + +#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK GENMASK(31, 0) +#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT 0 + +#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK GENMASK(31, 0) +#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT 0 + +#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK GENMASK(31, 0) +#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT 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_PTR 0 +#define MHI_TRE_CMD_NOOP_DWORD0 0 #define MHI_TRE_CMD_NOOP_DWORD1 (MHI_CMD_NOP << 16) /* Channel reset command */ -#define MHI_TRE_CMD_RESET_PTR (0) -#define MHI_TRE_CMD_RESET_DWORD0 (0) +#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)) /* Channel stop command */ -#define MHI_TRE_CMD_STOP_PTR (0) -#define MHI_TRE_CMD_STOP_DWORD0 (0) +#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)) /* Channel start command */ -#define MHI_TRE_CMD_START_PTR (0) -#define MHI_TRE_CMD_START_DWORD0 (0) +#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_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_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xff) +#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xff) /* Event descriptor macros */ /* Transfer completion event */ @@ -42,18 +133,18 @@ #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_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_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) /* State change event */ #define MHI_SC_EV_PTR 0 diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index a324a76684d0..c882245b9133 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -11,197 +11,109 @@ extern struct bus_type mhi_bus_type; -#define MHIREGLEN (0x0) -#define MHIREGLEN_MHIREGLEN_MASK (0xFFFFFFFF) -#define MHIREGLEN_MHIREGLEN_SHIFT (0) - -#define MHIVER (0x8) -#define MHIVER_MHIVER_MASK (0xFFFFFFFF) -#define MHIVER_MHIVER_SHIFT (0) - -#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 CHDBOFF (0x18) -#define CHDBOFF_CHDBOFF_MASK (0xFFFFFFFF) -#define CHDBOFF_CHDBOFF_SHIFT (0) - -#define ERDBOFF (0x20) -#define ERDBOFF_ERDBOFF_MASK (0xFFFFFFFF) -#define ERDBOFF_ERDBOFF_SHIFT (0) - -#define BHIOFF (0x28) -#define BHIOFF_BHIOFF_MASK (0xFFFFFFFF) -#define BHIOFF_BHIOFF_SHIFT (0) - -#define BHIEOFF (0x2C) -#define BHIEOFF_BHIEOFF_MASK (0xFFFFFFFF) -#define BHIEOFF_BHIEOFF_SHIFT (0) - -#define DEBUGOFF (0x30) -#define DEBUGOFF_DEBUGOFF_MASK (0xFFFFFFFF) -#define DEBUGOFF_DEBUGOFF_SHIFT (0) - -#define MHICTRL (0x38) -#define MHICTRL_MHISTATE_MASK (0x0000FF00) -#define MHICTRL_MHISTATE_SHIFT (8) -#define MHICTRL_RESET_MASK (0x2) -#define MHICTRL_RESET_SHIFT (1) - -#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 CCABAP_LOWER (0x58) -#define CCABAP_LOWER_CCABAP_LOWER_MASK (0xFFFFFFFF) -#define CCABAP_LOWER_CCABAP_LOWER_SHIFT (0) - -#define CCABAP_HIGHER (0x5C) -#define CCABAP_HIGHER_CCABAP_HIGHER_MASK (0xFFFFFFFF) -#define CCABAP_HIGHER_CCABAP_HIGHER_SHIFT (0) - -#define ECABAP_LOWER (0x60) -#define ECABAP_LOWER_ECABAP_LOWER_MASK (0xFFFFFFFF) -#define ECABAP_LOWER_ECABAP_LOWER_SHIFT (0) - -#define ECABAP_HIGHER (0x64) -#define ECABAP_HIGHER_ECABAP_HIGHER_MASK (0xFFFFFFFF) -#define ECABAP_HIGHER_ECABAP_HIGHER_SHIFT (0) - -#define CRCBAP_LOWER (0x68) -#define CRCBAP_LOWER_CRCBAP_LOWER_MASK (0xFFFFFFFF) -#define CRCBAP_LOWER_CRCBAP_LOWER_SHIFT (0) - -#define CRCBAP_HIGHER (0x6C) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_MASK (0xFFFFFFFF) -#define CRCBAP_HIGHER_CRCBAP_HIGHER_SHIFT (0) - -#define CRDB_LOWER (0x70) -#define CRDB_LOWER_CRDB_LOWER_MASK (0xFFFFFFFF) -#define CRDB_LOWER_CRDB_LOWER_SHIFT (0) - -#define CRDB_HIGHER (0x74) -#define CRDB_HIGHER_CRDB_HIGHER_MASK (0xFFFFFFFF) -#define CRDB_HIGHER_CRDB_HIGHER_SHIFT (0) - -#define MHICTRLBASE_LOWER (0x80) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_LOWER_MHICTRLBASE_LOWER_SHIFT (0) - -#define MHICTRLBASE_HIGHER (0x84) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLBASE_HIGHER_MHICTRLBASE_HIGHER_SHIFT (0) - -#define MHICTRLLIMIT_LOWER (0x88) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_LOWER_MHICTRLLIMIT_LOWER_SHIFT (0) - -#define MHICTRLLIMIT_HIGHER (0x8C) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHICTRLLIMIT_HIGHER_MHICTRLLIMIT_HIGHER_SHIFT (0) - -#define MHIDATABASE_LOWER (0x98) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_MASK (0xFFFFFFFF) -#define MHIDATABASE_LOWER_MHIDATABASE_LOWER_SHIFT (0) - -#define MHIDATABASE_HIGHER (0x9C) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATABASE_HIGHER_MHIDATABASE_HIGHER_SHIFT (0) - -#define MHIDATALIMIT_LOWER (0xA0) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_LOWER_MHIDATALIMIT_LOWER_SHIFT (0) - -#define MHIDATALIMIT_HIGHER (0xA4) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF) -#define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0) +/* MHI registers */ +#define MHIREGLEN 0x0 +#define MHIVER 0x8 +#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) +#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 (0x3FFFFFFF) -#define BHI_TXDB_SEQNUM_SHFT (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 (0xC0000000) -#define BHI_STATUS_SHIFT (30) -#define BHI_STATUS_ERROR (3) -#define BHI_STATUS_SUCCESS (2) -#define BHI_STATUS_RESET (0) +#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_TXDB_SEQNUM_SHFT 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_SHIFT 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 (0x3FFFFFFF) -#define BHIE_TXVECDB_SEQNUM_SHFT (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_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 (0x3FFFFFFF) -#define BHIE_RXVECDB_SEQNUM_SHFT (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_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 (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 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_TXVECDB_SEQNUM_SHFT 0 +#define BHIE_TXVECSTATUS_OFFS 0x0044 +#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_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_RXVECDB_SEQNUM_SHFT 0 +#define BHIE_RXVECSTATUS_OFFS 0x0078 +#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 + +#define SOC_HW_VERSION_OFFS 0x224 +#define SOC_HW_VERSION_FAM_NUM_BMSK GENMASK(31, 28) +#define SOC_HW_VERSION_FAM_NUM_SHFT 28 +#define SOC_HW_VERSION_DEV_NUM_BMSK GENMASK(27, 16) +#define SOC_HW_VERSION_DEV_NUM_SHFT 16 +#define SOC_HW_VERSION_MAJOR_VER_BMSK GENMASK(15, 8) +#define SOC_HW_VERSION_MAJOR_VER_SHFT 8 +#define SOC_HW_VERSION_MINOR_VER_BMSK GENMASK(7, 0) +#define SOC_HW_VERSION_MINOR_VER_SHFT 0 struct mhi_ctxt { struct mhi_event_ctxt *er_ctxt; From patchwork Thu Dec 2 11:35:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519857 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 D1D28C433EF for ; Thu, 2 Dec 2021 11:37:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357420AbhLBLkq (ORCPT ); Thu, 2 Dec 2021 06:40:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357396AbhLBLkp (ORCPT ); Thu, 2 Dec 2021 06:40:45 -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 6FAD3C06174A for ; Thu, 2 Dec 2021 03:37:23 -0800 (PST) Received: by mail-pf1-x433.google.com with SMTP id x131so27612518pfc.12 for ; Thu, 02 Dec 2021 03:37:23 -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=bSNDgfSnnHSOAxLz//LJ0mPnxALqBXxPZ9zRcv3JEOA=; b=OWfUMCs4dJLO7/cdowviPLJyDrwRiTx3iQCaYFZ2spGszC0aIVCHyn2cyAGn1fza5K UHULhAjLxPNCSi3h/qZ5PsgJvm3EK6Cs9sNX1khsJeQVlA7usz71H+prEUZ+NQtTG8au w3nx+UrQBe/fcOjRy5lGmQ69NtE5stT1PmYr8AJY2SKlE5cQLqkCbdgWP7CtHNwHHVVv /FY+2ZzBGhyj1CDbfGX+7VFhlUtXpP1vEjxD95AGy4JCgIyoLfxNxnf26yhyt1EHrTUK HL9QG/HA42gt66Ci9wjRU3pSxnNmta35MxLyAJWSkEmEcyGOaC7u7oWwDrTLLT1DHDyn VnNA== 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=bSNDgfSnnHSOAxLz//LJ0mPnxALqBXxPZ9zRcv3JEOA=; b=rzhjI1PoquQG4rewrjd55z70tqhJjhhK5r8Bgy+bam3oBkjnLOEmLsJSYOJrNc/fwc fv5qzAEtCgpHkV0Wgq+t1m75hbONCgPvfRJou+VmOknVwG0upXDJTWE3ldLPV9NcYTgN zBscPNu/W7vo9BeoVzON7M8iuEmjiZpidwo6gxzHSbRR1bgmblTuJ4K0ATe1K/Q9+hTa YRrWw7YF9ZzTNAv7zeSFIPYRISWdu4p01h0yPlEo2cEVb4XT79+LAXSFIALF3z1QT4PP AaB481spqF9kYIv4C96/p0CKk6YvaIzP8skGdlCZFU5yjQFsJ/s8pvz042ms36CCbFOE Dz4A== X-Gm-Message-State: AOAM533j/KDk+qadPdLRFddhZqpAe7R5FrrQils2p2AaCFEnDipunCl/ /CtNCpsUtS6TgNCu1g4GoMhm X-Google-Smtp-Source: ABdhPJyszZmXWHMOrMoGCnQ1BnaJuWKuaCpr8XcvVNwko8bdDdqbyVLc1NGMYCQF/yIth9DgqHkV9g== X-Received: by 2002:a63:a556:: with SMTP id r22mr7069339pgu.587.1638445042795; Thu, 02 Dec 2021 03:37:22 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:22 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 05/20] bus: mhi: ep: Add support for registering MHI endpoint controllers Date: Thu, 2 Dec 2021 17:05:37 +0530 Message-Id: <20211202113553.238011-6-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This commit adds support for registering MHI endpoint controller drivers with the MHI endpoint stack. MHI endpoint controller drivers manages 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. 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. Signed-off-by: Manivannan Sadhasivam --- 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 | 158 +++++++++++++++++++++++ drivers/bus/mhi/ep/main.c | 231 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 140 +++++++++++++++++++++ 7 files changed, 545 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 @@ # 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 += host/ + +# Endpoint MHI stack +obj-y += ep/ diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig new file mode 100644 index 000000000000..229c71397b30 --- /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 the host processors to control + and communicate with modem devices over a high speed peripheral + bus or shared memory. + + MHI_BUS_EP implements the MHI protocol for the endpoint devices + like 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) += mhi_ep.o +mhi_ep-y := main.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h new file mode 100644 index 000000000000..7b164daf4332 --- /dev/null +++ b/drivers/bus/mhi/ep/internal.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ + +#ifndef _MHI_EP_INTERNAL_ +#define _MHI_EP_INTERNAL_ + +#include + +#include "../common.h" + +extern struct bus_type mhi_ep_bus_type; + +/* MHI register definitions */ +#define MHIREGLEN 0x100 +#define MHIVER 0x108 +#define MHICFG 0x110 +#define CHDBOFF 0x118 +#define ERDBOFF 0x120 +#define BHIOFF 0x128 +#define DEBUGOFF 0x130 +#define MHICTRL 0x138 +#define MHISTATUS 0x148 +#define CCABAP_LOWER 0x158 +#define CCABAP_HIGHER 0x15c +#define ECABAP_LOWER 0x160 +#define ECABAP_HIGHER 0x164 +#define CRCBAP_LOWER 0x168 +#define CRCBAP_HIGHER 0x16c +#define CRDB_LOWER 0x170 +#define CRDB_HIGHER 0x174 +#define MHICTRLBASE_LOWER 0x180 +#define MHICTRLBASE_HIGHER 0x184 +#define MHICTRLLIMIT_LOWER 0x188 +#define MHICTRLLIMIT_HIGHER 0x18c +#define MHIDATABASE_LOWER 0x198 +#define MHIDATABASE_HIGHER 0x19c +#define MHIDATALIMIT_LOWER 0x1a0 +#define MHIDATALIMIT_HIGHER 0x1a4 +#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 BHI_INTVEC 0x220 +#define BHI_EXECENV 0x228 +#define BHI_IMGTXDB 0x218 + +#define MHI_CTRL_INT_STATUS_A7 0x4 +#define MHI_CTRL_INT_STATUS_A7_MSK BIT(0) +#define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1) +#define MHI_CHDB_INT_STATUS_A7_n(n) (0x28 + 0x4 * (n)) +#define MHI_ERDB_INT_STATUS_A7_n(n) (0x38 + 0x4 * (n)) + +#define MHI_CTRL_INT_CLEAR_A7 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_A7_n(n) (0x70 + 0x4 * (n)) +#define MHI_CHDB_INT_CLEAR_A7_n_CLEAR_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_CLEAR_A7_n(n) (0x80 + 0x4 * (n)) +#define MHI_ERDB_INT_CLEAR_A7_n_CLEAR_ALL GENMASK(31, 0) + +#define MHI_CTRL_INT_MASK_A7 0x94 +#define MHI_CTRL_INT_MASK_A7_MASK_MASK GENMASK(1, 0) +#define MHI_CTRL_MHICTRL_MASK BIT(0) +#define MHI_CTRL_MHICTRL_SHFT 0 +#define MHI_CTRL_CRDB_MASK BIT(1) +#define MHI_CTRL_CRDB_SHFT 1 + +#define MHI_CHDB_INT_MASK_A7_n(n) (0xb8 + 0x4 * (n)) +#define MHI_CHDB_INT_MASK_A7_n_EN_ALL GENMASK(31, 0) +#define MHI_ERDB_INT_MASK_A7_n(n) (0xc8 + 0x4 * (n)) +#define MHI_ERDB_INT_MASK_A7_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 { + __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); +}; + +enum mhi_ep_ring_state { + RING_STATE_UINT = 0, + RING_STATE_IDLE, +}; + +enum mhi_ep_ring_type { + RING_TYPE_CMD = 0, + RING_TYPE_ER, + RING_TYPE_CH, + RING_TYPE_INVALID, +}; + +struct mhi_ep_ring_element { + u64 ptr; + u32 dword[2]; +}; + +/* Transfer ring element type */ +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 list_head list; + struct mhi_ep_cntrl *mhi_cntrl; + int (*ring_cb)(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); + union mhi_ep_ring_ctx *ring_ctx; + struct mhi_ep_ring_element *ring_cache; + enum mhi_ep_ring_type type; + enum mhi_ep_ring_state state; + 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..db664360c8ab --- /dev/null +++ b/drivers/bus/mhi/ep/main.c @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MHI Bus Endpoint stack + * + * Copyright (C) 2021 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 = to_mhi_ep_device(dev); + + /* + * We need to set the mhi_chan->mhi_dev to NULL here since the MHI + * devices for the channels will only get created if the mhi_dev + * associated with it is NULL. + */ + if (mhi_dev->ul_chan) + mhi_dev->ul_chan->mhi_dev = NULL; + + if (mhi_dev->dl_chan) + mhi_dev->dl_chan->mhi_dev = NULL; + + kfree(mhi_dev); +} + +static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_device *mhi_dev; + struct device *dev; + + mhi_dev = kzalloc(sizeof(*mhi_dev), GFP_KERNEL); + if (!mhi_dev) + return ERR_PTR(-ENOMEM); + + dev = &mhi_dev->dev; + device_initialize(dev); + dev->bus = &mhi_ep_bus_type; + dev->release = mhi_ep_release_device; + + if (mhi_cntrl->mhi_dev) { + /* for MHI client devices, parent is the MHI controller device */ + dev->parent = &mhi_cntrl->mhi_dev->dev; + } else { + /* for MHI controller device, parent is the bus device (e.g. PCI EPF) */ + dev->parent = mhi_cntrl->cntrl_dev; + } + + mhi_dev->mhi_cntrl = mhi_cntrl; + + return mhi_dev; +} + +static int parse_ch_cfg(struct mhi_ep_cntrl *mhi_cntrl, + const struct mhi_ep_cntrl_config *config) +{ + const struct mhi_ep_channel_config *ch_cfg; + struct device *dev = mhi_cntrl->cntrl_dev; + u32 chan, i; + int ret = -EINVAL; + + mhi_cntrl->max_chan = config->max_channels; + + /* + * Allocate max_channels supported by the MHI endpoint and populate + * only the defined channels + */ + mhi_cntrl->mhi_chan = kcalloc(mhi_cntrl->max_chan, sizeof(*mhi_cntrl->mhi_chan), + GFP_KERNEL); + if (!mhi_cntrl->mhi_chan) + return -ENOMEM; + + for (i = 0; i < config->num_channels; i++) { + struct mhi_ep_chan *mhi_chan; + + ch_cfg = &config->ch_cfg[i]; + + chan = ch_cfg->num; + if (chan >= mhi_cntrl->max_chan) { + dev_err(dev, "Channel %d not available\n", chan); + goto error_chan_cfg; + } + + mhi_chan = &mhi_cntrl->mhi_chan[chan]; + mhi_chan->name = ch_cfg->name; + mhi_chan->chan = chan; + mhi_chan->dir = ch_cfg->dir; + mutex_init(&mhi_chan->lock); + + /* Bi-directional and direction less channels are not supported */ + if (mhi_chan->dir == DMA_BIDIRECTIONAL || mhi_chan->dir == DMA_NONE) { + dev_err(dev, "Invalid channel configuration\n"); + goto error_chan_cfg; + } + } + + 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 = parse_ch_cfg(mhi_cntrl, config); + if (ret) + return ret; + + mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); + if (!mhi_cntrl->mhi_cmd) { + ret = -ENOMEM; + goto err_free_ch; + } + + /* Set controller index */ + mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); + if (mhi_cntrl->index < 0) { + ret = mhi_cntrl->index; + goto err_free_cmd; + } + + /* Allocate the controller device */ + mhi_dev = mhi_ep_alloc_device(mhi_cntrl); + if (IS_ERR(mhi_dev)) { + dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); + ret = PTR_ERR(mhi_dev); + goto err_ida_free; + } + + mhi_dev->dev_type = MHI_DEVICE_CONTROLLER; + dev_set_name(&mhi_dev->dev, "mhi_ep%d", mhi_cntrl->index); + mhi_dev->name = dev_name(&mhi_dev->dev); + + ret = device_add(&mhi_dev->dev); + if (ret) + goto err_release_dev; + + mhi_cntrl->mhi_dev = mhi_dev; + + dev_dbg(&mhi_dev->dev, "MHI EP Controller registered\n"); + + return 0; + +err_release_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 = 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 = 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 == MHI_DEVICE_CONTROLLER) + return 0; + + return 0; +}; + +struct bus_type mhi_ep_bus_type = { + .name = "mhi_ep", + .dev_name = "mhi_ep", + .match = 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..14fd40af8974 --- /dev/null +++ b/include/linux/mhi_ep.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021, Linaro Ltd. + * + */ +#ifndef _MHI_EP_H_ +#define _MHI_EP_H_ + +#include +#include + +#define MHI_EP_DEFAULT_MTU 0x4000 + +/** + * struct mhi_ep_channel_config - Channel configuration structure for controller + * @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 + * @max_channels: Maximum number of channels supported + * @num_channels: Number of channels defined in @ch_cfg + * @ch_cfg: Array of defined channels + * @mhi_version: MHI spec version supported by the controller + */ +struct mhi_ep_cntrl_config { + u32 max_channels; + u32 num_channels; + const struct mhi_ep_channel_config *ch_cfg; + u32 mhi_version; +}; + +/** + * 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 storing host context + * @unmap_addr: CB function to unmap the host context in endpoint + * @mhi_state: MHI Endpoint state + * @max_chan: Maximum channels supported by 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); + 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, u64 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); + + enum mhi_state mhi_state; + + u32 max_chan; + int index; +}; + +/** + * struct mhi_ep_device - Structure representing an MHI Endpoint device that 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 + * @ul_chan_id: Channel id for UL transfer + * @dl_chan_id: Channel id for DL transfer + */ +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; + int ul_chan_id; + int dl_chan_id; +}; + +#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 otherwise. + */ +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 From patchwork Thu Dec 2 11:35:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520277 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 6D621C433F5 for ; Thu, 2 Dec 2021 11:37:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357429AbhLBLlA (ORCPT ); Thu, 2 Dec 2021 06:41:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357447AbhLBLku (ORCPT ); Thu, 2 Dec 2021 06:40:50 -0500 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B4BBC061759 for ; Thu, 2 Dec 2021 03:37:28 -0800 (PST) Received: by mail-pg1-x52f.google.com with SMTP id r138so26685363pgr.13 for ; Thu, 02 Dec 2021 03:37:28 -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=pQ5+JHiLyGpfXmy2bsX3P8Df+ylH09T7mwEUuuuixTs=; b=SOqs8efhcz0+ib+JhnFnjXq3AgpFPZWSBwTD0qos3KsEN+S+uuhWj+1qoZf9+c7F9J 3ug5tChJ7O7T76gPnnwv22leOUPQuTrA2MjKFWRNPiFK0fNV5h7bp2CGJ4v1yLZFqe1N MjTutvXWYXu5rgO7CxOnP1BFlIioQB83AFyRIWnEXTp6VT+vm2MC5Yy1RV7e2N6LFv4Z ihZtFR36Pd1NP2wRcUrXr2wh2Qd1iQwWKvQu2Kf/idkRiq0P80IUNzJIDM/nKAC2Taoi cGqNbHTEFe1EmuQ/MbbUU394Ymj37ytl3qru4UrpNecejIemtRLwi3sFeRJxXeLbKjZL 3LZw== 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=pQ5+JHiLyGpfXmy2bsX3P8Df+ylH09T7mwEUuuuixTs=; b=aFejxC+VXIYJDyf5WDP2JAvhNDL9d6dQWj16QBk24oSdwpgFomYJsWQI5lVE45BcaY vhcIPDCMWJAGAW6mRD47mB1mbNv1OckT1tNLk3id+/jI+wG7WJikjyrDCfxjc+zGkM5s IDok0WcwlV733dVaszkifblhz15cg1Ru35F4kaIOAciNAt3uqRFF6GcR5WyYbtC0KOqU G5mTw5kXOOzOfi3mcP9SK8TO8oDfmPa2LpJ9LSRdbkd9KT/wNdAIbQq8rxCMBcTb+/sW u2UVZ3BdDe6EhA6ppzR2XEbSvaPPmLtlahKKvg6uSC3DwkDiqwUO9dwgb8XJGNAGd5yR omog== X-Gm-Message-State: AOAM531A/WvsaS8vs63Wa8aeKwNjp/woTF1rCaT7OkfJ+YaQT8opZRPS 9Z2iO87Bz62gX/j9J2GA0h2i X-Google-Smtp-Source: ABdhPJwoMatBfxxHTzgLxRPvhk5QJKQHuZ6U2D2hQf9FWvqoI7GyI5TfAiyNwcJaFjHEuEKzsHdC2g== X-Received: by 2002:a62:5142:0:b0:4a3:4d13:e7da with SMTP id f63-20020a625142000000b004a34d13e7damr12150089pfb.84.1638445047944; Thu, 02 Dec 2021 03:37:27 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:27 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 06/20] bus: mhi: ep: Add support for registering MHI endpoint client drivers Date: Thu, 2 Dec 2021 17:05:38 +0530 Message-Id: <20211202113553.238011-7-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org This commit adds support for registering MHI endpoint client drivers with the MHI endpoint stack. MHI endpoint client drivers binds 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. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 85 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 53 ++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index db664360c8ab..ce0f99f22058 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -193,9 +193,88 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); +static int mhi_ep_driver_probe(struct device *dev) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); + struct mhi_ep_chan *ul_chan = mhi_dev->ul_chan; + struct mhi_ep_chan *dl_chan = mhi_dev->dl_chan; + + if (ul_chan) + ul_chan->xfer_cb = mhi_drv->ul_xfer_cb; + + if (dl_chan) + dl_chan->xfer_cb = 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 = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + int dir; + + /* Skip if it is a controller device */ + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + return 0; + + /* Disconnect the channels associated with the driver */ + for (dir = 0; dir < 2; dir++) { + mhi_chan = 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 = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + mhi_chan->xfer_cb = 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 = &mhi_drv->driver; + + if (!mhi_drv->probe || !mhi_drv->remove) + return -EINVAL; + + driver->bus = &mhi_ep_bus_type; + driver->owner = owner; + driver->probe = mhi_ep_driver_probe; + driver->remove = 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 = to_mhi_ep_device(dev); + struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(drv); + const struct mhi_device_id *id; /* * If the device is a controller type then there is no client driver @@ -204,6 +283,12 @@ static int mhi_ep_match(struct device *dev, struct device_driver *drv) if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) return 0; + for (id = mhi_drv->id_table; id->chan[0]; id++) + if (!strcmp(mhi_dev->name, id->chan)) { + mhi_dev->id = id; + return 1; + } + return 0; }; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 14fd40af8974..bc72c197db4d 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -119,7 +119,60 @@ struct mhi_ep_device { int dl_chan_id; }; +/** + * struct mhi_ep_driver - Structure representing a MHI Endpoint client driver + * @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 data transfer + * @dl_xfer_cb: CB function for DL 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, driver) + +/* + * 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 otherwise. + */ +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); /** * mhi_ep_register_controller - Register MHI Endpoint controller From patchwork Thu Dec 2 11:35:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519856 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 B16ABC433F5 for ; Thu, 2 Dec 2021 11:38:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357545AbhLBLlZ (ORCPT ); Thu, 2 Dec 2021 06:41:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357479AbhLBLlA (ORCPT ); Thu, 2 Dec 2021 06:41:00 -0500 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF3B6C0613D7 for ; Thu, 2 Dec 2021 03:37:32 -0800 (PST) Received: by mail-pf1-x435.google.com with SMTP id g19so27623652pfb.8 for ; Thu, 02 Dec 2021 03:37:32 -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=H21OUa75Sn+QpTK/F/M/qnvZo747X4niCGMgpEDxUDA=; b=EYcUHStjptlCVAMQRk7zAyogtzw9/aY5nIzVE/9STvT/c0OHxdGd9NqmJsmaJmQxp2 8VfyJV+p9Kx8dgezp4NKEDmj23l3dSBdFIhmZsCHxgk28+7awbLl07JmCjMxmb7y5hA6 7deFF03dgQXs58d+irRTaGsp9/N6eKKw/jC1lV7jZ+DWgC2dgUsBGz0UrDr1y/mewF2G dxBAJj13rjjvNolhFOO7WZw60/4wJl5L4Ho9hkQ/j4K8ptmfSE9ah9Kw/UugAn7cqbHt f0Ct+st9Y9XOanCKQ8TEAU89986S6nvQvTdcxV4TQPkwJja1L6Wj+ZqoQ/m0O52Io7xq p13g== 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=H21OUa75Sn+QpTK/F/M/qnvZo747X4niCGMgpEDxUDA=; b=VOqAfFFL7BrffxQ93VMYQcPB4/fleEzKIawc/CW2TEjJADPpTW76Azg5/HWqAeJSCl XcVA8bTyPxfv8Xaxsw1VOUu5GwMg+j0Kdzo2BThOYeQmpUeooaF/vuBnFv02CoyvbOAu +yWdOABKviEVJOv27GexjwHMiJ7NvMOLTHjtsS1C53OPVpy/8hVjSynPIbSWFlmcBy8X 6KgtJruu6FBG873OQR0RNFekfUU6SZ0yF34Z8dSCuWsHQssTAshglWXcHqgthrUNK5ia BskyLkg0R5F/8AICvs5np6ue+mfWEgA3fK2/91ESmYHalRvX+5o7IwZxKUNR4egE5HRP eqUQ== X-Gm-Message-State: AOAM533miXSrmhCgyspBBsTmh0zp7RvU3ABnOlXNj5+W6q7My8/iNrvV 6sqW+pAvD5rNuYEcr4oSkat1 X-Google-Smtp-Source: ABdhPJwGDMNqxXATDFp2XhvgapmPmdtDl8bTVvg0ZhYSw/2f5rApkNt327ZLFq1/aN/vZohG9h008A== X-Received: by 2002:a05:6a00:b49:b0:49f:c8e0:51ff with SMTP id p9-20020a056a000b4900b0049fc8e051ffmr11735336pfo.36.1638445052403; Thu, 02 Dec 2021 03:37:32 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:31 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 07/20] bus: mhi: ep: Add support for creating and destroying MHI EP devices Date: Thu, 2 Dec 2021 17:05:39 +0530 Message-Id: <20211202113553.238011-8-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/main.c | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index ce0f99f22058..f0b5f49db95a 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -63,6 +63,91 @@ static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl) return mhi_dev; } +static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) +{ + struct mhi_ep_device *mhi_dev; + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ch_id]; + int ret; + + mhi_dev = mhi_ep_alloc_device(mhi_cntrl); + if (IS_ERR(mhi_dev)) + return PTR_ERR(mhi_dev); + + mhi_dev->dev_type = MHI_DEVICE_XFER; + + /* Configure primary channel */ + if (mhi_chan->dir == DMA_TO_DEVICE) { + mhi_dev->ul_chan = mhi_chan; + mhi_dev->ul_chan_id = mhi_chan->chan; + } else { + mhi_dev->dl_chan = mhi_chan; + mhi_dev->dl_chan_id = mhi_chan->chan; + } + + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev = mhi_dev; + + /* Configure secondary channel as well */ + mhi_chan++; + if (mhi_chan->dir == DMA_TO_DEVICE) { + mhi_dev->ul_chan = mhi_chan; + mhi_dev->ul_chan_id = mhi_chan->chan; + } else { + mhi_dev->dl_chan = mhi_chan; + mhi_dev->dl_chan_id = mhi_chan->chan; + } + + get_device(&mhi_dev->dev); + mhi_chan->mhi_dev = mhi_dev; + + /* Channel name is same for both UL and DL */ + mhi_dev->name = mhi_chan->name; + dev_set_name(&mhi_dev->dev, "%s_%s", + dev_name(&mhi_cntrl->mhi_dev->dev), + mhi_dev->name); + + ret = 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 != &mhi_ep_bus_type) + return 0; + + mhi_dev = to_mhi_ep_device(dev); + mhi_cntrl = mhi_dev->mhi_cntrl; + + /* Only destroy devices created for channels */ + if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) + return 0; + + ul_chan = mhi_dev->ul_chan; + dl_chan = 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 parse_ch_cfg(struct mhi_ep_cntrl *mhi_cntrl, const struct mhi_ep_cntrl_config *config) { From patchwork Thu Dec 2 11:35:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520276 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 33711C433F5 for ; Thu, 2 Dec 2021 11:38:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357477AbhLBLld (ORCPT ); Thu, 2 Dec 2021 06:41:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357417AbhLBLlB (ORCPT ); Thu, 2 Dec 2021 06:41:01 -0500 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A23BC0613E1 for ; Thu, 2 Dec 2021 03:37:37 -0800 (PST) Received: by mail-pf1-x432.google.com with SMTP id i12so27635322pfd.6 for ; Thu, 02 Dec 2021 03:37:37 -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=qmVcQr8PkVfv5VkFQ4HeP0jQQtjizWL5fbLHamvuirE=; b=YfWfnn9BEwD41/FWXEqxruKy5rneBA+0EljL4NfA0K7oMqAfjQpRQB5CKxjsA5K9Qd A6RQtm69ZgVHL8rX0fkTo0jYV4HOuT7Gl+B7KSlXXF8PEXBtnbvU+GX9FAueo4iGUMSo K/IyIF3tIBJ8Vl8UjyVXODff9OZl27B2dtk9bm8fr09nJygPIpqYcyeyQh1dKsAyUkMd WtsJ9pHz6p27BdFN5Gnhj/FTUexdwiQYd7+1ALBf4R4BkMb2muwhY7GhxJ9kqb8tYbMc kfkxlUftsx35ndWPBZgiIbM8ybsyrv/sMsPHs8/Y5PsDBkj6vupV+i4QCutjvBTnbF6i 95bw== 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=qmVcQr8PkVfv5VkFQ4HeP0jQQtjizWL5fbLHamvuirE=; b=Vlfxadb9zji4XsfbGy4wC4tJJRkShIk0F24Mcfs5hAp8tVbC59/mn/jEYNsdjHO5Pv usvGw2B7kPFCE64uuEeTQi0ph5zfn7hROIXaPzygCLRNY08ZbDun3YcBAzrmMSGRAIfy WxXUr4gVfuaEiERzx5/3fr0XCIKH1A0TauMrzfyocYVdrg+cHdXwvWUfIvEpZpFfOrA5 R3dqY1YZzvsROATQXgdcoaelmZTn32ZcbbYnTvvOnA2PnyT4v3p0f7oUPZWrJEEcaX+p 0GrAxbV5WhfFHChx2FH0V627ja3b/6mCG1KCxm2FXBeLgKKpzpKbyRhs/ruMVWkmK6Pr EnHg== X-Gm-Message-State: AOAM532UsKVuGlr31Y43XPzlwNFHxCS7LhF4tfo43yhtRYUTGq8pZaE9 k2LOqNmcZVNJTP53/1cO2SrS X-Google-Smtp-Source: ABdhPJxWmOaqaIgx6PFn9wgRHOcBz5K+ue0Nt5LkPqimvo55LmVhS9z2IASXcwPqxc1EmTOhtE7tgg== X-Received: by 2002:a63:b006:: with SMTP id h6mr9090487pgf.192.1638445057001; Thu, 02 Dec 2021 03:37:37 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:36 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 08/20] bus: mhi: ep: Add support for managing MMIO registers Date: Thu, 2 Dec 2021 17:05:40 +0530 Message-Id: <20211202113553.238011-9-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 36 ++++ drivers/bus/mhi/ep/main.c | 6 +- drivers/bus/mhi/ep/mmio.c | 303 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 18 ++ 5 files changed, 363 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) += mhi_ep.o -mhi_ep-y := main.o +mhi_ep-y := main.o mmio.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 7b164daf4332..39eeb5f384e2 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -91,6 +91,12 @@ struct mhi_generic_ctx { __u64 wp __packed __aligned(4); }; +enum mhi_ep_execenv { + MHI_EP_SBL_EE = 1, + MHI_EP_AMSS_EE = 2, + MHI_EP_UNRESERVED +}; + enum mhi_ep_ring_state { RING_STATE_UINT = 0, RING_STATE_IDLE, @@ -155,4 +161,34 @@ struct mhi_ep_chan { bool skip_td; }; +/* MMIO related functions */ +void mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 *regval); +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 shift, u32 val); +int mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, + u32 mask, u32 shift, u32 *regval); +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_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id); +void mhi_ep_mmio_disable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id); +void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +void mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl); +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); +void mhi_ep_mmio_get_ch_db(struct mhi_ep_ring *ring, u64 *wr_offset); +void mhi_ep_mmio_get_er_db(struct mhi_ep_ring *ring, u64 *wr_offset); +void mhi_ep_mmio_get_cmd_db(struct mhi_ep_ring *ring, u64 *wr_offset); +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_state *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 f0b5f49db95a..fddf75dfb9c7 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -209,7 +209,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_device *mhi_dev; int ret; - if (!mhi_cntrl || !mhi_cntrl->cntrl_dev) + if (!mhi_cntrl || !mhi_cntrl->cntrl_dev || !mhi_cntrl->mmio) return -EINVAL; ret = parse_ch_cfg(mhi_cntrl, config); @@ -222,6 +222,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_ch; } + /* Set MHI version and AMSS EE before enumeration */ + mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + /* Set controller index */ mhi_cntrl->index = 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..157ef1240f6f --- /dev/null +++ b/drivers/bus/mhi/ep/mmio.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include +#include + +#include "internal.h" + +void mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 *regval) +{ + *regval = 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 shift, u32 val) +{ + u32 regval; + + mhi_ep_mmio_read(mhi_cntrl, offset, ®val); + regval &= ~mask; + regval |= ((val << shift) & mask); + mhi_ep_mmio_write(mhi_cntrl, offset, regval); +} + +int mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, + u32 mask, u32 shift, u32 *regval) +{ + mhi_ep_mmio_read(dev, offset, regval); + *regval &= mask; + *regval >>= shift; + + return 0; +} + +void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state, + bool *mhi_reset) +{ + u32 regval; + + mhi_ep_mmio_read(mhi_cntrl, MHICTRL, ®val); + *state = FIELD_GET(MHICTRL_MHISTATE_MASK, regval); + *mhi_reset = !!FIELD_GET(MHICTRL_RESET_MASK, regval); +} + +static void mhi_ep_mmio_mask_set_chdb_int_a7(struct mhi_ep_cntrl *mhi_cntrl, + u32 chdb_id, bool enable) +{ + u32 chid_mask, chid_idx, chid_shft, val = 0; + + chid_shft = chdb_id % 32; + chid_mask = BIT(chid_shft); + chid_idx = chdb_id / 32; + + if (chid_idx >= MHI_MASK_ROWS_CH_EV_DB) + return; + + if (enable) + val = 1; + + mhi_ep_mmio_masked_write(mhi_cntrl, MHI_CHDB_INT_MASK_A7_n(chid_idx), + chid_mask, chid_shft, val); + mhi_ep_mmio_read(mhi_cntrl, MHI_CHDB_INT_MASK_A7_n(chid_idx), + &mhi_cntrl->chdb[chid_idx].mask); +} + +void mhi_ep_mmio_enable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id) +{ + mhi_ep_mmio_mask_set_chdb_int_a7(mhi_cntrl, chdb_id, true); +} + +void mhi_ep_mmio_disable_chdb_a7(struct mhi_ep_cntrl *mhi_cntrl, u32 chdb_id) +{ + mhi_ep_mmio_mask_set_chdb_int_a7(mhi_cntrl, chdb_id, false); +} + +static void mhi_ep_mmio_set_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl, bool enable) +{ + u32 val = 0, i = 0; + + if (enable) + val = MHI_CHDB_INT_MASK_A7_n_EN_ALL; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_MASK_A7_n(i), val); + mhi_cntrl->chdb[i].mask = 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_cntrl) +{ + mhi_ep_mmio_set_chdb_interrupts(mhi_cntrl, false); +} + +void mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 i; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_read(mhi_cntrl, MHI_CHDB_INT_STATUS_A7_n(i), + &mhi_cntrl->chdb[i].status); +} + +static void mhi_ep_mmio_set_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl, bool enable) +{ + u32 val = 0, i; + + if (enable) + val = MHI_ERDB_INT_MASK_A7_n_EN_ALL; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_MASK_A7_n(i), val); +} + +static void mhi_ep_mmio_mask_erdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl) +{ + 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_A7, + MHI_CTRL_MHICTRL_MASK, + MHI_CTRL_MHICTRL_SHFT, 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_A7, + MHI_CTRL_MHICTRL_MASK, + MHI_CTRL_MHICTRL_SHFT, 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_A7, + MHI_CTRL_CRDB_MASK, + MHI_CTRL_CRDB_SHFT, 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_A7, + MHI_CTRL_CRDB_MASK, + MHI_CTRL_CRDB_SHFT, 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 = 0; + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_A7_n(i), + MHI_CHDB_INT_CLEAR_A7_n_CLEAR_ALL); + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) + mhi_ep_mmio_write(mhi_cntrl, MHI_ERDB_INT_CLEAR_A7_n(i), + MHI_ERDB_INT_CLEAR_A7_n_CLEAR_ALL); + + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR_A7, + 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 ccabap_value = 0; + + mhi_ep_mmio_read(mhi_cntrl, CCABAP_HIGHER, &ccabap_value); + mhi_cntrl->ch_ctx_host_pa = ccabap_value; + mhi_cntrl->ch_ctx_host_pa <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, CCABAP_LOWER, &ccabap_value); + mhi_cntrl->ch_ctx_host_pa |= ccabap_value; +} + +void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 ecabap_value = 0; + + mhi_ep_mmio_read(mhi_cntrl, ECABAP_HIGHER, &ecabap_value); + mhi_cntrl->ev_ctx_host_pa = ecabap_value; + mhi_cntrl->ev_ctx_host_pa <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, ECABAP_LOWER, &ecabap_value); + mhi_cntrl->ev_ctx_host_pa |= ecabap_value; +} + +void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl) +{ + u32 crcbap_value = 0; + + mhi_ep_mmio_read(mhi_cntrl, CRCBAP_HIGHER, &crcbap_value); + mhi_cntrl->cmd_ctx_host_pa = crcbap_value; + mhi_cntrl->cmd_ctx_host_pa <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, CRCBAP_LOWER, &crcbap_value); + mhi_cntrl->cmd_ctx_host_pa |= crcbap_value; +} + +void mhi_ep_mmio_get_ch_db(struct mhi_ep_ring *ring, u64 *wr_ptr) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + u32 value = 0; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_h, &value); + *wr_ptr = value; + *wr_ptr <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_l, &value); + + *wr_ptr |= value; +} + +void mhi_ep_mmio_get_er_db(struct mhi_ep_ring *ring, u64 *wr_ptr) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + u32 value = 0; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_h, &value); + *wr_ptr = value; + *wr_ptr <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_l, &value); + + *wr_ptr |= value; +} + +void mhi_ep_mmio_get_cmd_db(struct mhi_ep_ring *ring, u64 *wr_ptr) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + u32 value = 0; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_h, &value); + *wr_ptr = value; + *wr_ptr <<= 32; + + mhi_ep_mmio_read(mhi_cntrl, ring->db_offset_l, &value); + *wr_ptr |= value; +} + +void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value) +{ + mhi_ep_mmio_write(mhi_cntrl, BHI_EXECENV, value); +} + +void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_masked_write(mhi_cntrl, MHICTRL, MHICTRL_RESET_MASK, + MHICTRL_RESET_SHIFT, 0); +} + +void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_write(mhi_cntrl, MHICTRL, 0); + mhi_ep_mmio_write(mhi_cntrl, MHISTATUS, 0); + mhi_ep_mmio_clear_interrupts(mhi_cntrl); +} + +void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl) +{ + int mhi_cfg = 0; + + mhi_ep_mmio_read(mhi_cntrl, CHDBOFF, &mhi_cntrl->chdb_offset); + mhi_ep_mmio_read(mhi_cntrl, ERDBOFF, &mhi_cntrl->erdb_offset); + + mhi_ep_mmio_read(mhi_cntrl, MHICFG, &mhi_cfg); + mhi_cntrl->event_rings = FIELD_GET(MHICFG_NER_MASK, mhi_cfg); + mhi_cntrl->hw_event_rings = FIELD_GET(MHICFG_NHWER_MASK, mhi_cfg); + + mhi_ep_mmio_reset(mhi_cntrl); +} + +void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl) +{ + int mhi_cfg = 0; + + mhi_ep_mmio_read(mhi_cntrl, MHICFG, &mhi_cfg); + mhi_cntrl->event_rings = FIELD_GET(MHICFG_NER_MASK, mhi_cfg); + mhi_cntrl->hw_event_rings = FIELD_GET(MHICFG_NHWER_MASK, mhi_cfg); +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index bc72c197db4d..902c8febd856 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 structure + * @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 @@ -66,6 +70,10 @@ struct mhi_ep_db_info { * @unmap_addr: CB function to unmap the host context in endpoint * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by 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 endpoint 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 { @@ -78,6 +86,12 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; + 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); void __iomem *(*alloc_addr)(struct mhi_ep_cntrl *mhi_cntrl, phys_addr_t *phys_addr, size_t size); @@ -91,6 +105,10 @@ struct mhi_ep_cntrl { enum mhi_state mhi_state; u32 max_chan; + u32 event_rings; + u32 hw_event_rings; + u32 chdb_offset; + u32 erdb_offset; int index; }; From patchwork Thu Dec 2 11:35:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520275 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 73ACFC433FE for ; Thu, 2 Dec 2021 11:38:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357467AbhLBLlm (ORCPT ); Thu, 2 Dec 2021 06:41:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357532AbhLBLlY (ORCPT ); Thu, 2 Dec 2021 06:41:24 -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 81288C0613F1 for ; Thu, 2 Dec 2021 03:37:42 -0800 (PST) Received: by mail-pj1-x1029.google.com with SMTP id n15-20020a17090a160f00b001a75089daa3so2216210pja.1 for ; Thu, 02 Dec 2021 03:37:42 -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=UENFBa0oIATirSmaEsUpUKVLwIwkCskxaXXfm167osA=; b=EB6dyHpCb/1LAHOK2w2UoXAf0q1ma4ACbErIX18mqix81xmzIJ9Fa/iMz3/p24HwYL 1IdinTgR9HFle0Pdz0zJtVY49IeNXAWGljzH6CAni3tQMNyMe4E1QGt1TOHbaj4BaOOF GpTZi26z7BPxc6VTejP8WecMXik4Ks9f33BkoxD4mxIO2ovfduerXbPQ0Og5plM3I8Px LzRx+jr2cUScaPep7aM1aG0opdiNAuPrM5wK41A8H3zsSwJmbRQzX3vCH1kedjVYbtk0 xZ7XAmPYNVrgMPoHigSLRy6rsyOoSi43CGvNjQjAyK3wbRyoqF3cQRuTMkNgXNRYIMdY D76g== 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=UENFBa0oIATirSmaEsUpUKVLwIwkCskxaXXfm167osA=; b=YigKYKaD0ijS24wdzkVTsGWihObfFaWIkBaABVNG+nqk/43/dmLZNH1U3nDFFLnN1l a/axgPfwpfSMgLTAbtwiBV/XmZl5/g3pYg93ns6G4Qhrp0tUlJQ4ttcL4CmV2NfBNNlZ r7gMHUTuqXmqOGNON/fHgPT6wkBOGuDvvXzcntjjzf4dFcmYJErWZW8fqX1ZOTnQrLGB +w3kVzJDv2ZjPYQfIrNz49Z3axee1CTgtny6WkGIiXdMvSg0eCRU+6zkkNHr9ljYv9TJ 41vdVhx+G82YzArikAZU+9xG68+zfNpxMQW9Uxmb7JuBoS0YY2o74xNAN9gW9wN3MOrL gSrw== X-Gm-Message-State: AOAM530YAKd/5YN+cFoZVkVkHmdM86wDNuDhK0JHHIEpCOo62R3jVt80 9JyP98gYQWLJEr0i3gqq+rUB X-Google-Smtp-Source: ABdhPJxSLWSF/CErNnJGBpM68C75FG1aAUryuaA/9zuUFBxPopHst54qAOQZ43AiE9Knpw0pQeJEZg== X-Received: by 2002:a17:903:30cd:b0:141:c6dd:4d03 with SMTP id s13-20020a17090330cd00b00141c6dd4d03mr14890321plc.16.1638445061865; Thu, 02 Dec 2021 03:37:41 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:41 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 09/20] bus: mhi: ep: Add support for ring management Date: Thu, 2 Dec 2021 17:05:41 +0530 Message-Id: <20211202113553.238011-10-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 23 +++ drivers/bus/mhi/ep/main.c | 53 +++++- drivers/bus/mhi/ep/ring.c | 314 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 11 ++ 5 files changed, 401 insertions(+), 2 deletions(-) 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) += mhi_ep.o -mhi_ep-y := main.o mmio.o +mhi_ep-y := main.o mmio.o ring.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 39eeb5f384e2..a7a4e6934f7d 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -97,6 +97,18 @@ enum mhi_ep_execenv { MHI_EP_UNRESERVED }; +/* Transfer Ring Element macros */ +#define MHI_EP_TRE_PTR(ptr) (ptr) +#define MHI_EP_TRE_DWORD0(len) (len & MHI_MAX_MTU) +#define MHI_EP_TRE_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 10) \ + | (ieot << 9) | (ieob << 8) | chain) +#define MHI_EP_TRE_GET_PTR(tre) ((tre)->ptr) +#define MHI_EP_TRE_GET_LEN(tre) ((tre)->dword[0] & 0xffff) +#define MHI_EP_TRE_GET_CHAIN(tre) FIELD_GET(BIT(0), (tre)->dword[1]) +#define MHI_EP_TRE_GET_IEOB(tre) FIELD_GET(BIT(8), (tre)->dword[1]) +#define MHI_EP_TRE_GET_IEOT(tre) FIELD_GET(BIT(9), (tre)->dword[1]) +#define MHI_EP_TRE_GET_BEI(tre) FIELD_GET(BIT(10), (tre)->dword[1]) + enum mhi_ep_ring_state { RING_STATE_UINT = 0, RING_STATE_IDLE, @@ -161,6 +173,17 @@ struct mhi_ep_chan { bool skip_td; }; +/* 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_stop(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring); +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr); +int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, + union mhi_ep_ring_ctx *ctx); +int mhi_ep_process_ring(struct mhi_ep_ring *ring); +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *element, + int evt_offset); +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring); + /* MMIO related functions */ void mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 *regval); void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val); diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index fddf75dfb9c7..6d448d42f527 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -18,6 +18,42 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static void mhi_ep_ring_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, + struct mhi_ep_cntrl, ring_work); + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring *ring; + struct list_head *cp, *q; + unsigned long flags; + int ret = 0; + + /* Process the command ring first */ + ret = mhi_ep_process_ring(&mhi_cntrl->mhi_cmd->ring); + if (ret) { + dev_err(dev, "Error processing command ring\n"); + goto err_unlock; + } + + spin_lock_irqsave(&mhi_cntrl->list_lock, flags); + /* Process the channel rings now */ + list_for_each_safe(cp, q, &mhi_cntrl->ch_db_list) { + ring = list_entry(cp, struct mhi_ep_ring, list); + list_del(cp); + ret = mhi_ep_process_ring(ring); + if (ret) { + dev_err(dev, "Error processing channel ring: %d\n", ring->ch_id); + goto err_unlock; + } + + /* Re-enable channel interrupt */ + mhi_ep_mmio_enable_chdb_a7(mhi_cntrl, ring->ch_id); + } + +err_unlock: + spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -222,6 +258,17 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_ch; } + INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); + + mhi_cntrl->ring_wq = alloc_ordered_workqueue("mhi_ep_ring_wq", WQ_HIGHPRI); + if (!mhi_cntrl->ring_wq) { + ret = -ENOMEM; + goto err_free_cmd; + } + + INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); + spin_lock_init(&mhi_cntrl->list_lock); + /* Set MHI version and AMSS EE before enumeration */ mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); @@ -230,7 +277,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { ret = mhi_cntrl->index; - goto err_free_cmd; + goto err_destroy_ring_wq; } /* Allocate the controller device */ @@ -259,6 +306,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_ring_wq: + destroy_workqueue(mhi_cntrl->ring_wq); err_free_cmd: kfree(mhi_cntrl->mhi_cmd); err_free_ch: @@ -272,6 +321,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; + destroy_workqueue(mhi_cntrl->ring_wq); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c new file mode 100644 index 000000000000..763b8506d309 --- /dev/null +++ b/drivers/bus/mhi/ep/ring.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#include "internal.h" + +size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr) +{ + u64 rbase; + + rbase = ring->ring_ctx->generic.rbase; + + return (ptr - rbase) / sizeof(struct mhi_ep_ring_element); +} + +static u32 mhi_ep_ring_num_elems(struct mhi_ep_ring *ring) +{ + return ring->ring_ctx->generic.rlen / sizeof(struct mhi_ep_ring_element); +} + +void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring) +{ + ring->rd_offset++; + if (ring->rd_offset == ring->ring_size) + ring->rd_offset = 0; +} + +static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + size_t start, copy_size; + struct mhi_ep_ring_element *ring_shadow; + phys_addr_t ring_shadow_phys; + size_t size = ring->ring_size * sizeof(struct mhi_ep_ring_element); + int ret; + + /* No need to cache event rings */ + if (ring->type == RING_TYPE_ER) + return 0; + + /* No need to cache the ring if write pointer is unmodified */ + if (ring->wr_offset == end) + return 0; + + start = ring->wr_offset; + + /* Allocate memory for host ring */ + ring_shadow = mhi_cntrl->alloc_addr(mhi_cntrl, &ring_shadow_phys, + size); + if (!ring_shadow) { + dev_err(dev, "Failed to allocate memory for ring_shadow\n"); + return -ENOMEM; + } + + /* Map host ring */ + ret = mhi_cntrl->map_addr(mhi_cntrl, ring_shadow_phys, + ring->ring_ctx->generic.rbase, size); + if (ret) { + dev_err(dev, "Failed to map ring_shadow\n\n"); + goto err_ring_free; + } + + dev_dbg(dev, "Caching ring: start %d end %d size %d", start, end, copy_size); + + if (start < end) { + copy_size = (end - start) * sizeof(struct mhi_ep_ring_element); + memcpy_fromio(&ring->ring_cache[start], &ring_shadow[start], copy_size); + } else { + copy_size = (ring->ring_size - start) * sizeof(struct mhi_ep_ring_element); + memcpy_fromio(&ring->ring_cache[start], &ring_shadow[start], copy_size); + if (end) + memcpy_fromio(&ring->ring_cache[0], &ring_shadow[0], + end * sizeof(struct mhi_ep_ring_element)); + } + + /* Now unmap and free host ring */ + mhi_cntrl->unmap_addr(mhi_cntrl, ring_shadow_phys); + mhi_cntrl->free_addr(mhi_cntrl, ring_shadow_phys, ring_shadow, size); + + return 0; + +err_ring_free: + mhi_cntrl->free_addr(mhi_cntrl, ring_shadow_phys, &ring_shadow, size); + + return ret; +} + +static int mhi_ep_cache_ring(struct mhi_ep_ring *ring, u64 wr_ptr) +{ + size_t wr_offset; + int ret; + + wr_offset = mhi_ep_ring_addr2offset(ring, wr_ptr); + + /* Cache the host ring till write offset */ + ret = __mhi_ep_cache_ring(ring, wr_offset); + if (ret) + return ret; + + ring->wr_offset = wr_offset; + + return 0; +} + +static int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring) +{ + u64 wr_ptr; + + switch (ring->type) { + case RING_TYPE_CMD: + mhi_ep_mmio_get_cmd_db(ring, &wr_ptr); + break; + case RING_TYPE_ER: + mhi_ep_mmio_get_er_db(ring, &wr_ptr); + break; + case RING_TYPE_CH: + mhi_ep_mmio_get_ch_db(ring, &wr_ptr); + break; + default: + return -EINVAL; + } + + return mhi_ep_cache_ring(ring, wr_ptr); +} + +static int mhi_ep_process_ring_element(struct mhi_ep_ring *ring, size_t offset) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_element *el; + int ret = -ENODEV; + + /* Get the element and invoke the respective callback */ + el = &ring->ring_cache[offset]; + + if (ring->ring_cb) + ret = ring->ring_cb(ring, el); + else + dev_err(dev, "No callback registered for ring\n"); + + return ret; +} + +int mhi_ep_process_ring(struct mhi_ep_ring *ring) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret = 0; + + /* Event rings should not be processed */ + if (ring->type == RING_TYPE_ER) + return -EINVAL; + + dev_dbg(dev, "Processing ring of type: %d\n", ring->type); + + /* Update the write offset for the ring */ + ret = mhi_ep_update_wr_offset(ring); + if (ret) { + dev_err(dev, "Error updating write offset for ring\n"); + return ret; + } + + /* Sanity check to make sure there are elements in the ring */ + if (ring->rd_offset == ring->wr_offset) + return 0; + + /* Process channel ring first */ + if (ring->type == RING_TYPE_CH) { + ret = mhi_ep_process_ring_element(ring, ring->rd_offset); + if (ret) + dev_err(dev, "Error processing ch ring element: %d\n", ring->rd_offset); + + return ret; + } + + /* Process command ring now */ + while (ring->rd_offset != ring->wr_offset) { + ret = mhi_ep_process_ring_element(ring, ring->rd_offset); + if (ret) { + dev_err(dev, "Error processing cmd ring element: %d\n", ring->rd_offset); + return ret; + } + + mhi_ep_ring_inc_index(ring); + } + + return 0; +} + +/* TODO: Support for adding multiple ring elements to the ring */ +int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el, int size) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_element *ring_shadow; + size_t ring_size = ring->ring_size * sizeof(struct mhi_ep_ring_element); + phys_addr_t ring_shadow_phys; + size_t old_offset = 0; + u32 num_free_elem; + int ret; + + ret = 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 = (ring->wr_offset - ring->rd_offset) - 1; + else + num_free_elem = ((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 < 1) { + dev_err(dev, "No space left in the ring\n"); + return -ENOSPC; + } + + old_offset = ring->rd_offset; + mhi_ep_ring_inc_index(ring); + + dev_dbg(dev, "Adding an element to ring at offset (%d)\n", ring->rd_offset); + + /* Update rp in ring context */ + ring->ring_ctx->generic.rp = (ring->rd_offset * sizeof(struct mhi_ep_ring_element)) + + ring->ring_ctx->generic.rbase; + + /* Allocate memory for host ring */ + ring_shadow = mhi_cntrl->alloc_addr(mhi_cntrl, &ring_shadow_phys, ring_size); + if (!ring_shadow) { + dev_err(dev, "failed to allocate ring_shadow\n"); + return -ENOMEM; + } + + /* Map host ring */ + ret = mhi_cntrl->map_addr(mhi_cntrl, ring_shadow_phys, + ring->ring_ctx->generic.rbase, ring_size); + if (ret) { + dev_err(dev, "failed to map ring_shadow\n\n"); + goto err_ring_free; + } + + /* Copy the element to ring */ + memcpy_toio(&ring_shadow[old_offset], el, sizeof(struct mhi_ep_ring_element)); + + /* Now unmap and free host ring */ + mhi_cntrl->unmap_addr(mhi_cntrl, ring_shadow_phys); + mhi_cntrl->free_addr(mhi_cntrl, ring_shadow_phys, ring_shadow, ring_size); + + return 0; + +err_ring_free: + mhi_cntrl->free_addr(mhi_cntrl, ring_shadow_phys, ring_shadow, ring_size); + + return ret; +} + +void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id) +{ + ring->state = RING_STATE_UINT; + ring->type = type; + if (ring->type == RING_TYPE_CMD) { + ring->db_offset_h = CRDB_HIGHER; + ring->db_offset_l = CRDB_LOWER; + } else if (ring->type == RING_TYPE_CH) { + ring->db_offset_h = CHDB_HIGHER_n(id); + ring->db_offset_l = CHDB_LOWER_n(id); + ring->ch_id = id; + } else if (ring->type == RING_TYPE_ER) { + ring->db_offset_h = ERDB_HIGHER_n(id); + ring->db_offset_l = 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 = &mhi_cntrl->mhi_dev->dev; + int ret; + + ring->mhi_cntrl = mhi_cntrl; + ring->ring_ctx = ctx; + ring->ring_size = mhi_ep_ring_num_elems(ring); + + /* During ring init, both rp and wp are equal */ + ring->rd_offset = mhi_ep_ring_addr2offset(ring, ring->ring_ctx->generic.rp); + ring->wr_offset = mhi_ep_ring_addr2offset(ring, ring->ring_ctx->generic.rp); + ring->state = RING_STATE_IDLE; + + /* Allocate ring cache memory for holding the copy of host ring */ + ring->ring_cache = kcalloc(ring->ring_size, sizeof(struct mhi_ep_ring_element), + GFP_KERNEL); + if (!ring->ring_cache) + return -ENOMEM; + + ret = mhi_ep_cache_ring(ring, ring->ring_ctx->generic.wp); + if (ret) { + dev_err(dev, "Failed to cache ring\n"); + kfree(ring->ring_cache); + return ret; + } + + return 0; +} + +void mhi_ep_ring_stop(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring) +{ + ring->state = RING_STATE_UINT; + kfree(ring->ring_cache); +} diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 902c8febd856..729f4b802b74 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -62,6 +62,11 @@ 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 structure + * @ring_wq: Dedicated workqueue for processing MHI rings + * @ring_work: Ring worker + * @ch_db_list: List of queued channel doorbells + * @st_transition_list: List of state transitions + * @list_lock: Lock for protecting state transition and channel doorbell lists * @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 @@ -90,6 +95,12 @@ struct mhi_ep_cntrl { u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + struct workqueue_struct *ring_wq; + struct work_struct ring_work; + + struct list_head ch_db_list; + struct list_head st_transition_list; + spinlock_t list_lock; struct mhi_ep_db_info chdb[4]; void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl); From patchwork Thu Dec 2 11:35:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519855 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 1D5A9C433F5 for ; Thu, 2 Dec 2021 11:38:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346359AbhLBLll (ORCPT ); Thu, 2 Dec 2021 06:41:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357535AbhLBLlY (ORCPT ); Thu, 2 Dec 2021 06:41:24 -0500 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7C489C06175D for ; Thu, 2 Dec 2021 03:37:47 -0800 (PST) Received: by mail-pf1-x432.google.com with SMTP id r130so27707155pfc.1 for ; Thu, 02 Dec 2021 03:37: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=8f7zzXKVcLX/dqa48zIkMnAKOzRJcJHZ6VvK4PzmNdM=; b=cYZHNmuiNkDaLaDpepX+4T5ZGpmGqI9b+2oJh5CvRFOYdUff6keezBOmYE88HDGmEc IpykMpEUoMDlayxW0Uh/PX4xDVtVbULgaw0TDQToYbfz3XGgHy/pTZOYevTjeTjidZzh D4SNZd6Qf68MS/qp0fx6OCvdH80cigAbmPRzWR+54kYK/ahg7UpML1hJO5oLgNdAToIa NKgCtUqAncjjy8YEEGLLFionHv78WSFrTb/dkEntVlxFyrXZOIRVluzohrjmZgnFQV+u G1e2lMnHLbX3yxVx0KiyangryHe/PcljeGwKdlDs2DuKSHn1Why6qAEbOd6a5HauwkhV +WDA== 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=8f7zzXKVcLX/dqa48zIkMnAKOzRJcJHZ6VvK4PzmNdM=; b=8DWfy0y/vtc5AUbt2VfCZL5hgrXLJpvTh1RbDnfx22yItEvOVnj3Z/1yqwYsdIrDx+ OeNnCAKlxBZrVX/cnJvBtgqS+dkr4ofTfxMRPwgQxVqmlRDne9Rf8ncLCKMrpTJHsQ1R 6/IGxyrAVps9ThsITnrbhbBoyDK6RrBiBoJF5IjDwHvXjAWOHMowmtKViCjW+Kagbmqg WWifBGOiytyL9AjBpB5fnv4MUPZbTC3dW6GPj/5529o5l+iqsoWiOLjeqp+PO2XesMAC y0QugsTDQjkwjXXncjXfv819s3JqJIoymruyF5xH43hI4R4QVA2s52NpzMtxmRJj9eY9 KioA== X-Gm-Message-State: AOAM532KbHj2/0c574HFhBT+4ePaz5cgLCg3w+uMyoFopl/WVBT6HlS6 OalSHH6E9q5DfiScXxPCBPCo X-Google-Smtp-Source: ABdhPJz59UVu2atFTvt4iRGhhE5UhVfFfc/L/4EQIIAWRhG95naOeowbEWy/PE8mxPePKoE6Kugmvg== X-Received: by 2002:aa7:9d9e:0:b0:4a0:25d0:a06f with SMTP id f30-20020aa79d9e000000b004a025d0a06fmr12272302pfq.82.1638445066983; Thu, 02 Dec 2021 03:37:46 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:46 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 10/20] bus: mhi: ep: Add support for sending events to the host Date: Thu, 2 Dec 2021 17:05:42 +0530 Message-Id: <20211202113553.238011-11-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/internal.h | 4 ++ drivers/bus/mhi/ep/main.c | 126 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 2 + 3 files changed, 132 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index a7a4e6934f7d..3551e673d99a 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -214,4 +214,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); +/* MHI EP core functions */ +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state); +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env); + #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 6d448d42f527..999784eadb65 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -18,6 +18,131 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 event_ring, + struct mhi_ep_ring_element *el) +{ + struct mhi_ep_ring *ring = &mhi_cntrl->mhi_event[event_ring].ring; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + union mhi_ep_ring_ctx *ctx; + int ret; + + mutex_lock(&mhi_cntrl->event_lock); + ctx = (union mhi_ep_ring_ctx *)&mhi_cntrl->ev_ctx_cache[event_ring]; + if (ring->state == RING_STATE_UINT) { + ret = mhi_ep_ring_start(mhi_cntrl, ring, ctx); + if (ret) { + dev_err(dev, "Error starting event ring (%d)\n", event_ring); + goto err_unlock; + } + } + + /* Add element to the primary event ring (0) */ + ret = mhi_ep_ring_add_element(ring, el, 0); + if (ret) { + dev_err(dev, "Error adding element to event ring (%d)\n", event_ring); + goto err_unlock; + } + + /* Ensure that the ring pointer gets updated in host memory before triggering IRQ */ + wmb(); + + 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 (!MHI_EP_TRE_GET_BEI(el)) + mhi_cntrl->raise_irq(mhi_cntrl); + + 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, + struct mhi_ep_ring *ring, u32 len, + enum mhi_ev_ccs code) +{ + struct mhi_ep_ring_element event = {}; + u32 er_index, tmp; + + er_index = mhi_cntrl->ch_ctx_cache[ring->ch_id].erindex; + event.ptr = ring->ring_ctx->generic.rbase + + ring->rd_offset * sizeof(struct mhi_ep_ring_element); + + tmp = event.dword[0]; + tmp |= MHI_TRE_EV_DWORD0(code, len); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, er_index, &event); +} + +int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state) +{ + struct mhi_ep_ring_element event = {}; + u32 tmp; + + tmp = event.dword[0]; + tmp |= MHI_SC_EV_DWORD0(state); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + +int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env) +{ + struct mhi_ep_ring_element event = {}; + u32 tmp; + + tmp = event.dword[0]; + tmp |= MHI_EE_EV_DWORD0(exec_env); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + +static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring_element event = {}; + u32 tmp; + + if (code > MHI_EV_CC_BAD_TRE) { + dev_err(dev, "Invalid command completion code: %d\n", code); + return -EINVAL; + } + + event.ptr = mhi_cntrl->cmd_ctx_cache->rbase + + (mhi_cntrl->mhi_cmd->ring.rd_offset * + (sizeof(struct mhi_ep_ring_element))); + + tmp = event.dword[0]; + tmp |= MHI_CC_EV_DWORD0(code); + event.dword[0] = tmp; + + tmp = event.dword[1]; + tmp |= MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); + event.dword[1] = tmp; + + return mhi_ep_send_event(mhi_cntrl, 0, &event); +} + static void mhi_ep_ring_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, @@ -268,6 +393,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); spin_lock_init(&mhi_cntrl->list_lock); + mutex_init(&mhi_cntrl->event_lock); /* Set MHI version and AMSS EE before enumeration */ mhi_ep_mmio_write(mhi_cntrl, MHIVER, config->mhi_version); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 729f4b802b74..323cd3319b13 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -67,6 +67,7 @@ struct mhi_ep_db_info { * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists + * @event_lock: Lock for protecting event rings * @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 @@ -101,6 +102,7 @@ struct mhi_ep_cntrl { struct list_head ch_db_list; struct list_head st_transition_list; spinlock_t list_lock; + struct mutex event_lock; struct mhi_ep_db_info chdb[4]; void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl); From patchwork Thu Dec 2 11:35:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519854 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 F07EBC4332F for ; Thu, 2 Dec 2021 11:38:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357509AbhLBLln (ORCPT ); Thu, 2 Dec 2021 06:41:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357439AbhLBLlZ (ORCPT ); Thu, 2 Dec 2021 06:41:25 -0500 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74F03C0613FB for ; Thu, 2 Dec 2021 03:37:52 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id u11so20043730plf.3 for ; Thu, 02 Dec 2021 03:37: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=262H3ZpiOHu7SqfUd+7SxsNZEjus1h/j40yrC+fiqwc=; b=mrWbPfBvknNyHFJNrSS2xJPJKeaxvpwNgMDhkkEGQtO/Dqa4ztEGOXSo8J4h+BF7d4 zbE1qpIWxZa1xnGOxbNndRs0vUptUO8JWrH/qgyTxcpkgEFbuAW+qbKPu1I84SU1AVbC YPL5yyAEpII/W2RrHAaCh7xi9SLL1h1HXKaNl9pZ5yABWjCOb9wMpDHAB3KPkfrQpNk9 I5m2eBNbdBHQQRR7EHV18T64jmH1gCax6oJEMhNjl2cHAHUBLPcf76ev/zh871nRMn3i +vc8j6ZTlHnoCe83fpeeMaJQCOD4uob7PHefUB0su9g7/lmAFqAwnJcFHZec+hqELQW5 NMvQ== 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=262H3ZpiOHu7SqfUd+7SxsNZEjus1h/j40yrC+fiqwc=; b=BhFS0gQZDC7b+kji/+Fqomzo831cHOUbGMHs+WF1/OqtsO/LIKbDnt6pHgni9ZTBAK b4mC+IGyewmrIEayxay9+dsnX4R9hrvV3Ys6xVvP/69HMRi/n9oZfQ3e5ILOFSHPBO7I 3Z64oiaVZGdz4ResmTZ7z2xz13JHgMeYv6LuW7gC+hk2cnLRUTXhmSaPBwnCyCjlXROx s16bgM7h8zxy22Qn9FtewE2cC0KVomdVfF62LnFbwBvyQK68C/9BsThiI0/USJjBSm67 BvcqEIBK6tyBNys1dQPS40GZK3fVzfo30XhO1+H31gb/Myt5atszYdZOLOw85aSK4T77 M9OA== X-Gm-Message-State: AOAM532TKrtgrK2hATyR8FEjZeLqmWnooRFEnWRr+/ujYGqlKDRWvQKV ceWU9LZZ+GsYvSzmwX2Tp5oJ X-Google-Smtp-Source: ABdhPJyxaFBkl7Nzc+wALuD9jDJXZOQU9IuR+RtZW2B4Fjga9xIHfs7J/Dgfc/IQK4fBls1rsDvwDQ== X-Received: by 2002:a17:90a:98f:: with SMTP id 15mr5329610pjo.166.1638445071909; Thu, 02 Dec 2021 03:37:51 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:51 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 11/20] bus: mhi: ep: Add support for managing MHI state machine Date: Thu, 2 Dec 2021 17:05:43 +0530 Message-Id: <20211202113553.238011-12-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/Makefile | 2 +- drivers/bus/mhi/ep/internal.h | 11 +++ drivers/bus/mhi/ep/main.c | 49 +++++++++- drivers/bus/mhi/ep/sm.c | 175 ++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 ++ 5 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 drivers/bus/mhi/ep/sm.c diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index 7ba0e04801eb..aad85f180b70 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_MHI_BUS_EP) += mhi_ep.o -mhi_ep-y := main.o mmio.o ring.o +mhi_ep-y := main.o mmio.o ring.o sm.o diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 3551e673d99a..ec508201c5c0 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -158,6 +158,11 @@ struct mhi_ep_event { struct mhi_ep_ring ring; }; +struct mhi_ep_state_transition { + struct list_head node; + enum mhi_state state; +}; + struct mhi_ep_chan { char *name; struct mhi_ep_device *mhi_dev; @@ -217,5 +222,11 @@ void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl); /* MHI EP core functions */ int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state); int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ep_execenv exec_env); +bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state, + enum mhi_state mhi_state); +int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state); +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); #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 999784eadb65..f9b80fccfe70 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -179,6 +179,42 @@ static void mhi_ep_ring_worker(struct work_struct *work) spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); } +static void mhi_ep_state_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, state_work); + struct device *dev = &mhi_cntrl->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", + TO_MHI_STATE_STR(itr->state)); + + switch (itr->state) { + case MHI_STATE_M0: + ret = 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 = 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", itr->state); + break; + } + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -384,6 +420,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, } INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); + INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); mhi_cntrl->ring_wq = alloc_ordered_workqueue("mhi_ep_ring_wq", WQ_HIGHPRI); if (!mhi_cntrl->ring_wq) { @@ -391,7 +428,14 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_free_cmd; } + mhi_cntrl->state_wq = alloc_ordered_workqueue("mhi_ep_state_wq", WQ_HIGHPRI); + if (!mhi_cntrl->state_wq) { + ret = -ENOMEM; + goto err_destroy_ring_wq; + } + INIT_LIST_HEAD(&mhi_cntrl->ch_db_list); + INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); spin_lock_init(&mhi_cntrl->list_lock); mutex_init(&mhi_cntrl->event_lock); @@ -403,7 +447,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, mhi_cntrl->index = ida_alloc(&mhi_ep_cntrl_ida, GFP_KERNEL); if (mhi_cntrl->index < 0) { ret = mhi_cntrl->index; - goto err_destroy_ring_wq; + goto err_destroy_state_wq; } /* Allocate the controller device */ @@ -432,6 +476,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_state_wq: + destroy_workqueue(mhi_cntrl->state_wq); err_destroy_ring_wq: destroy_workqueue(mhi_cntrl->ring_wq); err_free_cmd: @@ -447,6 +493,7 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; + destroy_workqueue(mhi_cntrl->state_wq); destroy_workqueue(mhi_cntrl->ring_wq); kfree(mhi_cntrl->mhi_cmd); diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c new file mode 100644 index 000000000000..95cec5c627b4 --- /dev/null +++ b/drivers/bus/mhi/ep/sm.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Manivannan Sadhasivam + */ + +#include +#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) +{ + bool valid = false; + + switch (mhi_state) { + case MHI_STATE_READY: + valid = (cur_mhi_state == MHI_STATE_RESET); + break; + case MHI_STATE_M0: + valid = (cur_mhi_state == MHI_STATE_READY || + cur_mhi_state == MHI_STATE_M3); + break; + case MHI_STATE_M3: + valid = (cur_mhi_state == MHI_STATE_M0); + break; + case MHI_STATE_SYS_ERR: + /* Transition to SYS_ERR state is allowed all the time */ + valid = true; + break; + default: + break; + } + + return valid; +} + +int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state) +{ + struct device *dev = &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", + TO_MHI_STATE_STR(mhi_state), + TO_MHI_STATE_STR(mhi_cntrl->mhi_state)); + return -EACCES; + } + + switch (mhi_state) { + case MHI_STATE_READY: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_READY_MASK, + MHISTATUS_READY_SHIFT, 1); + + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, + MHISTATUS_MHISTATE_SHIFT, mhi_state); + break; + case MHI_STATE_SYS_ERR: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_SYSERR_MASK, + MHISTATUS_SYSERR_SHIFT, 1); + + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, + MHISTATUS_MHISTATE_SHIFT, mhi_state); + break; + case MHI_STATE_M1: + case MHI_STATE_M2: + dev_err(dev, "MHI state (%s) not supported\n", TO_MHI_STATE_STR(mhi_state)); + return -EOPNOTSUPP; + case MHI_STATE_M0: + case MHI_STATE_M3: + mhi_ep_mmio_masked_write(mhi_cntrl, MHISTATUS, + MHISTATUS_MHISTATE_MASK, + MHISTATUS_MHISTATE_SHIFT, mhi_state); + break; + default: + dev_err(dev, "Invalid MHI state (%d)", mhi_state); + return -EINVAL; + } + + mhi_cntrl->mhi_state = mhi_state; + + return 0; +} + +int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state old_state; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + old_state = mhi_cntrl->mhi_state; + + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); + if (ret) { + spin_unlock_bh(&mhi_cntrl->state_lock); + return ret; + } + + spin_unlock_bh(&mhi_cntrl->state_lock); + /* Signal host that the device moved to M0 */ + ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M0); + if (ret) { + dev_err(dev, "Failed sending M0 state change event: %d\n", ret); + return ret; + } + + if (old_state == MHI_STATE_READY) { + /* Allow the host to process state change event */ + mdelay(1); + + /* Send AMSS EE event to host */ + ret = mhi_ep_send_ee_event(mhi_cntrl, MHI_EP_AMSS_EE); + if (ret) { + dev_err(dev, "Failed sending AMSS EE event: %d\n", ret); + return ret; + } + } + + return 0; +} + +int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + int ret; + + spin_lock_bh(&mhi_cntrl->state_lock); + ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); + if (ret) { + spin_unlock_bh(&mhi_cntrl->state_lock); + return ret; + } + + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* Signal host that the device moved to M3 */ + ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); + if (ret) { + dev_err(dev, "Failed sending M3 state change event: %d\n", ret); + return ret; + } + + return 0; +} + +int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &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_ep_mmio_masked_read(mhi_cntrl, MHISTATUS, MHISTATUS_MHISTATE_MASK, + MHISTATUS_MHISTATE_SHIFT, &mhi_state); + mhi_ep_mmio_masked_read(mhi_cntrl, MHISTATUS, MHISTATUS_READY_MASK, + MHISTATUS_READY_SHIFT, &is_ready); + + if (mhi_state != 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 -EFAULT; + } + + ret = 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 323cd3319b13..ea7435d0e609 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -62,11 +62,14 @@ 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 structure + * @state_wq: Dedicated workqueue for handling MHI state transitions * @ring_wq: Dedicated workqueue for processing MHI rings + * @state_work: State transition worker * @ring_work: Ring worker * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists + * @state_lock: Lock for protecting state transitions * @event_lock: Lock for protecting event rings * @chdb: Array of channel doorbell interrupt info * @raise_irq: CB function for raising IRQ to the host @@ -96,12 +99,15 @@ struct mhi_ep_cntrl { u64 ev_ctx_host_pa; u64 cmd_ctx_host_pa; + struct workqueue_struct *state_wq; struct workqueue_struct *ring_wq; + struct work_struct state_work; struct work_struct ring_work; struct list_head ch_db_list; struct list_head st_transition_list; spinlock_t list_lock; + spinlock_t state_lock; struct mutex event_lock; struct mhi_ep_db_info chdb[4]; From patchwork Thu Dec 2 11:35:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520274 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 966C2C433EF for ; Thu, 2 Dec 2021 11:38:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357359AbhLBLlm (ORCPT ); Thu, 2 Dec 2021 06:41:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357540AbhLBLlZ (ORCPT ); Thu, 2 Dec 2021 06:41:25 -0500 Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8051C0613FC for ; Thu, 2 Dec 2021 03:37:57 -0800 (PST) Received: by mail-pl1-x630.google.com with SMTP id p18so20001781plf.13 for ; Thu, 02 Dec 2021 03:37:57 -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=n9Zk0Mx91LkY3ff2uRdFKhlAWYb3Qu2I8it/OG3Zh78=; b=Q/78+blmQN0kykBYegZYj4RMoHPyz12H2xkImfaVEXW8VTXxzIf31Bem91lATJpl1U N7nlkHjEnSTWW5PBn24c1vQLV/V1dNg6ZMDBZwhZqZG0OcmPXa9PUwXYC6WiTiGnBIoq gXQYj7CY3ZEsgGP4l7t3RTaB8R58dbPuTGU2180FCVqzS0YluY5xf+jj0Rzgpu9ORmiA 4tr625w1odOqfwVQEVNuwUCLgiRsdc/+cuLl1cpbS212F7OD0Bez4NU8/fkQ6lhSgu95 ctzYBLHoAO2Ju8tXh1Op2DHeEpP7mnPeJTQc13cb3PNy7eIpcQ65AFl01vMYIMKpkDlT ryEQ== 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=n9Zk0Mx91LkY3ff2uRdFKhlAWYb3Qu2I8it/OG3Zh78=; b=f6yT1rNRne6XzWyPOrcvn201Pj8mai32vzCbY0eWRh/qkhXTXjM39Z5Qm2EzXJ52Uj QvheEtMyrydYlxqM2SmBOSSmnTW7aPwLbjtr2YYAwXUeCxX8HMYd3ejMcifsVIxqxfma K3/PPhZTWD1XJfOwuJJe4kj2rZlowmrE+9tWhx10xUtKLEfgp+NSx97CvgODmNFmOxRL jkrGlfcEU6QkcE0tXvrd+HIvl4pj250Bs22fSnkwgJJ8Ixg7FMowiGMUV7i08xZ/Yksh ouqe4torwhXffWfp/Y0d3H0TsvvYsZE5m102b2ZYi86Bww+T755EQNXWiF3svvKlTFJ/ sKTA== X-Gm-Message-State: AOAM531rLUMzl6eGGAYflDnXKlY+X6Fz4MgzWZFd4T+jr9g5vsOiJ+nT fkhjP71Gt3u2BAVPgwUokkzN X-Google-Smtp-Source: ABdhPJx1a7042SZo6wN5sWbJjlB8FVkEKUAWdmgxxZ+Jz8PpswrtSgCvYEFxDZQTm7tUnZmXro2gGQ== X-Received: by 2002:a17:90b:128d:: with SMTP id fw13mr5371859pjb.50.1638445077190; Thu, 02 Dec 2021 03:37:57 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:37:56 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 12/20] bus: mhi: ep: Add support for processing MHI endpoint interrupts Date: Thu, 2 Dec 2021 17:05:44 +0530 Message-Id: <20211202113553.238011-13-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/main.c | 114 +++++++++++++++++++++++++++++++++++++- include/linux/mhi_ep.h | 2 + 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index f9b80fccfe70..70740358d329 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -179,6 +179,56 @@ static void mhi_ep_ring_worker(struct work_struct *work) spin_unlock_irqrestore(&mhi_cntrl->list_lock, flags); } +static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, + unsigned long ch_int, u32 ch_idx) +{ + struct mhi_ep_ring *ring; + unsigned int i; + + for_each_set_bit(i, &ch_int, 32) { + /* Channel index varies for each register: 0, 32, 64, 96 */ + i += ch_idx; + ring = &mhi_cntrl->mhi_chan[i].ring; + + spin_lock(&mhi_cntrl->list_lock); + list_add(&ring->list, &mhi_cntrl->ch_db_list); + spin_unlock(&mhi_cntrl->list_lock); + /* + * Disable the channel interrupt here and enable it once + * the current interrupt got serviced + */ + mhi_ep_mmio_disable_chdb_a7(mhi_cntrl, i); + queue_work(mhi_cntrl->ring_wq, &mhi_cntrl->ring_work); + } +} + +/* + * Channel interrupt statuses are contained in 4 registers each of 32bit length. + * 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) +{ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + u32 ch_int, ch_idx; + int i; + + mhi_ep_mmio_read_chdb_status_interrupts(mhi_cntrl); + + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + ch_idx = i * MHI_MASK_CH_EV_LEN; + + /* Only process channel interrupt if the mask is enabled */ + ch_int = (mhi_cntrl->chdb[i].status & mhi_cntrl->chdb[i].mask); + if (ch_int) { + dev_dbg(dev, "Processing channel doorbell interrupt\n"); + mhi_ep_queue_channel_db(mhi_cntrl, ch_int, ch_idx); + mhi_ep_mmio_write(mhi_cntrl, MHI_CHDB_INT_CLEAR_A7_n(i), + mhi_cntrl->chdb[i].status); + } + } +} + static void mhi_ep_state_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, state_work); @@ -215,6 +265,54 @@ static void mhi_ep_state_worker(struct work_struct *work) } } +static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl, + enum mhi_state state) +{ + struct mhi_ep_state_transition *item = kmalloc(sizeof(*item), GFP_ATOMIC); + + item->state = 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->state_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 = data; + + struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 int_value = 0; + + /* Acknowledge the interrupts */ + mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS_A7, &int_value); + mhi_ep_mmio_write(mhi_cntrl, MHI_CTRL_INT_CLEAR_A7, int_value); + + /* Check for ctrl interrupt */ + if (FIELD_GET(MHI_CTRL_INT_STATUS_A7_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"); + queue_work(mhi_cntrl->ring_wq, &mhi_cntrl->ring_work); + } + + /* 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 = to_mhi_ep_device(dev); @@ -406,7 +504,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_device *mhi_dev; int ret; - 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; ret = parse_ch_cfg(mhi_cntrl, config); @@ -450,12 +548,20 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, goto err_destroy_state_wq; } + irq_set_status_flags(mhi_cntrl->irq, IRQ_NOAUTOEN); + ret = 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: %d\n", ret); + goto err_ida_free; + } + /* Allocate the controller device */ mhi_dev = mhi_ep_alloc_device(mhi_cntrl); if (IS_ERR(mhi_dev)) { dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate controller device\n"); ret = PTR_ERR(mhi_dev); - goto err_ida_free; + goto err_free_irq; } mhi_dev->dev_type = MHI_DEVICE_CONTROLLER; @@ -474,6 +580,8 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, err_release_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_state_wq: @@ -496,6 +604,8 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) destroy_workqueue(mhi_cntrl->state_wq); destroy_workqueue(mhi_cntrl->ring_wq); + free_irq(mhi_cntrl->irq, mhi_cntrl); + kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index ea7435d0e609..7a665cd55579 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -84,6 +84,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; @@ -129,6 +130,7 @@ struct mhi_ep_cntrl { u32 chdb_offset; u32 erdb_offset; int index; + int irq; }; /** From patchwork Thu Dec 2 11:35:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519852 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 74A15C433FE for ; Thu, 2 Dec 2021 11:38:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346388AbhLBLlt (ORCPT ); Thu, 2 Dec 2021 06:41:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357542AbhLBLlZ (ORCPT ); Thu, 2 Dec 2021 06:41:25 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD4D6C06175E for ; Thu, 2 Dec 2021 03:38:02 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id h24so20354208pjq.2 for ; Thu, 02 Dec 2021 03:38: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=bNkVGdcpAk1Xtqvfpq5Pdopfhy3WT41I1Sh0APLacSQ=; b=IHDK2pbhccoKe9ukL5raKWBzlM/5gZvLQmemIg4OfKxWjYFrg+uft4uJJS9wn0hoUR 1XHhaUSFgPr9BqtAHXgOHv10jGQwAEYPRWeXClm2DsgSmkuVVLxpxi1FbksAZeK/lCbm UZzi1gGjgtgGWbTm7tsQQgDXL27jFGa+VN9UmiiO2AJ8raYxoYsOxU+pVXD09cRonrHv B4ehwP/foVcgUFZEzithDCE63+EOHAHYOgnJdP2F9AqinucGeHQx1JgaY1a0GIP629PE OULjLSxAeosl9WNwO5PIIjlo6A3vkIFpSvuf2av/g3BFwD1kBOLm8kML6Q3plqw1pk7b VEXA== 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=bNkVGdcpAk1Xtqvfpq5Pdopfhy3WT41I1Sh0APLacSQ=; b=gtpAY+C+hIJidupBIn1PfaM2x1+cMYMRquWrdIa0nR6nhkZYpjwQAyLrw9s3zFZDMt etlhRocI6EWjo5MrOqkcXa7dB5MQiF5njIEYvSDgrT0+7d5DCvZNWPt35NRVf4jyGMUr wMLm4KfFtGrj2RPbhul5afRQc8Gkd28syCHFa69Dg9g2bgZG6nfgO3deinhFXwWSuL2s GTkqx6UF+pG0GH3YT8uRSlW3EKXT6mZ5x94b8Cn9Gq7+ZEaN0tMXNdurNJpbKUbEJQC5 t1se4NGEEU1y0GSL1soOunhlj09TEnIF7IoN4jNGaRUbkHLKv3FqLz2xnHZX4Wf6CRRT A/uA== X-Gm-Message-State: AOAM530+77lnmGHSLJLezXPK6FcjEEQGSziedvo0vNm9KMQjPN08I2P/ 7S35lmcGmgvvPSDr24eZNYH+ X-Google-Smtp-Source: ABdhPJwqqM09P5wvpx4+rW+a73V/212FE+papI75O2unr0Kj6KRqP8P5vyYOiLj5a2H5JDdsATWx0w== X-Received: by 2002:a17:902:ab94:b0:143:beb5:b6a7 with SMTP id f20-20020a170902ab9400b00143beb5b6a7mr15150911plr.30.1638445082160; Thu, 02 Dec 2021 03:38:02 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.37.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:01 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 13/20] bus: mhi: ep: Add support for powering up the MHI endpoint stack Date: Thu, 2 Dec 2021 17:05:45 +0530 Message-Id: <20211202113553.238011-14-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/main.c | 228 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 28 +++++ 2 files changed, 256 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 70740358d329..5f62b6fb6dbc 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -16,6 +16,9 @@ #include #include "internal.h" +#define MHI_SUSPEND_MIN 100 +#define MHI_SUSPEND_TIMEOUT 600 + static DEFINE_IDA(mhi_ep_cntrl_ida); static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 event_ring, @@ -143,6 +146,175 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_e return mhi_ep_send_event(mhi_cntrl, 0, &event); } +static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &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: %d, HW Event rings: %d\n", + mhi_cntrl->event_rings, mhi_cntrl->hw_event_rings); + + mhi_cntrl->ch_ctx_host_size = sizeof(struct mhi_chan_ctxt) * + mhi_cntrl->max_chan; + mhi_cntrl->ev_ctx_host_size = sizeof(struct mhi_event_ctxt) * + mhi_cntrl->event_rings; + mhi_cntrl->cmd_ctx_host_size = sizeof(struct mhi_cmd_ctxt); + + /* Get the channel context base pointer from host */ + mhi_ep_mmio_get_chc_base(mhi_cntrl); + + /* Allocate memory for caching host channel context */ + mhi_cntrl->ch_ctx_cache = mhi_cntrl->alloc_addr(mhi_cntrl, &mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_host_size); + if (!mhi_cntrl->ch_ctx_cache) { + dev_err(dev, "Failed to allocate ch_ctx_cache memory\n"); + return -ENOMEM; + } + + /* Map the host channel context */ + ret = mhi_cntrl->map_addr(mhi_cntrl, mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_host_pa, mhi_cntrl->ch_ctx_host_size); + if (ret) { + dev_err(dev, "Failed to map ch_ctx_cache\n"); + goto err_ch_ctx; + } + + /* Get the event context base pointer from host */ + mhi_ep_mmio_get_erc_base(mhi_cntrl); + + /* Allocate memory for caching host event context */ + mhi_cntrl->ev_ctx_cache = mhi_cntrl->alloc_addr(mhi_cntrl, &mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_host_size); + if (!mhi_cntrl->ev_ctx_cache) { + dev_err(dev, "Failed to allocate ev_ctx_cache memory\n"); + ret = -ENOMEM; + goto err_ch_ctx_map; + } + + /* Map the host event context */ + ret = mhi_cntrl->map_addr(mhi_cntrl, mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_host_pa, mhi_cntrl->ev_ctx_host_size); + if (ret) { + dev_err(dev, "Failed to map ev_ctx_cache\n"); + goto err_ev_ctx; + } + + /* Get the command context base pointer from host */ + mhi_ep_mmio_get_crc_base(mhi_cntrl); + + /* Allocate memory for caching host command context */ + mhi_cntrl->cmd_ctx_cache = mhi_cntrl->alloc_addr(mhi_cntrl, &mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_host_size); + if (!mhi_cntrl->cmd_ctx_cache) { + dev_err(dev, "Failed to allocate cmd_ctx_cache memory\n"); + ret = -ENOMEM; + goto err_ev_ctx_map; + } + + /* Map the host command context */ + ret = mhi_cntrl->map_addr(mhi_cntrl, mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_host_pa, mhi_cntrl->cmd_ctx_host_size); + if (ret) { + dev_err(dev, "Failed to map cmd_ctx_cache\n"); + goto err_cmd_ctx; + } + + /* Initialize command ring */ + ret = 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_map; + } + + return ret; + +err_cmd_ctx_map: + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->cmd_ctx_cache_phys); + +err_cmd_ctx: + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_cache, mhi_cntrl->cmd_ctx_host_size); + +err_ev_ctx_map: + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->ev_ctx_cache_phys); + +err_ev_ctx: + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_cache, mhi_cntrl->ev_ctx_host_size); + +err_ch_ctx_map: + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->ch_ctx_cache_phys); + +err_ch_ctx: + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_cache, mhi_cntrl->ch_ctx_host_size); + + return ret; +} + +static void mhi_ep_free_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->cmd_ctx_cache_phys); + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->cmd_ctx_cache_phys, + mhi_cntrl->cmd_ctx_cache, mhi_cntrl->cmd_ctx_host_size); + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->ev_ctx_cache_phys); + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->ev_ctx_cache_phys, + mhi_cntrl->ev_ctx_cache, mhi_cntrl->ev_ctx_host_size); + mhi_cntrl->unmap_addr(mhi_cntrl, mhi_cntrl->ch_ctx_cache_phys); + mhi_cntrl->free_addr(mhi_cntrl, mhi_cntrl->ch_ctx_cache_phys, + mhi_cntrl->ch_ctx_cache, mhi_cntrl->ch_ctx_host_size); +} + +static void mhi_ep_enable_int(struct mhi_ep_cntrl *mhi_cntrl) +{ + mhi_ep_mmio_enable_chdb_interrupts(mhi_cntrl); + 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 = &mhi_cntrl->mhi_dev->dev; + enum mhi_state state; + u32 max_cnt = 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 != MHI_STATE_M0 && max_cnt < MHI_SUSPEND_TIMEOUT); + + if (state == MHI_STATE_M0) { + ret = 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_EP_AMSS_EE); + } else { + dev_err(dev, "Host failed to enter M0\n"); + return -ETIMEDOUT; + } + + /* Enable all interrupts now */ + mhi_ep_enable_int(mhi_cntrl); + + return 0; +} + static void mhi_ep_ring_worker(struct work_struct *work) { struct mhi_ep_cntrl *mhi_cntrl = container_of(work, @@ -313,6 +485,62 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } +int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct device *dev = &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 = kzalloc(mhi_cntrl->event_rings * (sizeof(*mhi_cntrl->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 = 0; i < mhi_cntrl->max_chan; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_chan[i].ring, RING_TYPE_CH, i); + for (i = 0; i < mhi_cntrl->event_rings; i++) + mhi_ep_ring_init(&mhi_cntrl->mhi_event[i].ring, RING_TYPE_ER, i); + + spin_lock_bh(&mhi_cntrl->state_lock); + mhi_cntrl->mhi_state = MHI_STATE_RESET; + spin_unlock_bh(&mhi_cntrl->state_lock); + + /* Set AMSS EE before signaling ready state */ + mhi_ep_mmio_set_env(mhi_cntrl, MHI_EP_AMSS_EE); + + /* All set, notify the host that we are ready */ + ret = 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 = mhi_ep_enable(mhi_cntrl); + if (ret) { + dev_err(dev, "Failed to enable MHI endpoint: %d\n", ret); + goto err_free_event; + } + + enable_irq(mhi_cntrl->irq); + mhi_cntrl->is_enabled = 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 = to_mhi_ep_device(dev); diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 7a665cd55579..105e8067409a 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -59,9 +59,18 @@ 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 structure + * @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 + * @ch_ctx_host_size: Size of the host channel context data structure + * @ev_ctx_host_size: Size of the host event context data structure + * @cmd_ctx_host_size: Size of the host command context data structure * @state_wq: Dedicated workqueue for handling MHI state transitions * @ring_wq: Dedicated workqueue for processing MHI rings * @state_work: State transition worker @@ -85,6 +94,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 + * @is_enabled: Check if the endpoint controller is enabled or not */ struct mhi_ep_cntrl { struct device *cntrl_dev; @@ -96,9 +106,18 @@ struct mhi_ep_cntrl { struct mhi_ep_cmd *mhi_cmd; struct mhi_ep_sm *sm; + 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; + phys_addr_t ch_ctx_cache_phys; + phys_addr_t ev_ctx_cache_phys; + phys_addr_t cmd_ctx_cache_phys; + size_t ch_ctx_host_size; + size_t ev_ctx_host_size; + size_t cmd_ctx_host_size; struct workqueue_struct *state_wq; struct workqueue_struct *ring_wq; @@ -131,6 +150,7 @@ struct mhi_ep_cntrl { u32 erdb_offset; int index; int irq; + bool is_enabled; }; /** @@ -229,4 +249,12 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); +/** + * 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 From patchwork Thu Dec 2 11:35:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520273 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 6A7BDC433F5 for ; Thu, 2 Dec 2021 11:38:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357483AbhLBLls (ORCPT ); Thu, 2 Dec 2021 06:41:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346388AbhLBLla (ORCPT ); Thu, 2 Dec 2021 06:41:30 -0500 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B820AC061761 for ; Thu, 2 Dec 2021 03:38:07 -0800 (PST) Received: by mail-pf1-x435.google.com with SMTP id u80so27653429pfc.9 for ; Thu, 02 Dec 2021 03:38:07 -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=nV8vHxyZkpSnq48aLAVk9vWe3JSWpiq16Z/xCyUhjNk=; b=Y8YiN5H2VJrW66Jul8DtVt+vPTBGorE5JkAQNt5Pfqh0p1zZffWZMqz+ZgOzkQjQW8 PU81FmoyDguGJJV6l9fxt6rgDCCNtvMiB0mks1nN6CKlsbnMR13HRODeaDfEbL751WG9 4Jy4J7F79S37q4xR/TlNyNmLqIMqwvUWLUSf4H8GT9b6KosBheKjhkn3pNgsv0eDe9KL F8YqtX3ZgZ/w88OAUVGb4jdHdNrTDYqFBf1oIo2A1n+Sprutp6oEMZfb29AKUqsFft7B V8b+4oTAUyzZ4HbkDORrCQhhyb9qMlAWo5TADfv/jgSoETMC2E7kps/ng445CndAeuDt jZNQ== 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=nV8vHxyZkpSnq48aLAVk9vWe3JSWpiq16Z/xCyUhjNk=; b=DeFh/tSld+FfdpRn+7nvB1TjxJOhWfKMFkDi1/YOC3mS5g3ksoXf+fzYnlfide0XEJ JElKgMJiSgXXmLPi+FjHSaB6KnX7ZRB8ZT6spWjZ0QLcvwksHuOfwp3BzZZUSmJ0A4bT DqR3xPodONmNA/6I9OOrxJyME+1BZ/hUTxOCL7ka5bzWdei2Y2QHwZpD8plGS6FZDnfJ NMwYqAQWRKztU1MROTg6twhbktA2VK5irClyON7eJP7EVklO3G21yBqbdJyPFiJferyE BWwwZaYckWTNum0BvTbFb3Q1GFQ54IdSCSEndFfWOGSqaiJCI4BgZ+KlcG64NAcrPfCM 6y5Q== X-Gm-Message-State: AOAM531wVykmHbNA+6eNoA6BFL+Hf1f/LyLIGfGbO7TLEbuTqg2noZaN l2n9tacEUW0w8pYUz8yEA58T X-Google-Smtp-Source: ABdhPJwpqrSSnOrT7D2SRy1GCdYfVGlS+Hb9qNXef7DD3HfUnGZOuYU/lpSmNu3ustqALzJtRuQmaQ== X-Received: by 2002:a63:66c7:: with SMTP id a190mr9181345pgc.463.1638445087251; Thu, 02 Dec 2021 03:38:07 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:06 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 14/20] bus: mhi: ep: Add support for powering down the MHI endpoint stack Date: Thu, 2 Dec 2021 17:05:46 +0530 Message-Id: <20211202113553.238011-15-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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 --- drivers/bus/mhi/ep/main.c | 81 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 +++ 2 files changed, 87 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 5f62b6fb6dbc..89d1bb780747 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,8 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_destroy_device(struct device *dev, void *data); + static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 event_ring, struct mhi_ep_ring_element *el) { @@ -485,6 +487,71 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } +static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_ring *ch_ring, *ev_ring; + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + int i; + + /* Stop all the channels */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + ch_ring = &mhi_cntrl->mhi_chan[i].ring; + if (ch_ring->state == RING_STATE_UINT) + continue; + + mhi_chan = &mhi_cntrl->mhi_chan[i]; + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to client drivers */ + if (mhi_chan->xfer_cb) { + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + } + + flush_workqueue(mhi_cntrl->ring_wq); + flush_workqueue(mhi_cntrl->state_wq); + + /* Destroy devices associated with all channels */ + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_ep_destroy_device); + + /* Stop and reset the transfer rings */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + ch_ring = &mhi_cntrl->mhi_chan[i].ring; + if (ch_ring->state == RING_STATE_UINT) + continue; + + mhi_chan = &mhi_cntrl->mhi_chan[i]; + mutex_lock(&mhi_chan->lock); + mhi_ep_ring_stop(mhi_cntrl, ch_ring); + mutex_unlock(&mhi_chan->lock); + } + + /* Stop and reset the event rings */ + for (i = 0; i < mhi_cntrl->event_rings; i++) { + ev_ring = &mhi_cntrl->mhi_event[i].ring; + if (ev_ring->state == RING_STATE_UINT) + continue; + + mutex_lock(&mhi_cntrl->event_lock); + mhi_ep_ring_stop(mhi_cntrl, ev_ring); + mutex_unlock(&mhi_cntrl->event_lock); + } + + /* Stop and reset the command ring */ + mhi_ep_ring_stop(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring); + + mhi_ep_free_host_cfg(mhi_cntrl); + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + + mhi_cntrl->is_enabled = false; +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; @@ -541,6 +608,16 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_up); +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) +{ + if (mhi_cntrl->is_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 = to_mhi_ep_device(dev); @@ -825,6 +902,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, } EXPORT_SYMBOL_GPL(mhi_ep_register_controller); +/* + * It is expected that the controller drivers will power down the MHI EP stack + * 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 = mhi_cntrl->mhi_dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 105e8067409a..57fa445661f6 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -257,4 +257,10 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); */ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); +/** + * 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 From patchwork Thu Dec 2 11:35:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519853 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 444D9C433F5 for ; Thu, 2 Dec 2021 11:38:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357512AbhLBLlr (ORCPT ); Thu, 2 Dec 2021 06:41:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53580 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357485AbhLBLlf (ORCPT ); Thu, 2 Dec 2021 06:41:35 -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 17F9DC061763 for ; Thu, 2 Dec 2021 03:38:13 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id v23so20316071pjr.5 for ; Thu, 02 Dec 2021 03:38: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=MQpuLNYbNEk4H3hjLraNYlFa80x0Jc5kbBWvJgY8MCY=; b=d6pjc/4+ke7zeA04PwXzsExF2m7sEhoOLVk/k2VhBUwUWDp3SV8DHL6yzARWC33RNV D9c1WlH1fVTEZKUXPMzdzaFaBQVoxpYa3LQR0/UL+Tkg57By5NFYWLWxfq+UodcfOUzy qTZ/sWr6D8/ZqDUySdXVkPpI3SlVcSgbZvkSqM5A2dZKi/lpQcJkPPOJwsjWKvDgmetW 01UUp2EZT6CHtDyFhBUm5MGm0DjpywpKE1B+M99eTiTx/CWwjr863nu7NDL71rdg9bqD 9ezYZDdVg1GD3Dn8KSWa7jaV5cKWpWzmx9VxLBtX7QNR+Db5+Z3Iq/PK5HPmSQ3ljd+J oljw== 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=MQpuLNYbNEk4H3hjLraNYlFa80x0Jc5kbBWvJgY8MCY=; b=xM7UVV0mGX3Wexn3mrjcqwl3krU9b10jUiRkP1G3eiHT26c802B0dez69NfYFqdWSo 065zSwizpPgMAdPOhZTVWy+orO5cDc18S6G4Kt8HwZEjj1L+jyFJXQZ4NpoESAY6siYj 1g8E0N4jjQC0TQaITo8/8GaKLqZanTsP0kiUgQOnM4QjBegZdldDbWmCf0qBy9MeIxfE dCZbf/HSCNwXMJa9eJIrZddd0rCgBIP4eKPGuB3NbN1uctpGVupaPZPsLInuyhy8sl2F B6wvXF1GsVUytSajSg633svGJpkjgtKAOdlVN9ErbzJ4b8Aoiy/Ie2aS6dM1kNPDozF7 WF7g== X-Gm-Message-State: AOAM530VPknPqmXZlwv3bHTdSdfq006AcVWcpv9LjFP9ovv3+JOYqKUM YsyWAvfl3uPs0t58LOmCsmgT X-Google-Smtp-Source: ABdhPJzUwEZeU1c8UgjJMRhmgJ+L7SdM1HOzaq0rA8VT+svZDvxm+CT7Gz/AkIeWhio02WDOnUTkoA== X-Received: by 2002:a17:90b:224f:: with SMTP id hk15mr5399079pjb.173.1638445092509; Thu, 02 Dec 2021 03:38:12 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:12 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 15/20] bus: mhi: ep: Add support for handling MHI_RESET Date: Thu, 2 Dec 2021 17:05:47 +0530 Message-Id: <20211202113553.238011-16-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. 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 89d1bb780747..0b0fad6bf69a 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -464,6 +464,7 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) struct device *dev = &mhi_cntrl->mhi_dev->dev; enum mhi_state state; u32 int_value = 0; + bool mhi_reset; /* Acknowledge the interrupts */ mhi_ep_mmio_read(mhi_cntrl, MHI_CTRL_INT_STATUS_A7, &int_value); @@ -472,6 +473,14 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) /* Check for ctrl interrupt */ if (FIELD_GET(MHI_CTRL_INT_STATUS_A7_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); } @@ -552,6 +561,49 @@ static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) mhi_cntrl->is_enabled = false; } +static void mhi_ep_reset_worker(struct work_struct *work) +{ + struct mhi_ep_cntrl *mhi_cntrl = container_of(work, struct mhi_ep_cntrl, reset_work); + struct device *dev = &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 = 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 == 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_EP_AMSS_EE); + + /* All set, notify the host that we are ready */ + ret = mhi_ep_set_ready_state(mhi_cntrl); + if (ret) + return; + + dev_dbg(dev, "READY state notification sent to the host\n"); + + ret = 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 = &mhi_cntrl->mhi_dev->dev; @@ -824,6 +876,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, INIT_WORK(&mhi_cntrl->ring_work, mhi_ep_ring_worker); INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); + INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); mhi_cntrl->ring_wq = alloc_ordered_workqueue("mhi_ep_ring_wq", WQ_HIGHPRI); if (!mhi_cntrl->ring_wq) { diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 57fa445661f6..6482b0c91865 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -75,6 +75,7 @@ struct mhi_ep_db_info { * @ring_wq: Dedicated workqueue for processing MHI rings * @state_work: State transition worker * @ring_work: Ring worker + * @reset_work: Worker for MHI Endpoint reset * @ch_db_list: List of queued channel doorbells * @st_transition_list: List of state transitions * @list_lock: Lock for protecting state transition and channel doorbell lists @@ -123,6 +124,7 @@ struct mhi_ep_cntrl { struct workqueue_struct *ring_wq; struct work_struct state_work; struct work_struct ring_work; + struct work_struct reset_work; struct list_head ch_db_list; struct list_head st_transition_list; From patchwork Thu Dec 2 11:35:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520272 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 31610C433F5 for ; Thu, 2 Dec 2021 11:38:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357496AbhLBLlz (ORCPT ); Thu, 2 Dec 2021 06:41:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357500AbhLBLlk (ORCPT ); Thu, 2 Dec 2021 06:41:40 -0500 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A877BC0613FF for ; Thu, 2 Dec 2021 03:38:17 -0800 (PST) Received: by mail-pl1-x636.google.com with SMTP id b13so20044341plg.2 for ; Thu, 02 Dec 2021 03:38: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=uXxNxYYV5RcHGgry8/y8RqGwg5B0/QotcI3nKFMorEY=; b=BXPRbj2Qu5dHWVrN6tGOyX9geBDY49fZxhhIDpA9RXI9OOTtqG5b+BBW36OIbpgmZc GGMMazAOykh6BNZZK39dZwfRT0EQPeuVu5FWr1oR1OCJGAKR+YwBRwpFtoaOhwMHW6V5 fRhYdjTCE9cb/tHOZI9+Mx+e7kOrNIwKsNl+m6rpnaTzYghpyGhItJovE6TF9ctZVPCM z1TlqaLXS76YXOgOrYXi9nXk96uBXziK22vwppp4Bq1l1UinDo/4XNT8DHY3sGhulZzn WBJqUjxx8cbNb+cak6TA8xR003fwnFir7UQ9HZ5YQhWBDJbF5LXbqUjDJKOQqJ0az172 IBwg== 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=uXxNxYYV5RcHGgry8/y8RqGwg5B0/QotcI3nKFMorEY=; b=X5qV2U9fJoVInvOmAf0NVMGsVFeFhiK2OFOVTC3UDK5wq6Fr5nubaeytRLwf8KEA+h M7mn721z0adyvTnUNdp89oN0dmOOSMkRF4Ld1DgVRquDUH/JRKD2ftVCj1hit5+Q5VEq Fyr+JG6yMXoDuAqOmZaPUu5RQCk1nfUpQopiL7rXMAhttsG3AS0OZg82Rv5OtUKdmr1N dGE27VkI8fCrBYvlDCMeCB32sg3uuT97lc9GJUuPkSOxPdQj8NgrOm6REALnEyCRmu6N BOq5pArWSYyoNFEwryyHtlUtUr/pTt2Cfq8X5HLsWJRkg9XnZcjvpLpLH0my1O72BoeO jqTw== X-Gm-Message-State: AOAM530LIPamtuMBTecrU4iiZ9oO9TNzcX0iz0v8pmmeW2mo2P4Mq07A N7ZF7u5MSwuxL5sqchsvqFkw X-Google-Smtp-Source: ABdhPJwqoDiWydSWys1ELJ6GFmYWiGCZ1L72iBAely2qK/nzEA+cXaOXsaHsOnLjY0WBHqRk2jMPTw== X-Received: by 2002:a17:90b:33d0:: with SMTP id lk16mr5506453pjb.20.1638445097166; Thu, 02 Dec 2021 03:38:17 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:16 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 16/20] bus: mhi: ep: Add support for handling SYS_ERR condition Date: Thu, 2 Dec 2021 17:05:48 +0530 Message-Id: <20211202113553.238011-17-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/internal.h | 1 + drivers/bus/mhi/ep/main.c | 24 ++++++++++++++++++++++++ drivers/bus/mhi/ep/sm.c | 2 ++ 3 files changed, 27 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index ec508201c5c0..5c6b622482c9 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -228,5 +228,6 @@ 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); #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 0b0fad6bf69a..088eac0808d1 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -148,6 +148,30 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_e return mhi_ep_send_event(mhi_cntrl, 0, &event); } +/* + * We don't need to do anything special other than setting the MHI SYS_ERR + * state. The host issue 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 = &mhi_cntrl->mhi_dev->dev; + int ret; + + /* If MHI EP is not enabled, nothing to do */ + if (!mhi_cntrl->is_enabled) + return; + + ret = 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 = 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); +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index 95cec5c627b4..50378b9f7300 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -98,6 +98,7 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); spin_unlock_bh(&mhi_cntrl->state_lock); return ret; } @@ -133,6 +134,7 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) spin_lock_bh(&mhi_cntrl->state_lock); ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M3); if (ret) { + mhi_ep_handle_syserr(mhi_cntrl); spin_unlock_bh(&mhi_cntrl->state_lock); return ret; } From patchwork Thu Dec 2 11:35:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519851 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 8256BC433F5 for ; Thu, 2 Dec 2021 11:38:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241526AbhLBLmL (ORCPT ); Thu, 2 Dec 2021 06:42:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53550 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357439AbhLBLlo (ORCPT ); Thu, 2 Dec 2021 06:41:44 -0500 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBF34C06174A for ; Thu, 2 Dec 2021 03:38:22 -0800 (PST) Received: by mail-pg1-x52f.google.com with SMTP id j11so16828577pgs.2 for ; Thu, 02 Dec 2021 03:38:22 -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=e+aUkbjzi1MK2hvOsEY4CY7pNRFfLRq84Zvw7+YMNiA=; b=BDMl+sDXE/gug1hhp4vN1iDLiKSlczozIBQUQckN9Ozsc7VjZ/vmHaSJ2E/DnOq9D0 BbNRwiunRKoAx0R+FJxf5W9OmP9zRfgE/l4IWhOPKIo+ORfmQx6IHdtRYpc3wwMiRN/T PAaUIHpY+iVMKoASuom0CMseq9AFpAhcZSdaE8+jnR2XxNRCij+MzJfMMzCLZ6uhICC3 lnVMl4Z1OVQ9uq3drAvhvelsY9BqGiK6c0C5f/EMdLUDvNlmu0xOL6yRIBZQYo+kUa3w tK/7D1BIL/9UzdFL7kXJmBuOFudGf6CzWvlhY5oK1xJsRi5C+j1e/TWGg0r5UJ52rlK1 dpWA== 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=e+aUkbjzi1MK2hvOsEY4CY7pNRFfLRq84Zvw7+YMNiA=; b=r6tYd9vPNDlff2oKZ5HOIsj3xqKB7AF+f7XyoDv1SUXttY7Zj8jVizJqtsHOR5Ioq0 n1nNjCBENOfg6aJJTfENaPYNZgHqDPIE0yGT8ZEjhwPOQKjKuJhaiSqWzVHvs102tA0p x3WuxsOIGRdBnogAyQz/ZI0TaUc/O6hNUHh1+gCfHm0uc6ku8eizNngA333lkrtTm+bc xS84CNUFmIU/T0m4Dpdae5j5niBNeZfgsj5q+Ov5a5O3puX2wb8dSA2lwby1B9gCtxCv FWMZNsilH6QFVWlzVatZkxr4abtHgHp9VUWxc19dNhgXeq7mVBr2LPMXkngH/JNl4SHj XVXQ== X-Gm-Message-State: AOAM531xk3m0Ot5rvh8jn1xLyUrJnnt++YONrOrbKMTnYxJ6dTY3Jtyo +LVbONINCULEZZn/2g5KuUUn X-Google-Smtp-Source: ABdhPJzjvG3oA9qcjp93hKg2dvLQMAn/A7afYi6Cd9geFgTCwgxJWT8toiuj1bYH3lQzslBCiRKfqA== X-Received: by 2002:aa7:96ba:0:b0:49f:c35f:83f8 with SMTP id g26-20020aa796ba000000b0049fc35f83f8mr12226795pfk.47.1638445102232; Thu, 02 Dec 2021 03:38:22 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:21 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 17/20] bus: mhi: ep: Add support for processing command and TRE rings Date: Thu, 2 Dec 2021 17:05:49 +0530 Message-Id: <20211202113553.238011-18-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Since we now have all necessary infrastructure, let's add support for processing the command and TRE rings in the MHI endpoint stack. As a part of the TRE ring processing, the channel read functionality is also added that allows the MHI endpoint device to read data from the host over any available MHI channel. During the TRE ring processing, client driver will also be notified about the data availability. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/internal.h | 2 + drivers/bus/mhi/ep/main.c | 350 ++++++++++++++++++++++++++++++++++ drivers/bus/mhi/ep/ring.c | 2 + include/linux/mhi_ep.h | 9 + 4 files changed, 363 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 5c6b622482c9..70626ef3799d 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -188,6 +188,8 @@ int mhi_ep_process_ring(struct mhi_ep_ring *ring); int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *element, int evt_offset); void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring); +int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); +int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el); /* MMIO related functions */ void mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 *regval); diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 088eac0808d1..26d551eb63ce 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -21,6 +21,7 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +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); static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 event_ring, @@ -172,6 +173,355 @@ void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl) dev_err(dev, "Failed sending SYS_ERR state change event: %d\n", ret); } +int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_ep_ring *ch_ring, *event_ring; + union mhi_ep_ring_ctx *event_ctx; + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + u32 event_ring_idx, tmp; + u32 ch_id; + int ret; + + ch_id = MHI_TRE_GET_CMD_CHID(el); + mhi_chan = &mhi_cntrl->mhi_chan[ch_id]; + ch_ring = &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 (%d)\n", ch_id); + + mutex_lock(&mhi_chan->lock); + /* Initialize and configure the corresponding channel ring */ + if (ch_ring->state == RING_STATE_UINT) { + ret = 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 (%d)\n", ch_id); + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, + MHI_EV_CC_UNDEFINED_ERR); + if (ret) + dev_err(dev, "Error sending completion event: %d\n", + MHI_EV_CC_UNDEFINED_ERR); + + goto err_unlock; + } + } + + /* Enable DB for the channel */ + mhi_ep_mmio_enable_chdb_a7(mhi_cntrl, ch_id); + + mutex_lock(&mhi_cntrl->event_lock); + event_ring_idx = mhi_cntrl->ch_ctx_cache[ch_id].erindex; + event_ring = &mhi_cntrl->mhi_event[event_ring_idx].ring; + event_ctx = (union mhi_ep_ring_ctx *)&mhi_cntrl->ev_ctx_cache[event_ring_idx]; + if (event_ring->state == RING_STATE_UINT) { + ret = mhi_ep_ring_start(mhi_cntrl, event_ring, event_ctx); + if (ret) { + dev_err(dev, "Error starting event ring: %d\n", + mhi_cntrl->ch_ctx_cache[ch_id].erindex); + mutex_unlock(&mhi_cntrl->event_lock); + goto err_unlock; + } + } + + mutex_unlock(&mhi_cntrl->event_lock); + + /* Set channel state to RUNNING */ + mhi_chan->state = MHI_CH_STATE_RUNNING; + tmp = mhi_cntrl->ch_ctx_cache[ch_id].chcfg; + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_RUNNING << CHAN_CTX_CHSTATE_SHIFT); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = tmp; + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event: %d\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 != 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 = mhi_ep_create_device(mhi_cntrl, ch_id); + if (ret) { + dev_err(dev, "Error creating device for channel (%d)\n", ch_id); + return ret; + } + } + + break; + case MHI_PKT_TYPE_STOP_CHAN_CMD: + dev_dbg(dev, "Received STOP command for channel (%d)\n", ch_id); + if (ch_ring->state == RING_STATE_UINT) { + dev_err(dev, "Channel (%d) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Disable DB for the channel */ + mhi_ep_mmio_disable_chdb_a7(mhi_cntrl, ch_id); + + /* Set the local value of the transfer ring read pointer to the channel context */ + ch_ring->rd_offset = mhi_ep_ring_addr2offset(ch_ring, + ch_ring->ring_ctx->generic.rp); + + /* Send channel disconnect status to client drivers */ + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to STOP */ + mhi_chan->state = MHI_CH_STATE_STOP; + tmp = mhi_cntrl->ch_ctx_cache[ch_id].chcfg; + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_STOP << CHAN_CTX_CHSTATE_SHIFT); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = tmp; + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event: %d\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 (%d)\n", ch_id); + if (ch_ring->state == RING_STATE_UINT) { + dev_err(dev, "Channel (%d) not opened\n", ch_id); + return -ENODEV; + } + + mutex_lock(&mhi_chan->lock); + /* Stop and reset the transfer ring */ + mhi_ep_ring_stop(mhi_cntrl, ch_ring); + + /* Send channel disconnect status to client driver */ + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + + /* Set channel state to DISABLED */ + mhi_chan->state = MHI_CH_STATE_DISABLED; + tmp = mhi_cntrl->ch_ctx_cache[ch_id].chcfg; + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + mhi_cntrl->ch_ctx_cache[ch_id].chcfg = tmp; + + ret = mhi_ep_send_cmd_comp_event(mhi_cntrl, MHI_EV_CC_SUCCESS); + if (ret) { + dev_err(dev, "Error sending command completion event: %d\n", + MHI_EV_CC_SUCCESS); + goto err_unlock; + } + mutex_unlock(&mhi_chan->lock); + break; + default: + dev_err(dev, "Invalid command received: %d for channel (%d)", + 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_check_tre_bytes_left(struct mhi_ep_cntrl *mhi_cntrl, + struct mhi_ep_ring *ring, + struct mhi_ep_ring_element *el) +{ + struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id]; + bool td_done = 0; + + /* A full TRE worth of data was consumed. Check if we are at a TD boundary */ + if (mhi_chan->tre_bytes_left == 0) { + if (MHI_EP_TRE_GET_CHAIN(el)) { + if (MHI_EP_TRE_GET_IEOB(el)) + mhi_ep_send_completion_event(mhi_cntrl, + ring, MHI_EP_TRE_GET_LEN(el), MHI_EV_CC_EOB); + } else { + if (MHI_EP_TRE_GET_IEOT(el)) + mhi_ep_send_completion_event(mhi_cntrl, + ring, MHI_EP_TRE_GET_LEN(el), MHI_EV_CC_EOT); + td_done = 1; + } + + mhi_ep_ring_inc_index(ring); + mhi_chan->tre_bytes_left = 0; + mhi_chan->tre_loc = 0; + } + + return td_done; +} + +bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir) +{ + struct mhi_ep_chan *mhi_chan = (dir == DMA_FROM_DEVICE) ? mhi_dev->dl_chan : + mhi_dev->ul_chan; + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; + struct mhi_ep_ring *ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + return !!(ring->rd_offset == 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 = &mhi_cntrl->mhi_chan[ring->ch_id]; + struct device *dev = &mhi_cntrl->mhi_dev->dev; + size_t bytes_to_read, addr_offset; + struct mhi_ep_ring_element *el; + ssize_t bytes_read = 0; + u32 buf_remaining; + void __iomem *tre_buf; + phys_addr_t tre_phys; + void *write_to_loc; + u64 read_from_loc; + bool td_done = 0; + int ret; + + buf_remaining = len; + + do { + /* Don't process the transfer ring if the channel is not in RUNNING state */ + if (mhi_chan->state != MHI_CH_STATE_RUNNING) + return -ENODEV; + + el = &ring->ring_cache[ring->rd_offset]; + + if (mhi_chan->tre_loc) { + bytes_to_read = min(buf_remaining, + mhi_chan->tre_bytes_left); + dev_dbg(dev, "TRE bytes remaining: %d", mhi_chan->tre_bytes_left); + } else { + if (mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)) + /* Nothing to do */ + return 0; + + mhi_chan->tre_loc = MHI_EP_TRE_GET_PTR(el); + mhi_chan->tre_size = MHI_EP_TRE_GET_LEN(el); + mhi_chan->tre_bytes_left = mhi_chan->tre_size; + + bytes_to_read = min(buf_remaining, mhi_chan->tre_size); + } + + bytes_read += bytes_to_read; + addr_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left; + read_from_loc = mhi_chan->tre_loc + addr_offset; + write_to_loc = result->buf_addr + (len - buf_remaining); + mhi_chan->tre_bytes_left -= bytes_to_read; + + tre_buf = mhi_cntrl->alloc_addr(mhi_cntrl, &tre_phys, bytes_to_read); + if (!tre_buf) { + dev_err(dev, "Failed to allocate TRE buffer\n"); + return -ENOMEM; + } + + ret = mhi_cntrl->map_addr(mhi_cntrl, tre_phys, read_from_loc, bytes_to_read); + if (ret) { + dev_err(dev, "Failed to map TRE buffer\n"); + goto err_tre_free; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Reading %d bytes", bytes_to_read); + memcpy_fromio(write_to_loc, tre_buf, bytes_to_read); + + mhi_cntrl->unmap_addr(mhi_cntrl, tre_phys); + mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_read); + + buf_remaining -= bytes_to_read; + td_done = mhi_ep_check_tre_bytes_left(mhi_cntrl, ring, el); + } while (buf_remaining && !td_done); + + result->bytes_xferd = bytes_read; + + return bytes_read; + +err_tre_free: + mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_read); + + return ret; +} + +int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element *el) +{ + struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl; + struct mhi_result result = {}; + u32 len = MHI_EP_DEFAULT_MTU; + struct mhi_ep_chan *mhi_chan; + int ret = 0; + + mhi_chan = &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; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Processing TRE ring\n"); + + mutex_lock(&mhi_chan->lock); + if (ring->ch_id % 2) { + /* DL channel */ + result.dir = mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } else { + /* UL channel */ + while (1) { + result.buf_addr = kzalloc(len, GFP_KERNEL); + if (!result.buf_addr) { + ret = -ENOMEM; + goto err_unlock; + } + + ret = mhi_ep_read_channel(mhi_cntrl, ring, &result, len); + if (ret < 0) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel"); + kfree(result.buf_addr); + break; + } else if (ret == 0) { + /* No more data to read */ + kfree(result.buf_addr); + break; + } + + result.dir = mhi_chan->dir; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + kfree(result.buf_addr); + } + } + +err_unlock: + mutex_unlock(&mhi_chan->lock); + + return ret; +} + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c index 763b8506d309..11adfb659f16 100644 --- a/drivers/bus/mhi/ep/ring.c +++ b/drivers/bus/mhi/ep/ring.c @@ -264,9 +264,11 @@ void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 ring->state = RING_STATE_UINT; ring->type = type; if (ring->type == RING_TYPE_CMD) { + ring->ring_cb = mhi_ep_process_cmd_ring; ring->db_offset_h = CRDB_HIGHER; ring->db_offset_l = CRDB_LOWER; } else if (ring->type == RING_TYPE_CH) { + ring->ring_cb = mhi_ep_process_tre_ring; ring->db_offset_h = CHDB_HIGHER_n(id); ring->db_offset_l = CHDB_LOWER_n(id); ring->ch_id = id; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 6482b0c91865..260a181d3fab 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -265,4 +265,13 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); */ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); +/** + * 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_direction dir); + #endif From patchwork Thu Dec 2 11:35:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 519850 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 BEC8BC433EF for ; Thu, 2 Dec 2021 11:38:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357490AbhLBLmT (ORCPT ); Thu, 2 Dec 2021 06:42:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357488AbhLBLlu (ORCPT ); Thu, 2 Dec 2021 06:41:50 -0500 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65AD8C06175F for ; Thu, 2 Dec 2021 03:38:28 -0800 (PST) Received: by mail-pj1-x102a.google.com with SMTP id nn15-20020a17090b38cf00b001ac7dd5d40cso4409162pjb.3 for ; Thu, 02 Dec 2021 03:38:28 -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=mb08uectv3gQ/l2JA/mJ57RAUgqx8WhgYqgq7CpOQ08=; b=QKVeFCMZqnbKzg72bRUoGwZ98XZQsvcT4nnn4/MwENKvpVrSDovrfYyjjD028MnB5W bqmaxcgD9SM/tB8mwpysFNYJZw4yUT26lcZtrC6ctw2St6/72S0t1m7vDxEhBuOIOQJS rSHCCJw9YK/YkOTRd53D3EVbvXGkzkZRxusatiBLWqVyZExbOx/UAr//5Tcjp+wUkfiX 6lEEI4Sb6zpl5AlS0iu74zyqDW4sun38L9roEkU1voVFQuhJ+/OsXTd49rLslQFDhHo1 8ouZsgwNjgvLjCHHSofRlhXleQnde0oeiEECEIv/9pOOnlGZLx5KwSJTK6gzfSkI8CIb 4Itg== 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=mb08uectv3gQ/l2JA/mJ57RAUgqx8WhgYqgq7CpOQ08=; b=WP1q77nUQjR1XGxrGu/RuQvn0cfNdSQoegIp0B1iiROraZp1PlX3IiR79G4yt+GVh7 3mBImwMf2ZlhFwAIneK2F9UQRVyMcbN6CPUlpC5U1Jb1ZjclrF36aHuxQOinAB2VxhCR FCRQVj+Gs/XnAI8Q+nJETZLmrumsdFsZyEX+iEmj/fqhrIkOUzMfwT9eh9hsiv5BS9DX x7SVddvqfdjJZik+BQgSCVpQt0SPQ7bs5p2tgLh8B8qxsyCuw44SLMrpa/mbRetqJYa9 ebJ7G5zNuptxQ/LitDEH897kPBYYG9KFtgV6zhwQ7EmmQ6Qi2obGZYAJVWwchXJNkRzP dg7Q== X-Gm-Message-State: AOAM5322D0B5W8GR61l/dH7TuH63PKWg7nB1DGRvJe2m4uwaHQ1Ph5fD fFtyGoOf/gS4GkrazCpPSmpX X-Google-Smtp-Source: ABdhPJy+kdFVSgRQqfpsUckHH+EyjS9mtFb++kXeELtyn3sS74xg2xLFyVmMW/nPqZPRPTEaIV2Iuw== X-Received: by 2002:a17:90a:cf85:: with SMTP id i5mr5504573pju.101.1638445107631; Thu, 02 Dec 2021 03:38:27 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:26 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 18/20] bus: mhi: ep: Add support for queueing SKBs over MHI bus Date: Thu, 2 Dec 2021 17:05:50 +0530 Message-Id: <20211202113553.238011-19-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for queueing SKBs over MHI bus in the MHI endpoint stack. The mhi_ep_queue_skb() API will be used by the client networking drivers to queue the SKBs to the host over MHI. Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 132 ++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 12 ++++ 2 files changed, 144 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 26d551eb63ce..cc3da846ed36 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -522,6 +522,138 @@ int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element return ret; } +static void skip_to_next_td(struct mhi_ep_chan *mhi_chan, struct mhi_ep_ring *ring) +{ + struct mhi_ep_ring_element *el; + u32 td_boundary_reached = 0; + + mhi_chan->skip_td = 1; + el = &ring->ring_cache[ring->rd_offset]; + while (ring->rd_offset != ring->wr_offset) { + if (td_boundary_reached) { + mhi_chan->skip_td = 0; + break; + } + + if (!MHI_EP_TRE_GET_CHAIN(el)) + td_boundary_reached = 1; + + mhi_ep_ring_inc_index(ring); + el = &ring->ring_cache[ring->rd_offset]; + } +} + +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir, + struct sk_buff *skb, size_t len, enum mhi_flags mflags) +{ + struct mhi_ep_chan *mhi_chan = (dir == DMA_FROM_DEVICE) ? mhi_dev->dl_chan : + mhi_dev->ul_chan; + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; + enum mhi_ev_ccs code = MHI_EV_CC_INVALID; + struct mhi_ep_ring_element *el; + u64 write_to_loc, skip_tre = 0; + struct mhi_ep_ring *ring; + size_t bytes_to_write; + void __iomem *tre_buf; + phys_addr_t tre_phys; + void *read_from_loc; + u32 buf_remaining; + u32 tre_len; + int ret = 0; + + if (dir == DMA_TO_DEVICE) + return -EINVAL; + + buf_remaining = len; + ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; + + mutex_lock(&mhi_chan->lock); + if (mhi_chan->skip_td) + skip_to_next_td(mhi_chan, ring); + + do { + /* Don't process the transfer ring if the channel is not in RUNNING state */ + if (mhi_chan->state != MHI_CH_STATE_RUNNING) { + dev_err(&mhi_chan->mhi_dev->dev, "Channel not available"); + ret = -ENODEV; + goto err_exit; + } + + if (mhi_ep_queue_is_empty(mhi_dev, dir)) { + dev_err(&mhi_chan->mhi_dev->dev, "TRE not available!\n"); + ret = -EINVAL; + goto err_exit; + } + + el = &ring->ring_cache[ring->rd_offset]; + tre_len = MHI_EP_TRE_GET_LEN(el); + if (skb->len > tre_len) { + dev_err(&mhi_chan->mhi_dev->dev, "Buffer size (%d) is too large!\n", + skb->len); + ret = -ENOMEM; + goto err_exit; + } + + bytes_to_write = min(buf_remaining, tre_len); + read_from_loc = skb->data; + write_to_loc = MHI_EP_TRE_GET_PTR(el); + + tre_buf = mhi_cntrl->alloc_addr(mhi_cntrl, &tre_phys, bytes_to_write); + if (!tre_buf) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to allocate TRE buffer\n"); + ret = -ENOMEM; + goto err_exit; + } + + ret = mhi_cntrl->map_addr(mhi_cntrl, tre_phys, write_to_loc, bytes_to_write); + if (ret) { + dev_err(&mhi_chan->mhi_dev->dev, "Failed to map TRE buffer\n"); + goto err_tre_free; + } + + dev_dbg(&mhi_chan->mhi_dev->dev, "Writing %d bytes", bytes_to_write); + memcpy_toio(tre_buf, read_from_loc, bytes_to_write); + + mhi_cntrl->unmap_addr(mhi_cntrl, tre_phys); + mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_write); + + buf_remaining -= bytes_to_write; + if (buf_remaining) { + if (!MHI_EP_TRE_GET_CHAIN(el)) + code = MHI_EV_CC_OVERFLOW; + else if (MHI_EP_TRE_GET_IEOB(el)) + code = MHI_EV_CC_EOB; + } else { + if (MHI_EP_TRE_GET_CHAIN(el)) + skip_tre = 1; + code = MHI_EV_CC_EOT; + } + + ret = mhi_ep_send_completion_event(mhi_cntrl, ring, bytes_to_write, code); + if (ret) { + dev_err(&mhi_chan->mhi_dev->dev, "Error sending completion event"); + goto err_exit; + } + + mhi_ep_ring_inc_index(ring); + } while (!skip_tre && buf_remaining); + + if (skip_tre) + skip_to_next_td(mhi_chan, ring); + + mutex_unlock(&mhi_chan->lock); + + return 0; + +err_tre_free: + mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_write); +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) { struct device *dev = &mhi_cntrl->mhi_dev->dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 260a181d3fab..a7715f8066ed 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -274,4 +274,16 @@ 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_direction dir); +/** + * mhi_ep_queue_skb - Send SKBs to host over MHI Endpoint + * @mhi_dev: Device associated with the channels + * @dir: DMA direction for the channel + * @skb: Buffer for holding SKBs + * @len: Buffer length + * @mflags: MHI Endpoint transfer flags used for the transfer + * + * 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, enum dma_data_direction dir, + struct sk_buff *skb, size_t len, enum mhi_flags mflags); #endif From patchwork Thu Dec 2 11:35:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520271 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 0947DC433F5 for ; Thu, 2 Dec 2021 11:38:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357519AbhLBLmR (ORCPT ); Thu, 2 Dec 2021 06:42:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357493AbhLBLlz (ORCPT ); Thu, 2 Dec 2021 06:41:55 -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 230D5C0613DD for ; Thu, 2 Dec 2021 03:38:33 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id b13so20044767plg.2 for ; Thu, 02 Dec 2021 03:38:33 -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=xf7vNFLWq8MuNmvFYkwL5H5mINaB3lxvdk/G5WOR8Gg=; b=D1z/V+8MMQDxyoN2M35VASNVJP9x3lMl5IRFA4u+hg+RB/miQQxxDGB08l2A+MzlnR 1H9kesEvlkZ5tz2oR2e1PSIH+aPHoAcM4r974E+SG+OrTvf0NZEM/A9QZcVdjS+kJPM8 zXpfA4gvOohyA8xJU8aJqqku22RmWgL4vJiDh52eSrKcLBoST2DZXqP4IPLfDGVfeAm9 UK8HhSOyEfKNA5nvpGHxWocdz3sep3cBhCwawMsIackHktEc5xcn00CvqZZHZIqBGl3F FZTZBdKCpVZz19/HA2TFmTgZfeWmeA2d+N1RCezTwVUhmfJkyLKxROzDCJrwJxr/IwNU tefQ== 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=xf7vNFLWq8MuNmvFYkwL5H5mINaB3lxvdk/G5WOR8Gg=; b=QKdsJOOjFPfj01SODzupB8GNBWlx+Z93Sjea3W5CPGCz8ygx2Ebh8YhqlWzw0k2m2C V3WvnoCuS0286Q9STlkhCTjQP5v5s4H6HmQ9zXig6SRzi04h7LoIBx6LSTvEu9YSkTlm OfgXTa4T3cDbzsWL2HpfP4QVspejD1y30xDpPmc++JU4xPTgY4wO2wnDuWedopoSmO90 bbM/qZhkI553pQPTDSpuWFkQ/fuBeswQ56xaMZbJs3X7C+xJ621bKS373a7vLpV9AIoZ j6vGKpRCbrNqEisQjuGaJ96bROrMRz+1F6Pn2ZFVr9N7pqcA2EK//F5UhopjyNWwyl0K G2Rw== X-Gm-Message-State: AOAM5305vh66SxSTHEY2Uy1tbxDa/TD2CK6pJ7frkXsTuMM5NVmI5dbk 0y3KMBR39aULHz6j7bV5Pnyh X-Google-Smtp-Source: ABdhPJwpdux3KkMAAG5uf/v+7/HBi88ktJA9WdlbO3bZ5Kpm5g4dqOD2VIMsIRF1d3YVz21WZBUc9A== X-Received: by 2002:a17:90a:1a55:: with SMTP id 21mr5390733pjl.240.1638445112581; Thu, 02 Dec 2021 03:38:32 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:32 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 19/20] bus: mhi: ep: Add support for suspending and resuming channels Date: Thu, 2 Dec 2021 17:05:51 +0530 Message-Id: <20211202113553.238011-20-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. 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 | 4 +++ 3 files changed, 64 insertions(+) diff --git a/drivers/bus/mhi/ep/internal.h b/drivers/bus/mhi/ep/internal.h index 70626ef3799d..e0c36346c5b8 100644 --- a/drivers/bus/mhi/ep/internal.h +++ b/drivers/bus/mhi/ep/internal.h @@ -231,5 +231,7 @@ 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); #endif diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index cc3da846ed36..930b5c2005d0 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1176,6 +1176,64 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_down); +void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_chan *mhi_chan; + u32 tmp; + int i; + + for (i = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &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 = mhi_cntrl->ch_ctx_cache[i].chcfg; + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != 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 &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_SUSPENDED << CHAN_CTX_CHSTATE_SHIFT); + mhi_cntrl->ch_ctx_cache[i].chcfg = 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 = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &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 = mhi_cntrl->ch_ctx_cache[i].chcfg; + if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != 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 &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_RUNNING << CHAN_CTX_CHSTATE_SHIFT); + mhi_cntrl->ch_ctx_cache[i].chcfg = tmp; + mutex_unlock(&mhi_chan->lock); + } +} + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); diff --git a/drivers/bus/mhi/ep/sm.c b/drivers/bus/mhi/ep/sm.c index 50378b9f7300..0bef5d808195 100644 --- a/drivers/bus/mhi/ep/sm.c +++ b/drivers/bus/mhi/ep/sm.c @@ -93,8 +93,11 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl) enum mhi_state old_state; int ret; + /* If MHI is in M3, resume suspended channels */ spin_lock_bh(&mhi_cntrl->state_lock); old_state = mhi_cntrl->mhi_state; + if (old_state == MHI_STATE_M3) + mhi_ep_resume_channels(mhi_cntrl); ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0); if (ret) { @@ -140,6 +143,7 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl) } spin_unlock_bh(&mhi_cntrl->state_lock); + mhi_ep_suspend_channels(mhi_cntrl); /* Signal host that the device moved to M3 */ ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3); From patchwork Thu Dec 2 11:35:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 520270 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 0B8FCC433EF for ; Thu, 2 Dec 2021 11:39:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233370AbhLBLmc (ORCPT ); Thu, 2 Dec 2021 06:42:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357551AbhLBLmA (ORCPT ); Thu, 2 Dec 2021 06:42:00 -0500 Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36FC4C0613F3 for ; Thu, 2 Dec 2021 03:38:38 -0800 (PST) Received: by mail-pf1-x431.google.com with SMTP id u80so27655042pfc.9 for ; Thu, 02 Dec 2021 03:38:38 -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=e4KnceHWSyh2zZH+Q5Ra1eL2F8m4VYDX4eTKiilrqSA=; b=do+Hl0B42RklfGnUs2hZSYbOmsjKoJnjw1NOQsA9pQQPd1/2iFfcp322ICIT1YyoU0 6xOGXB5NWZdW9siiWHjkMWIhmmEcD1dFfUOVO4WK3xh5jeSfO2JSm7YmyM3vrr+Jv+8H DTYPw9WuVfggJyAhasdKI3exFpguGq5+r92l+lWh2+ZICAHAcA5pAERGqvRZQZ2zLIyC EeGLURxApmv81TG2T2JCGuRwpVuOha9pbVPmIw8YieWrASs1LPiuaoMFXkrWTPZlcfNx AjXMCJhaOnR4RCSaVyP1gs4+uyG5pM9DYkNV8xo+xVpkqajvGNjiUlUNAe21JEjJrm/O oHUw== 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=e4KnceHWSyh2zZH+Q5Ra1eL2F8m4VYDX4eTKiilrqSA=; b=yjx8aEJ9P9d6K9ExWPOQ3bbSQxKgma2FDkjeCZLQ+GCZlc9CUE5WRtVGQFsVk6zVMZ 6WF5+r+HrljGb/2ZIRBiMRfUKsy2NpRz+QLukGgBpJjyWhnYBqrN8kxXjxAOXQPiVzqq S4Rw2LttokZ02a25TkcfHysJvo1m1uStqCD7PfduV3/cKwmd3n0D2+splMH3nn1Y2dRt Rc256OkX3qdEpbivpvsYjYDuJ4wY5rQOT/d21T9ljYXJbK54n5NAffQ3i3jdFoR+DS4B ecsQiUnfDLOZH03bULzx00A2QbrWmeSWCnqG3SrhIV5W310vxmWOcLdNZRO1oaVDxkDs ZkGw== X-Gm-Message-State: AOAM530j4gYxPYywRK1MOzQwfA6DqLzwlmayiJNxhdZlN3j5kial9Ski 4rTBugJ0N0jEWA6pUwiQadCj X-Google-Smtp-Source: ABdhPJx8BaztlDTuFsvAgCYst3hLcJqR7wBfJuRxnIHZsnq/AHZ+DFbUb7+SAk/kFqPhZANMhxXdBA== X-Received: by 2002:a65:4381:: with SMTP id m1mr9340248pgp.248.1638445117743; Thu, 02 Dec 2021 03:38:37 -0800 (PST) Received: from localhost.localdomain ([117.202.184.5]) by smtp.gmail.com with ESMTPSA id h5sm3602552pfi.46.2021.12.02.03.38.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Dec 2021 03:38:37 -0800 (PST) From: Manivannan Sadhasivam To: mhi@lists.linux.dev Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org, quic_jhugo@quicinc.com, vinod.koul@linaro.org, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, skananth@codeaurora.org, vpernami@codeaurora.org, vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Manivannan Sadhasivam Subject: [PATCH 20/20] bus: mhi: ep: Add uevent support for module autoloading Date: Thu, 2 Dec 2021 17:05:52 +0530 Message-Id: <20211202113553.238011-21-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> References: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org 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. 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 930b5c2005d0..42470d2a82b8 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1619,6 +1619,14 @@ void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv) } EXPORT_SYMBOL_GPL(mhi_ep_driver_unregister); +static int mhi_ep_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); + + return add_uevent_var(env, "MODALIAS=" 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 = to_mhi_ep_device(dev); @@ -1645,6 +1653,7 @@ struct bus_type mhi_ep_bus_type = { .name = "mhi_ep", .dev_name = "mhi_ep", .match = mhi_ep_match, + .uevent = mhi_ep_uevent, }; static int __init mhi_ep_init(void) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index ae2e75d15b21..a85d453ebf67 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 +#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 49aba862073e..90cda36f3159 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1380,6 +1380,15 @@ static int do_mhi_entry(const char *filename, void *symval, char *alias) return 1; } +/* 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; +} + static int do_auxiliary_entry(const char *filename, void *symval, char *alias) { DEF_FIELD_ADDR(symval, auxiliary_device_id, name); @@ -1496,6 +1505,7 @@ static const struct devtable devtable[] = { {"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},