From nobody Mon Sep 28 21:03:42 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7CE53F5BF0 for ; Mon, 17 Aug 2026 10:14:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961687; cv=none; b=qHYguKNlXupag83HKtSu2w0m9Qk+QSnEsuMxgPAZWEwuubGgb8PDTRhMbo12Nok175k4Q8gsmxa0aiX4xqlPiIilPiDR/gf1HhGwp8wZtB3bRttPNnK/vQs8fS6H5z0US/NiMoh9zUfzSgZMfvpy70LnWg7z4JtBL1hAXfalZlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961687; c=relaxed/simple; bh=6242R4pzFL7r/tqFjb1Hk8gsb/XCavnRon8/YLzIeJM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UL4UWkKh5UXxLGMFb7yBo/u6RcCTilvaDCwfGb1/KF5QdsIQOs+UrpgPa0d/iVY1+djwAM2vfQdudciOxlA2bVtLhYs3qmKROqxD99n8WlgOC5emFstCJx9SqPzJvkiW3q7VGF4Zml4twDjWkU4/09C53atJ50kRNHCBui2FGAk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=aJ11wiCz; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=OhjcNg0Z; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="aJ11wiCz"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="OhjcNg0Z" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9dgRs1542188 for ; Mon, 17 Aug 2026 10:14:44 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= yTbaB+z5Yseh105+ajN8GEITb3BhA9qwqXWhIlbOb/0=; b=aJ11wiCz+MS3ypke YupEiIf6/Rx3i0Y8H2eQXrVCJtnOo0oovjHheWjMEYu5AtWlyssIr4jV97/kvjVb ZaYUirrxKnIKjGYuDyFYg828t3w5tnx9sRO+n2WEbYPgaEuSRaOVgclRBq0SDWrD t5/RT7FCICQi/yaabjuWIqP0Fny8sDh0vQJPteVBC+sdSYQnbJFpdbkWczMovB7H JRdQZvLST9BRXQjKrI/y2LF9PVXbaAV+9/rKNhRxFIgj6ANmJZ3OXhnYbFLZ6Wb+ m8YQRB6F86K165mg+YHG/G4hXvAMkSzl0jy8Wkd9F2d8vk3cYr8XZ7WCb5dsGCcj kKUWTA== Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3xw8gcse-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:14:43 +0000 (GMT) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-cb4bd11ddf8so4463961a12.3 for ; Mon, 17 Aug 2026 03:14:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786961683; x=1787566483; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=yTbaB+z5Yseh105+ajN8GEITb3BhA9qwqXWhIlbOb/0=; b=OhjcNg0Zsmwb/CXURyHUABpqOAdkaHH37yEa0fgZE4+R4KaM5ZvtrB79Ubisi6Zcn1 99KbTdM4tTVyQaqWJiv1uvX/kV8UyrVR6OPJurnQxXHbKKSqQsSoSlMfNOj9iSU+7ZH8 jftXpoKf1DKu7znekL0Ot4KBOOhfsV6b24bk14KSZUTLO5wcuqPwnI/hss/Edo9jiQZX PUCTzos3cW41lCgDyB9wOIdAiE8IJLDSRwYz6xc16l8CVO3oE+YmBa7rcUz20y3J/RDN MEiJ7q2mm5LSJUAQmlVHFY+eKizDZzfwEHaaE/+USJqP6p3S4qDTfBWN/hoE6e/92ZNB mi4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786961683; x=1787566483; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=yTbaB+z5Yseh105+ajN8GEITb3BhA9qwqXWhIlbOb/0=; b=AGa6RWUQkckHLkY/7COOtSP1Vnxoq+rT9sioP2DC/RSw4wqW2PFuMnOa0LpyauIwBY ezBLCZXNf4613hn21u4fk47l3iwoXvgiJcJJ5PkyqXXUGsxURQuyfkTUZN7C9U/iTkqf 4j0m9JEegfx26hOiDFxtgQgkCqQTHejbABq4l9rs3qXDttlkdzb9BY+810VAMpzFCPia lSqNZlSvNjyIx6uEpSXnQCzXlsyoWSrMFxqxk2wFbijyOCNXpBNPLhDS/F1Vi9HPh3G+ xq/AzrDXk121ZOGS83h/1aS62Mo1K+RhThUDfuUzoFJ4qFInmDp91bYizu038EP/ccru W+8w== X-Forwarded-Encrypted: i=1; AHgh+RoxbVOEzvBQTQDaX6c7eBGCA7YTvsLKVGJV0ShMKGgJYrFb4XsO5Kadcb+gAL71A0TN0QXhTCp5SVJkPL0=@vger.kernel.org X-Gm-Message-State: AOJu0Yz6sJeZcXedbn7T94bVkQc6O+7uIDhFdaRr20ZigLoMlJyaFmgC nFZdq9Ns4HBNObFJSOI1axr4fkh3OKzKc7ARQhQv9a1qUjt0Djtn3D3B4MJJOTbAJ3YPJwB1TU/ Ffzv80TZzymH4qLd6OQ4LyNXqYJjKvQKYE3buG6GbaSh7CW8QIh6J6zBkad7zTygkkfQv3KAy4y o= X-Gm-Gg: AR+sD13lTlJJNqZdUr4MhQXDO2bWATWfM2JxTBFpbYOXVVHnhHOBOlA52Xekspeb5NS jE67NmcVsHQxHsnHOWirgqYx1keqnGJMbtIwBQx9K7PtFaavi4xUIH2qHdKiLdmZIIHhvGMk1TT /G3VI0OuJbL/cmq5z8+h41yO/FO4SzOrtoyBb5XUeG8fMOkF7bhqhgJhXLDNY3KKIwxNekB6rrt vf+N1gh2FkLXD68+ZqEGlJLI7mYMSjz1R6aUhndGT1bEoCLEEPGZIqt7eUxswGlXBhxnDFHp6i/ SPlxgRpzNyeluaWaw58ZyIgAE+Dn3uf42Lblew2B0uqlaL2gBDVETIxsukEuiyVdCCK3gczM6o3 W4uYiDSnNIikWB+fDRQW6lowaYA== X-Received: by 2002:a17:90b:4d08:b0:37f:c22a:c188 with SMTP id 98e67ed59e1d1-3933b6f0622mr23595405a91.4.1786961682496; Mon, 17 Aug 2026 03:14:42 -0700 (PDT) X-Received: by 2002:a17:90b:4d08:b0:37f:c22a:c188 with SMTP id 98e67ed59e1d1-3933b6f0622mr23595346a91.4.1786961681828; Mon, 17 Aug 2026 03:14:41 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3954d3d2adcsm1744315a91.17.2026.08.17.03.14.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:14:41 -0700 (PDT) From: Sumit Kumar Date: Mon, 17 Aug 2026 15:44:34 +0530 Subject: [PATCH v5 1/3] bus: mhi: host: clients: Add loopback driver with sysfs interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260817-loopback_mhi-v5-1-50efc7360b7f@oss.qualcomm.com> References: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> In-Reply-To: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> To: Manivannan Sadhasivam , Jeff Hugo Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar , Krishna Chaitanya Chundru X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786961675; l=14334; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=6242R4pzFL7r/tqFjb1Hk8gsb/XCavnRon8/YLzIeJM=; b=8H68ii6iQDydZl4GwH7JaNP/j6O90+9yS30DEbxuL+1oqrKM//Ej7vTAUvnZGFmxxY7WF7Jgz Q5Zu5t6tQ3iD66SdB3YtwCKlhc3qXu5eLnIosL1tQldjobMO3YtIE5C X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-GUID: 54pIOPYY8rCM77Wu_d-NUQNoe_2eJpcP X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfX1gvoOr5t0Fxw p+gIfw/BAAnrgoXFTzPu2NMWrzYrer+kvHTU/luV5UOSwhuxv56EgCvqtC7szPn04G4fFSE5KzZ oDuO9ScZ7BwPzCnFU1o7HK2UCBee0uo= X-Authority-Analysis: v=2.4 cv=SuCgLvO0 c=1 sm=1 tr=0 ts=6a82df13 cx=c_pps a=rz3CxIlbcmazkYymdCej/Q==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=lEU7m922GBS3jRTx-gMA:9 a=QEXdDO2ut3YA:10 a=bFCP_H2QrGi7Okbo017w:22 X-Proofpoint-ORIG-GUID: 54pIOPYY8rCM77Wu_d-NUQNoe_2eJpcP X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfX2mgnH1tpto5d 6rgN8QIWjz/CQJW4KdmG4C9tx1D0zfWzZ3Kq9K7EmIN0CnUHrxlXODY+ad+pqg8PLiBTG0AkZv/ xvnrpOu6cGTsxvFQnJS/0g7c5RZy9nF3v7D7IZ6BZwku5RNifQzBTchnlsyMfFVa9ipHg6LwSh3 jffGLh6l0kDQcd0yXtU3Pnkk/46BteHVzfJBlTxDMIwPKfQlVREFR7NrGl9hRLpzrt9FQQh4oHc 5LOkSX3siCyn472BSe5c94yDIvz4Q9KtowcZBYTfVogPUHNzIU5+LGc13RRvfls9PWojxjyD4fO /qLkdt9LJiCywyblPMlIXKCdIh7ByrXAX3yieXApBR1i2O/srsJ7x7bi6l70wUSMTOm9MCVuzNp 7IiJKHr+zBb/C8N90hCL1+5bYti2UqjM4kMB9ND6lfGmLCkA9P7KwKE+JMe8jOflntchwPyF2F2 YZ2XvfzBvpZA6MCdiiA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 priorityscore=1501 phishscore=0 clxscore=1015 impostorscore=0 lowpriorityscore=0 suspectscore=0 adultscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170075 The MHI specification defines a LOOPBACK channel. The endpoint firmware echoes back whatever the host sends on this channel. Without a host-side driver, there is no way to exercise this channel to validate MHI data path integrity between host and endpoint. Add a host-side loopback driver that binds to the LOOPBACK channel and expose a sysfs interface for data path testing. The sysfs interface allows users to configure TRE buffer size and count, trigger a loopback test, and read the result. Co-developed-by: Krishna Chaitanya Chundru Signed-off-by: Krishna Chaitanya Chundru Signed-off-by: Sumit Kumar --- .../ABI/testing/sysfs-bus-mhi-devices-loopback | 39 +++ MAINTAINERS | 1 + drivers/bus/mhi/host/Kconfig | 1 + drivers/bus/mhi/host/Makefile | 1 + drivers/bus/mhi/host/clients/Kconfig | 17 ++ drivers/bus/mhi/host/clients/Makefile | 2 + drivers/bus/mhi/host/clients/loopback.c | 289 +++++++++++++++++= ++++ 7 files changed, 350 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback b/Doc= umentation/ABI/testing/sysfs-bus-mhi-devices-loopback new file mode 100644 index 0000000000000000000000000000000000000000..1622a146110c2069c8b51e5bdf6= 65c882b853303 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback @@ -0,0 +1,39 @@ +What: /sys/bus/mhi/devices/mhi_LOOPBACK/tre_size +Date: August 2026 +KernelVersion: 7.2 +Contact: mhi@lists.linux.dev +Description: + (RW) Size of each Transfer Ring Element (TRE) buffer in bytes + used for the loopback test. Valid range is 1 to the value + reported by max_tre_size. Default value is 32 bytes. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/max_tre_size +Date: August 2026 +KernelVersion: 7.2 +Contact: mhi@lists.linux.dev +Description: + (RO) Maximum allowed TRE size in bytes. Reading this file + returns the upper bound for the tre_size attribute. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/num_tre +Date: August 2026 +KernelVersion: 7.2 +Contact: mhi@lists.linux.dev +Description: + (RW) Number of Transfer Ring Elements (TREs) to use per + loopback test. Must be greater than zero and must not exceed + the channel ring capacity. Default value is 1. + +What: /sys/bus/mhi/devices/mhi_LOOPBACK/start +Date: August 2026 +KernelVersion: 7.2 +Contact: mhi@lists.linux.dev +Description: + (WO) Write any value to trigger a loopback test. The driver + sends random data to the endpoint using the configured tre_size + and num_tre parameters, waits for the endpoint to echo it back, + and verifies the received data matches what was sent. + + This is a blocking write that returns when the test completes + or times out after 5 seconds. The write returns an error code + if the test fails or times out. diff --git a/MAINTAINERS b/MAINTAINERS index a4b89bd497ad5051c190025838e0e93d257ed061..098b12692140514da52565a3200= 801f5e24a43b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17469,6 +17469,7 @@ L: linux-arm-msm@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git F: Documentation/ABI/stable/sysfs-bus-mhi +F: Documentation/ABI/testing/sysfs-bus-mhi-devices-loopback F: Documentation/mhi/ F: drivers/bus/mhi/ F: drivers/pci/endpoint/functions/pci-epf-mhi.c diff --git a/drivers/bus/mhi/host/Kconfig b/drivers/bus/mhi/host/Kconfig index da5cd0c9fc620ab595e742c422f1a22a2a84c7b9..627c57948235aa52348179ae8b2= d0826ebaed01e 100644 --- a/drivers/bus/mhi/host/Kconfig +++ b/drivers/bus/mhi/host/Kconfig @@ -29,3 +29,4 @@ config MHI_BUS_PCI_GENERIC This driver provides MHI PCI controller driver for devices such as Qualcomm SDX55 based PCIe modems. =20 +source "drivers/bus/mhi/host/clients/Kconfig" diff --git a/drivers/bus/mhi/host/Makefile b/drivers/bus/mhi/host/Makefile index 859c2f38451c669b3d3014c374b2b957c99a1cfe..2a16008aeb38127494782bbff4e= 1656428d2b776 100644 --- a/drivers/bus/mhi/host/Makefile +++ b/drivers/bus/mhi/host/Makefile @@ -4,3 +4,4 @@ mhi-$(CONFIG_MHI_BUS_DEBUG) +=3D debugfs.o =20 obj-$(CONFIG_MHI_BUS_PCI_GENERIC) +=3D mhi_pci_generic.o mhi_pci_generic-y +=3D pci_generic.o +obj-y +=3D clients/ diff --git a/drivers/bus/mhi/host/clients/Kconfig b/drivers/bus/mhi/host/cl= ients/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..312a0b5a8e83b6ad7246453908b= d552841a89188 --- /dev/null +++ b/drivers/bus/mhi/host/clients/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MHI_BUS_LOOPBACK + tristate "MHI LOOPBACK client driver" + depends on MHI_BUS + help + MHI LOOPBACK client driver that binds to the MHI LOOPBACK channel + as defined in the MHI specification. The LOOPBACK channel is + implemented by MHI-based devices (modems, WLAN) in the field, where + the endpoint firmware echoes back whatever the host sends. + + This driver exposes a sysfs interface for testing MHI data path + integrity between host and endpoint. Users can configure the TRE + size and count, and trigger a loopback test. + + To compile this driver as a module, choose M here. The module + will be called mhi_loopback. diff --git a/drivers/bus/mhi/host/clients/Makefile b/drivers/bus/mhi/host/c= lients/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3811b6928f42b38f94b1167941c= f3b0fe512d32b --- /dev/null +++ b/drivers/bus/mhi/host/clients/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_LOOPBACK) +=3D mhi_loopback.o +mhi_loopback-y +=3D loopback.o diff --git a/drivers/bus/mhi/host/clients/loopback.c b/drivers/bus/mhi/host= /clients/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..02a952e8e01222cd8cb842c9f94= 90479df8ea2bd --- /dev/null +++ b/drivers/bus/mhi/host/clients/loopback.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MHI_LOOPBACK_DEFAULT_TRE_SIZE 32 +#define MHI_LOOPBACK_DEFAULT_NUM_TRE 1 +#define MHI_LOOPBACK_TIMEOUT_MS 5000 +#define MHI_LOOPBACK_MAX_TRE_SIZE (SZ_64K - 1) + +struct mhi_loopback { + struct mhi_device *mdev; + /* Serializes the sysfs attributes against a running test */ + struct mutex lb_mutex; + struct completion comp; + atomic_t tre_pending; + u32 num_tre; + u32 tre_size; +}; + +static ssize_t tre_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", loopback->tre_size); +} + +static ssize_t tre_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 val; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (val =3D=3D 0 || val > MHI_LOOPBACK_MAX_TRE_SIZE) + return -EINVAL; + + guard(mutex)(&loopback->lb_mutex); + loopback->tre_size =3D val; + + return count; +} +static DEVICE_ATTR_RW(tre_size); + +static ssize_t max_tre_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", MHI_LOOPBACK_MAX_TRE_SIZE); +} +static DEVICE_ATTR_RO(max_tre_size); + +static ssize_t num_tre_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + + return sysfs_emit(buf, "%u\n", loopback->num_tre); +} + +static ssize_t num_tre_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 val; + int el_num; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (val =3D=3D 0) + return -EINVAL; + + guard(mutex)(&loopback->lb_mutex); + + el_num =3D min(mhi_get_free_desc_count(loopback->mdev, DMA_TO_DEVICE), + mhi_get_free_desc_count(loopback->mdev, DMA_FROM_DEVICE)); + if (val > el_num) { + dev_err(dev, "num_tre (%u) exceeds ring capacity (%d)\n", val, el_num); + return -EINVAL; + } + + loopback->num_tre =3D val; + + return count; +} +static DEVICE_ATTR_RW(num_tre); + +static ssize_t start_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(dev); + u32 total_size, tre_count, tre_size; + int i, ret; + + guard(mutex)(&loopback->lb_mutex); + + tre_size =3D loopback->tre_size; + tre_count =3D loopback->num_tre; + total_size =3D size_mul(tre_count, tre_size); + + if (total_size > KMALLOC_MAX_SIZE) + return -EINVAL; + + if (tre_count > mhi_get_free_desc_count(loopback->mdev, DMA_TO_DEVICE) || + tre_count > mhi_get_free_desc_count(loopback->mdev, DMA_FROM_DEVICE))= { + dev_err(dev, "Not enough ring space for %u TREs\n", tre_count); + return -ENOSPC; + } + + void *recv_buf __free(kfree) =3D kzalloc(total_size, GFP_KERNEL); + if (!recv_buf) + return -ENOMEM; + + void *send_buf __free(kfree) =3D kzalloc(total_size, GFP_KERNEL); + if (!send_buf) + return -ENOMEM; + + get_random_bytes(send_buf, total_size); + + atomic_set(&loopback->tre_pending, tre_count); + reinit_completion(&loopback->comp); + + for (i =3D 0; i < tre_count; i++) { + ret =3D mhi_queue_buf(loopback->mdev, DMA_FROM_DEVICE, + recv_buf + (i * tre_size), tre_size, MHI_EOT); + if (ret) { + dev_err(dev, "Unable to queue read TRE %d: %d\n", i, ret); + if (atomic_sub_and_test(tre_count - i, &loopback->tre_pending)) + complete(&loopback->comp); + return ret; + } + } + + for (i =3D 0; i < tre_count - 1; i++) { + ret =3D mhi_queue_buf(loopback->mdev, DMA_TO_DEVICE, + send_buf + (i * tre_size), tre_size, MHI_CHAIN); + if (ret) { + dev_err(dev, "Unable to queue send TRE %d: %d\n", i, ret); + return ret; + } + } + + ret =3D mhi_queue_buf(loopback->mdev, DMA_TO_DEVICE, + send_buf + (i * tre_size), tre_size, MHI_EOT); + if (ret) { + dev_err(dev, "Unable to queue final TRE: %d\n", ret); + return ret; + } + + if (!wait_for_completion_timeout(&loopback->comp, + msecs_to_jiffies(MHI_LOOPBACK_TIMEOUT_MS))) { + dev_err(dev, "Loopback test timed out\n"); + /* Reset the channel to reclaim the TREs still pointing at the buffers */ + mhi_unprepare_from_transfer(loopback->mdev); + ret =3D mhi_prepare_for_transfer(loopback->mdev); + if (ret) + dev_err(dev, "Failed to re-prepare channel for transfers: %d\n", ret); + + return -ETIMEDOUT; + } + + if (memcmp(send_buf, recv_buf, total_size)) { + dev_err(dev, "Loopback data mismatch\n"); + return -EIO; + } + + return count; +} +static DEVICE_ATTR_WO(start); + +static void mhi_loopback_dl_callback(struct mhi_device *mhi_dev, + struct mhi_result *mhi_res) +{ + struct mhi_loopback *loopback =3D dev_get_drvdata(&mhi_dev->dev); + + if (mhi_res->transaction_status && mhi_res->transaction_status !=3D -ENOT= CONN) + dev_err(&mhi_dev->dev, "DL callback error: status %d\n", + mhi_res->transaction_status); + + if (atomic_dec_and_test(&loopback->tre_pending)) + complete(&loopback->comp); +} + +static void mhi_loopback_ul_callback(struct mhi_device *mhi_dev, + struct mhi_result *mhi_res) +{ + if (mhi_res->transaction_status && mhi_res->transaction_status !=3D -ENOT= CONN) + dev_err(&mhi_dev->dev, "UL callback error: status %d\n", + mhi_res->transaction_status); +} + +static struct attribute *mhi_loopback_attrs[] =3D { + &dev_attr_tre_size.attr, + &dev_attr_max_tre_size.attr, + &dev_attr_num_tre.attr, + &dev_attr_start.attr, + NULL, +}; + +static const struct attribute_group mhi_loopback_group =3D { + .attrs =3D mhi_loopback_attrs, +}; + +static int mhi_loopback_probe(struct mhi_device *mhi_dev, + const struct mhi_device_id *id) +{ + struct mhi_loopback *loopback; + int ret; + + loopback =3D devm_kzalloc(&mhi_dev->dev, sizeof(*loopback), GFP_KERNEL); + if (!loopback) + return -ENOMEM; + + loopback->mdev =3D mhi_dev; + loopback->tre_size =3D MHI_LOOPBACK_DEFAULT_TRE_SIZE; + loopback->num_tre =3D MHI_LOOPBACK_DEFAULT_NUM_TRE; + + mutex_init(&loopback->lb_mutex); + init_completion(&loopback->comp); + + dev_set_drvdata(&mhi_dev->dev, loopback); + + ret =3D mhi_prepare_for_transfer(mhi_dev); + if (ret) { + dev_err(&mhi_dev->dev, "Failed to prepare for transfers: %d\n", ret); + return ret; + } + + ret =3D sysfs_create_group(&mhi_dev->dev.kobj, &mhi_loopback_group); + if (ret) { + dev_err(&mhi_dev->dev, "Failed to create sysfs attributes: %d\n", ret); + mhi_unprepare_from_transfer(mhi_dev); + return ret; + } + + return 0; +} + +static void mhi_loopback_remove(struct mhi_device *mhi_dev) +{ + /* Blocks until any in-progress store() has returned */ + sysfs_remove_group(&mhi_dev->dev.kobj, &mhi_loopback_group); + mhi_unprepare_from_transfer(mhi_dev); +} + +static const struct mhi_device_id mhi_loopback_id_table[] =3D { + { .chan =3D "LOOPBACK"}, + {} +}; +MODULE_DEVICE_TABLE(mhi, mhi_loopback_id_table); + +static struct mhi_driver mhi_loopback_driver =3D { + .probe =3D mhi_loopback_probe, + .remove =3D mhi_loopback_remove, + .dl_xfer_cb =3D mhi_loopback_dl_callback, + .ul_xfer_cb =3D mhi_loopback_ul_callback, + .id_table =3D mhi_loopback_id_table, + .driver =3D { + .name =3D "mhi_loopback", + }, +}; + +module_mhi_driver(mhi_loopback_driver); + +MODULE_AUTHOR("Krishna Chaitanya Chundru "); +MODULE_AUTHOR("Sumit Kumar "); +MODULE_DESCRIPTION("MHI Host Loopback Driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Mon Sep 28 21:03:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE91B3DA5DA for ; Mon, 17 Aug 2026 10:14:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961689; cv=none; b=SgN+8ru+w/c6H5MQws+raOjRNUTvE4UW2wfKb0GRoOTrgsqi4p9hjb/gTSDP353NqkuBEVF6Hs+LdFjsfQ+C+4rdRjPL7wNrLfqL9TAGS0O+uRoNmW+U17jJLyuIw4QQmSbm8dsbs/csox0dF9LEJbsL3SMUafIbXTtl0GePHrM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961689; c=relaxed/simple; bh=ApMUAuZs3L2v5RzHWa7346il7lYG55ETS5DCt1UhV9I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bRSUFTQqdNxYB16fLVCwYFqtiYe5uEMkp0o7xoafL1Feb6y9k7Y3ulD6s4ebwjZFNztnu1WyO75j2a96pZL58AHIyh/KUrzbwdCYAPqLB74qFdMY+B7eJeyHpERoSR4/G1KjbCB2hXpYCpnHC1PbcgtnRs5B6OMrtmb5+i6KR7Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=LUoZz0O4; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=HXHspIk6; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="LUoZz0O4"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="HXHspIk6" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9ddt71058307 for ; Mon, 17 Aug 2026 10:14:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= s08t3lOMFf+kNQ18LHM3sQsH9kbgW1CP2CV275SRJLM=; b=LUoZz0O43HuxfbdA 5RdfhAqWVwvHtWOYuCn9rzCcJ8VxcH+Ilmp6GbqDHbEp3GgMl+RH/Vz4rCrWXD+b Q2Dp/ngTGUoUyB0ZIv1tHpDr5TjDcTYaCaIWlzQCaBumu7IAeIToSjeYJmsUsMW+ htLySgYC7CeIZNF8s+bLn+Qs+qpR2Yu9/ENbiwZF6CgXMQOd/JeovkJsEN3XY9gV Ug5HXnVnUFztllhqRWtHmIaqxKx1RsPxbGpi+9UUkvxqQt9Pl/T71DvkyZx9Br4c CYoGs1C7kVDf4hO4Da4NN/hZRDgVsZYDWbMrgt0mk4HRnUzyp11xbxojmrh7psYn 2qNFJQ== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3x30gk1c-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:14:46 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38dc085b0a7so6082700a91.2 for ; Mon, 17 Aug 2026 03:14:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786961685; x=1787566485; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=s08t3lOMFf+kNQ18LHM3sQsH9kbgW1CP2CV275SRJLM=; b=HXHspIk6EhxfWLoU0NJAq8wrU6SovCeprIlyoGdSAynG2rmMn4mwNeJSRsX8V1LNOx XnABST+p+53oSnZgUDpK01V9EHiGJsei3xSbENBIWprOhZygBth5B+fQcqfMOJeE4T9m NqNsreBLVBa/9yDhcMyAUofQCAQOwEDFdqou52ykz8L/q8Wh1A1mIPX1kx6smCE8JQnN WTdu35/GyWE4njTBGDWPLv6Bppc+pdlsXm0HzasB5J5ltNBOyLTKxHnSMCiBQhr5iAxn W2vMZNLrJhGc1QTUJUaEgyNbKDIsgXeXfKS5KmZZLVi8kqXtrIvT0QdWYKoohdjQL9Ad LAjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786961685; x=1787566485; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=s08t3lOMFf+kNQ18LHM3sQsH9kbgW1CP2CV275SRJLM=; b=Inje+5C6eVFgeYZMHLxIHxQ9puKZdvK38m1pbOGRvewePS3BxSH2Y2u6dqSd9BXdiJ nIv1NTlORtM+U2UJ/V9mXX4QRaOyPyFbByHjVBvMDL5x5kdhnUEJIAGa07LB17bLGMEI X9qF5/MxW4Rtwk3KqcOqkLCVI5+jqxw0uilOw76xQXROp2PatZdFHn+3tUWReaKvd6l8 KM964KSe2unlXkwXw978KnAGr8ibIVnbJ0Mi8V+j2PosaCw+BYKTLJcbutXdTl6eKjEw /9gbtHj/poni+yqRs+O1pHO9+BRFK1QVHi3kdZAW4B93IZfafFxZRvwPV1dIu8LhIqbh sOZQ== X-Forwarded-Encrypted: i=1; AHgh+Rp5orZ4PmZjOTiIsWyEh0xp3wm8c6Ua1DDitQ98Q+uX57jg3FW5D6H+fZmEhv1ertWJ7P0sMlxCDkRLcQA=@vger.kernel.org X-Gm-Message-State: AOJu0YxsTVksz3WYa6U2yFq7gupoQEFgqVui+1obYaaLx5xd0SN0jCP/ X3x6RtLSVo5/2cJIPYoeJ8mTqd00GMdQHHjFtApypzynZaG1A3k7q36xgRwGerIvL/5FpS6Xw7i TzY6BTAYXLbY8v7lobRkRqV/iPRL2MtFcnpZc8W2A9zFbJOHMwnMsYSLromq4bcC18Vo9t3ygOy 0= X-Gm-Gg: AR+sD121Brp/j9d0SQIyCOUjCzqHVJW9QJXN83tpnveJcsiN8bYg7KVuc+Jpb8sYbjY 383o1vYhUcgMzhMvu6GbiCcbOD5CYWCdqe1V05rYxk3uLoSX1PFyuRF87rYjgxQZRd1OWzXyJaa 93N/YD0DSrXrQnfJtpYeGxWvJI3ogMqTJNQaIcO+5PjecCthrXdxmh5H8AnrttUtnj54Jay9I7O Q6Xw1AIKhjQ5pZV13tujGU01f6KxAljevznrddIy+ucjdCwF+N+V2VoqWoYrmJT7QjFuuyavONd ewXkgWlSZQOo+24YKGx+DZu/86TrBMYbPl7vLSgiSG4a72IL+6dmQN265xbh+gkRcLBlku+9T34 HQ6RGd89DcOSRzoVpSdDlJUBx+A== X-Received: by 2002:a17:90b:2f0d:b0:38e:7268:220d with SMTP id 98e67ed59e1d1-3933ed5e238mr26276646a91.20.1786961685353; Mon, 17 Aug 2026 03:14:45 -0700 (PDT) X-Received: by 2002:a17:90b:2f0d:b0:38e:7268:220d with SMTP id 98e67ed59e1d1-3933ed5e238mr26276588a91.20.1786961684805; Mon, 17 Aug 2026 03:14:44 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3954d3d2adcsm1744315a91.17.2026.08.17.03.14.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:14:44 -0700 (PDT) From: Sumit Kumar Date: Mon, 17 Aug 2026 15:44:35 +0530 Subject: [PATCH v5 2/3] bus: mhi: ep: Add mhi_ep_queue_buf() API for raw buffer queuing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260817-loopback_mhi-v5-2-50efc7360b7f@oss.qualcomm.com> References: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> In-Reply-To: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> To: Manivannan Sadhasivam , Jeff Hugo Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786961675; l=4480; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=ApMUAuZs3L2v5RzHWa7346il7lYG55ETS5DCt1UhV9I=; b=t1VhTPN6kzGBpFfFaDq9P+GpbUSoTNNPt96OcLRkBbdB+qO5xEt10P9IafMXqPtGefWixkP2U GkiUlE3ZbEYCzWXObScFhi4FvoINKcxzpn+hXD89a5zbH4nYH3Bcre6 X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfX43ppBhvVcTfN hlknX4Y13mJ48VxELWoVH8/duCsUf5iPzmk5OiWIQIIpmhi5g0q8Uvs8QYcuUQ1Ft9akQfIisUd +AkjVEnNw6G3C6Tf5lM1DEknzEcsy5+VNoX8NIkR3pgKCRMQ61XzteUWwuDzHbHfm4Q/ny8CiMP dVryVbAl8lNObUrFusHTQ+nyL9NiDIVFUANOtVxKsZ3P3dG7loN6Qbq2Hc8znkXapl4FWkMwPmY GlrPv/q0NxaqLwQLtQjNk9DmYtKWGPWl1mZ0m5YreL4s5Ybs4HxYwG/qBABd+zgLwke8NUu851D XC73ukOT1yudl4+HK78D2nEzsulLD5QRMgHqTDRA8lFHWYNtEY0OoOdUOnCAMfZC1G3EC91/OaL iRnuZ3i8aKJhBYJ7wmAlAfx4WoxKCOshtA/QOyJ3Po6QWCiKmVgGsr9vj75F+0OgkXkNYAPkAFd TD7g/BCyQfWRWVTvV8A== X-Proofpoint-GUID: nv2RIipZu3L5qsyzH0wI2-gSWBIeApJN X-Proofpoint-ORIG-GUID: nv2RIipZu3L5qsyzH0wI2-gSWBIeApJN X-Authority-Analysis: v=2.4 cv=Y9/IdBeN c=1 sm=1 tr=0 ts=6a82df16 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=27Ti7_ZD70JoqEhemiIA:9 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfXwtyAuE27dwIi S1Hqf5IgAerDS0WGVhNGSsFtPmhLMJVymFqq2gbHTnSRyFQIw0RwiXLY3RD0YkMv70cFjKYf6xd FxTYAKonLJU+Dmc0Xf3lr9zMP6XVxpU= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 priorityscore=1501 impostorscore=0 clxscore=1015 bulkscore=0 malwarescore=0 phishscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170075 Some MHI endpoint clients do not use socket buffers and need a way to queue raw buffers for DL transfers. Add mhi_ep_queue_buf() to support this use case. Refactor mhi_ep_queue_skb() to delegate to a new internal mhi_ep_queue() helper shared by both APIs, and rename mhi_ep_skb_completion() to mhi_ep_buf_completion() to reflect its broader use. Signed-off-by: Sumit Kumar --- drivers/bus/mhi/ep/main.c | 29 ++++++++++++++++++++--------- include/linux/mhi_ep.h | 16 ++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 038b47158f0e0c905194779e24da1ad851e76061..7be1d3bbf5339156fee85d6b476= 03a5c8d46a8d5 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -505,7 +505,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *r= ing) return 0; } =20 -static void mhi_ep_skb_completion(struct mhi_ep_buf_info *buf_info) +static void mhi_ep_buf_completion(struct mhi_ep_buf_info *buf_info) { struct mhi_ep_device *mhi_dev =3D buf_info->mhi_dev; struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; @@ -533,22 +533,22 @@ static void mhi_ep_skb_completion(struct mhi_ep_buf_i= nfo *buf_info) =20 mhi_ep_ring_inc_index(ring); } - /* TODO: Handle partially formed TDs */ -int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) +static int mhi_ep_queue(struct mhi_ep_device *mhi_dev, void *buf, size_t l= en, + void *cb_buf) { struct mhi_ep_cntrl *mhi_cntrl =3D mhi_dev->mhi_cntrl; struct mhi_ep_chan *mhi_chan =3D mhi_dev->dl_chan; struct device *dev =3D &mhi_chan->mhi_dev->dev; struct mhi_ep_buf_info buf_info =3D {}; struct mhi_ring_element *el; - u32 buf_left, read_offset; + size_t buf_left, read_offset; struct mhi_ep_ring *ring; size_t tr_len; u32 tre_len; int ret; =20 - buf_left =3D skb->len; + buf_left =3D len; ring =3D &mhi_cntrl->mhi_chan[mhi_chan->chan].ring; =20 mutex_lock(&mhi_chan->lock); @@ -571,13 +571,13 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, s= truct sk_buff *skb) tre_len =3D MHI_TRE_DATA_GET_LEN(el); =20 tr_len =3D min(buf_left, tre_len); - read_offset =3D skb->len - buf_left; + read_offset =3D len - buf_left; =20 - buf_info.dev_addr =3D skb->data + read_offset; + buf_info.dev_addr =3D buf + read_offset; buf_info.host_addr =3D MHI_TRE_DATA_GET_PTR(el); buf_info.size =3D tr_len; - buf_info.cb =3D mhi_ep_skb_completion; - buf_info.cb_buf =3D skb; + buf_info.cb =3D mhi_ep_buf_completion; + buf_info.cb_buf =3D cb_buf; buf_info.mhi_dev =3D mhi_dev; =20 /* @@ -616,8 +616,19 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, st= ruct sk_buff *skb) =20 return ret; } + +int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb) +{ + return mhi_ep_queue(mhi_dev, skb->data, skb->len, skb); +} EXPORT_SYMBOL_GPL(mhi_ep_queue_skb); =20 +int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len) +{ + return mhi_ep_queue(mhi_dev, buf, len, buf); +} +EXPORT_SYMBOL_GPL(mhi_ep_queue_buf); + static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl) { size_t cmd_ctx_host_size, ch_ctx_host_size, ev_ctx_host_size; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index f6383a57a872bf3cdea236ae9fe65f4ec8747b3e..852f331f03fda5c0212585de7d6= f4eb9f8270609 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -304,4 +304,20 @@ bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_d= ev, enum dma_data_directio */ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb); =20 +/** + * mhi_ep_queue_buf - Transfer buffer contents to host over MHI Endpoint + * @mhi_dev: Device associated with the DL channel + * @buf: Buffer to be queued. On success, ownership passes to the MHI stac= k; + * the caller must not free @buf until the DL transfer callback fires + * with result->buf_addr equal to @buf. On failure, the caller retai= ns + * ownership and must free @buf. + * Note: if @len spans multiple host DL TREs, the DL transfer callba= ck + * fires once per TRE, each time with result->buf_addr equal to @buf. + * @len: Size of the buffer + * + * Return: 0 if the buffer contents have been transferred successfully, a + * negative error code otherwise. + */ +int mhi_ep_queue_buf(struct mhi_ep_device *mhi_dev, void *buf, size_t len); + #endif --=20 2.34.1 From nobody Mon Sep 28 21:03:42 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 281EC3F3279 for ; Mon, 17 Aug 2026 10:14:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961698; cv=none; b=VN3l8IJa9+HrEfUxucrQITYeW2leJMi1kK2zfSZCV1ViC2VvuhQ8DnAmOZole/ZuA/5USGwKaG7D75hAr/OQW+JlUSUAH8QcT6zQtvDywYsZPcBIrFXxfIoHl/f0M2M6gCajFbmDYVG00FtO57KUOGnAL6rZFKjpQTO/Y/nEybE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786961698; c=relaxed/simple; bh=XoQxJJ4G4Dr0ttKF9Uej+JnGlrI6hRsCj0OAR11OKhY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MmUyKewGZ5P9oSO2A2uNRJUqtuVKzPq/q7pJoYoyv2ioyK5CeQolD7xyC6zNaonIwXJ8GlkQAIJRKwU3RSrW9a6NZnWhuxS3Ssv8Ccw7XupnpWLx9xIh5hfYni4A+8u1JYLbNrhNeahMMqzVh8VfGWs5Ltj9jo1oBURaTfUph5Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=lMDBHQLm; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=exiyTiCv; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="lMDBHQLm"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="exiyTiCv" Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9dfXt2470492 for ; Mon, 17 Aug 2026 10:14:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=lMDBHQLmNyAMV7LZ ibaz7TogGOvP8C0SOFc4gJ8XLNL5l9Pu+gXOUPgdfJW//riKYXc1v62LBruxC5uh bT7j1wGo6s1bIkd2dGrDwPnUwRNmm1z6SsjqFCSuHw4WES8G8CZKLo2LttjCVC4P Yx6RSvqx5ncDmpIqLntqzHp5DJAJsb3GFDmZK+EWgLrFTU4yuvymyAaaA5Qa5BSB NF0htXkJGTQaNSgNJaWqxDJH77i+9VDvqkvNKBlOks5uYdBYj3jjmGv77713ukO0 W9kzYkN8b5AXVcaQ2TbF6QUV0XEXxzGRMzkiq/ZFxIAYuzWevOIAMS8Bhj7h+1ok TFO2qg== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3wm7rpv8-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:14:49 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-3950b1371a7so2777907a91.2 for ; Mon, 17 Aug 2026 03:14:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786961688; x=1787566488; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=exiyTiCvOi4AYYbmz197q3S60pleLGwCr52KImp4E9gJKvswFzDsbCqi9ySAI2G1EG gr5MIzDGDSYN1Qq5JuFgvChvZhhjKh0IfP2XjZA6Qscv0n8WuQiiNiOLr2c+YbIbW/T5 jF4szFDRGh7X2In1hdm7ly5dlkOdt0p6ZMjMwNcj/2XnbpOnMeZZeNDG/Wx+T6SowOD8 x0zq3UrwwH7wGfYyF97aTjfwBUtdYNWyk6HlmhKYRbeLSgjz53VW4h5Cea9WIpFBZGOp a8QtV1Of6t/+sREdbllKhSMsA77D+6elRX6IVOZWH90NmC0bW29Ov9+7vZtISooM5vy2 Mmmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786961688; x=1787566488; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=dX9CJTTi2Ly8+vgHI4D9jojeLGUDlkOkyBwFunQwNU4=; b=T+4SlIZ0XOfna22CMNaoJBKJHWMVzvgLFpIwgoUhJR8Vs1ArOk1byBYyjw3HAME9zF g1sVl83whsl6M9rrEC27r7UDRXT8kHHRfpA9RU+f+PXTyFzd4BAvg7xj1coyCe2f7AlX LdUZSZngMBDfc7WdYGGZeGsik1L+zHYQ7GngWXRpoppHCWk+Ffd8ES9PgsYkGOeDqKXP VaaHTa9q2hziO6d+wy/GQ2M5zSy4grbDAH6/+s0CK3AB+FxW6pdrFFvgB5dA6yvABvN3 bX0bTjFnn2RxYI4eneCYfuqGFX6zU0Q2RFqa/oGVjaGBf8PqPolv9JdHOAvi0rNCgwf+ 79cw== X-Forwarded-Encrypted: i=1; AHgh+Rrs8JmuZtRcrWj+DkCPEML7ebvpJ6RNU/4WpDSEFy+mwVHoZXBu0ituiVm1fQZpYt7yDfQFUPPVAUgT/hQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwUGxT3ZGHjV+1jZnnVO4DN+1I/8P1h5AVQPVMZ0NpxUa0sj4mU k9vzAGgPQpO0lqEqAXUJKKfMq4byEs3jLXI+r2NxRNZhWgHpqzbNj+u7n3HS+kDIjsFw/774uuU h1s9RcsPQZ7mel9jdUzUzXROu566zLvxIXY2WjxnnsrFJxC9PCwSLWLYqflCoBc8+y4Z/VYMs3X I= X-Gm-Gg: AR+sD11OLw1DReAwq4BBoLLIPp6pGmCxcI3UMYCUjmGJ4CKXlDVYMtjZXWdMQGd/0rf G5HzaeVtGxfNyOWue6wulw86w6FIRFRVprThm8Zvzs8LHo3qJ2EQE083yHSKC9ZAVzLmKkIwWqV Fv3tcfaWgyjKKHuDwqZoPjD4N/8+mswEogK3cR8vtJFK1AgJBcpKnTUU/KY4VaJ3r6Xh4nx0N6o DxtdMoGLxL7cOVUVCaicgKKOMO+WdO8C15Q+ydIvhdbTx/sZPWsd3I80tf/ppX1zQRvmP9wdI3f EufzK3U5vEOHDn8WP3YktlbARhW31LuEakNOZPzuaI7/jf5LZdnarkQpp5PK8/huNK5xD9yAdny VUu/t9MgCCGsTNjJuw1+apkoCXQ== X-Received: by 2002:a17:90b:1a87:b0:38e:57a3:f218 with SMTP id 98e67ed59e1d1-3933b956294mr24198935a91.13.1786961688426; Mon, 17 Aug 2026 03:14:48 -0700 (PDT) X-Received: by 2002:a17:90b:1a87:b0:38e:57a3:f218 with SMTP id 98e67ed59e1d1-3933b956294mr24198874a91.13.1786961687867; Mon, 17 Aug 2026 03:14:47 -0700 (PDT) Received: from hu-sumk-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3954d3d2adcsm1744315a91.17.2026.08.17.03.14.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:14:47 -0700 (PDT) From: Sumit Kumar Date: Mon, 17 Aug 2026 15:44:36 +0530 Subject: [PATCH v5 3/3] bus: mhi: ep: clients: Add loopback driver for data path testing Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260817-loopback_mhi-v5-3-50efc7360b7f@oss.qualcomm.com> References: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> In-Reply-To: <20260817-loopback_mhi-v5-0-50efc7360b7f@oss.qualcomm.com> To: Manivannan Sadhasivam , Jeff Hugo Cc: mhi@lists.linux.dev, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Sumit Kumar , Krishna Chaitanya Chundru X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1786961675; l=7186; i=sumit.kumar@oss.qualcomm.com; s=20250409; h=from:subject:message-id; bh=XoQxJJ4G4Dr0ttKF9Uej+JnGlrI6hRsCj0OAR11OKhY=; b=6lYGLte404UZocgwzJBcKpkiCEszoNVkI0+J2liHJMXrXMFxi9/XCW9WX0+3hPCgfG7r/uzLw DXGl81ZwcK3Cn5S7/s3MiV3bO5GioGST8Hp7E/n6AsA3eh6AJx7DFS1 X-Developer-Key: i=sumit.kumar@oss.qualcomm.com; a=ed25519; pk=3cys6srXqLACgA68n7n7KjDeM9JiMK1w6VxzMxr0dnM= X-Proofpoint-GUID: HIofiggv23HSWLkuGZmP-IN4hR-gDAQl X-Proofpoint-ORIG-GUID: HIofiggv23HSWLkuGZmP-IN4hR-gDAQl X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfXz2yLIzRpEa1A rhzPNGIzqm/lBKVqImTwNhfLpxqRUmUv6vDjAJegjWE1A/UJctPB2pQMC3aWEJ8iehYn2Y+te8R MwQ/fpl/H+QOriVYBskEPXswmy9l2+cHtrOxHy1uYzKTuPxXYR2z6WgPsKzlczbLmxggfx9GA8f xh7HhQM5imnX1LJscVqPAu62/NTYBhVOPUbx6HzqdFWRdW9r1IpLe5YElRurm1genuPulUhpolF F3CMJoiBfvHeymI6C6aZQ3EGmy1Fu/MffPQNBvdzlizTMCsreMWLzdE4xQkPkEbyw7GiFd4mG9m sb70a8okJk555jwqxvp3Gsul0DmG51l2XwsRvv6M0HHcMWsIiIfgsngvUA/qOx/qHk+srZIA1ly WLnh/o97YEfrNnrhBhhuJtSC362hItMleC6s8f1d1KzSbUcARRzZliuFfqNLxVI+stxHhM3ZeM8 mc3F8GcyD1f4zrwhYsw== X-Authority-Analysis: v=2.4 cv=YqM/gYYX c=1 sm=1 tr=0 ts=6a82df19 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=F9PWhn0UeK7EsyOwsFYA:9 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA3NSBTYWx0ZWRfX+Le7YweEeDb/ qvUoGZQESup/iOkyG4cHOiamWEYRcEpwEefMfPF3xvb70GoPJj0mHMae6kJ+qVUJFuD5UWNqQNa 5FQhUVjHMjrPL/PCtapHzHZ3kCAKypE= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 impostorscore=0 suspectscore=0 adultscore=0 clxscore=1015 bulkscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170075 When an MHI endpoint device runs Linux, there is no firmware to implement the LOOPBACK channel echo that real modem firmware provides. Without an endpoint-side driver, the host loopback test has no software echo partner and cannot exercise the full end-to-end MHI data path. Add an endpoint-side loopback driver that binds to the LOOPBACK channel and echoes received data back to the host. An ordered workqueue is used for asynchronous processing to preserve packet ordering. Together with the host-side loopback driver, this enables complete MHI data path validation for Linux-based endpoint devices. Co-developed-by: Krishna Chaitanya Chundru Signed-off-by: Krishna Chaitanya Chundru Signed-off-by: Sumit Kumar --- drivers/bus/mhi/ep/Kconfig | 2 + drivers/bus/mhi/ep/Makefile | 1 + drivers/bus/mhi/ep/clients/Kconfig | 16 +++++ drivers/bus/mhi/ep/clients/Makefile | 2 + drivers/bus/mhi/ep/clients/loopback.c | 130 ++++++++++++++++++++++++++++++= ++++ 5 files changed, 151 insertions(+) diff --git a/drivers/bus/mhi/ep/Kconfig b/drivers/bus/mhi/ep/Kconfig index 90ab3b040672e0f04181d4802e3062afcc7cf782..9edb81b39890e093a51138465a4= d7705767eafa5 100644 --- a/drivers/bus/mhi/ep/Kconfig +++ b/drivers/bus/mhi/ep/Kconfig @@ -8,3 +8,5 @@ config MHI_BUS_EP =20 MHI_BUS_EP implements the MHI protocol for the endpoint devices, such as SDX55 modem connected to the host machine over PCIe. + +source "drivers/bus/mhi/ep/clients/Kconfig" diff --git a/drivers/bus/mhi/ep/Makefile b/drivers/bus/mhi/ep/Makefile index aad85f180b707fb997fcb541837eda9bbbb67437..ab36ef2a40ab8174e5ddae44a3e= 6ccb8eb31168d 100644 --- a/drivers/bus/mhi/ep/Makefile +++ b/drivers/bus/mhi/ep/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MHI_BUS_EP) +=3D mhi_ep.o mhi_ep-y :=3D main.o mmio.o ring.o sm.o +obj-y +=3D clients/ diff --git a/drivers/bus/mhi/ep/clients/Kconfig b/drivers/bus/mhi/ep/client= s/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..4cf27184058ca2be020885b6f57= b4cc44b5054b6 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0 + +config MHI_BUS_EP_LOOPBACK + tristate "MHI Endpoint LOOPBACK client driver" + depends on MHI_BUS_EP + help + MHI Endpoint LOOPBACK client driver that binds to the MHI LOOPBACK + channel as defined in the MHI specification. The LOOPBACK channel is + implemented by MHI-based endpoint devices (modems, WLAN) in the field, + where the endpoint firmware echoes back whatever the host sends. + + This driver receives data on the uplink channel and echoes it back on + the downlink channel for testing the MHI endpoint data path. + + To compile this driver as a module, choose M here. The module + will be called mhi_ep_loopback. diff --git a/drivers/bus/mhi/ep/clients/Makefile b/drivers/bus/mhi/ep/clien= ts/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..71dc91cc63b02592b177cf66db6= 090748c0653a6 --- /dev/null +++ b/drivers/bus/mhi/ep/clients/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MHI_BUS_EP_LOOPBACK) +=3D mhi_ep_loopback.o +mhi_ep_loopback-y +=3D loopback.o diff --git a/drivers/bus/mhi/ep/clients/loopback.c b/drivers/bus/mhi/ep/cli= ents/loopback.c new file mode 100644 index 0000000000000000000000000000000000000000..18a92d6a40e0f7de277d155cdb5= 495d14a60c19d --- /dev/null +++ b/drivers/bus/mhi/ep/clients/loopback.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include + +struct mhi_ep_loopback { + struct workqueue_struct *wq; + struct mhi_ep_device *mdev; +}; + +struct mhi_ep_loopback_work { + struct mhi_ep_device *mdev; + struct work_struct work; + void *buf; + size_t len; +}; + +static void mhi_ep_loopback_work_handler(struct work_struct *work) +{ + struct mhi_ep_loopback_work *mhi_ep_lb_work =3D container_of(work, + struct mhi_ep_loopback_work, work); + int ret; + + ret =3D mhi_ep_queue_buf(mhi_ep_lb_work->mdev, mhi_ep_lb_work->buf, + mhi_ep_lb_work->len); + if (ret) { + dev_err(&mhi_ep_lb_work->mdev->dev, "Failed to queue buffer: %d\n", ret); + kfree(mhi_ep_lb_work->buf); + } + + kfree(mhi_ep_lb_work); +} + +static void mhi_ep_loopback_ul_callback(struct mhi_ep_device *mhi_dev, + struct mhi_result *mhi_res) +{ + struct mhi_ep_loopback *mhi_ep_lb =3D dev_get_drvdata(&mhi_dev->dev); + struct mhi_ep_loopback_work *mhi_ep_lb_work; + void *buf; + + if (!mhi_ep_lb) + return; + + if (!mhi_res->transaction_status) { + if (!mhi_res->bytes_xferd) + return; + + buf =3D kmemdup(mhi_res->buf_addr, mhi_res->bytes_xferd, GFP_KERNEL); + if (!buf) { + dev_err(&mhi_dev->dev, "Failed to allocate loopback buffer\n"); + return; + } + + mhi_ep_lb_work =3D kmalloc(sizeof(*mhi_ep_lb_work), GFP_KERNEL); + if (!mhi_ep_lb_work) { + dev_err(&mhi_dev->dev, "Failed to allocate loopback work\n"); + kfree(buf); + return; + } + + INIT_WORK(&mhi_ep_lb_work->work, mhi_ep_loopback_work_handler); + mhi_ep_lb_work->mdev =3D mhi_dev; + mhi_ep_lb_work->buf =3D buf; + mhi_ep_lb_work->len =3D mhi_res->bytes_xferd; + + queue_work(mhi_ep_lb->wq, &mhi_ep_lb_work->work); + } +} + +static void mhi_ep_loopback_dl_callback(struct mhi_ep_device *mhi_dev, + struct mhi_result *mhi_res) +{ + kfree(mhi_res->buf_addr); +} + +static int mhi_ep_loopback_probe(struct mhi_ep_device *mhi_dev, const stru= ct mhi_device_id *id) +{ + struct mhi_ep_loopback *mhi_ep_lb; + + mhi_ep_lb =3D devm_kzalloc(&mhi_dev->dev, sizeof(*mhi_ep_lb), GFP_KERNEL); + if (!mhi_ep_lb) + return -ENOMEM; + + mhi_ep_lb->wq =3D alloc_ordered_workqueue("mhi_ep_loopback", WQ_MEM_RECLA= IM); + if (!mhi_ep_lb->wq) { + dev_err(&mhi_dev->dev, "Failed to create workqueue\n"); + return -ENOMEM; + } + + mhi_ep_lb->mdev =3D mhi_dev; + dev_set_drvdata(&mhi_dev->dev, mhi_ep_lb); + + return 0; +} + +static void mhi_ep_loopback_remove(struct mhi_ep_device *mhi_dev) +{ + struct mhi_ep_loopback *mhi_ep_lb =3D dev_get_drvdata(&mhi_dev->dev); + + destroy_workqueue(mhi_ep_lb->wq); +} + +static const struct mhi_device_id mhi_ep_loopback_id_table[] =3D { + { .chan =3D "LOOPBACK"}, + {} +}; +MODULE_DEVICE_TABLE(mhi, mhi_ep_loopback_id_table); + +static struct mhi_ep_driver mhi_ep_loopback_driver =3D { + .probe =3D mhi_ep_loopback_probe, + .remove =3D mhi_ep_loopback_remove, + .dl_xfer_cb =3D mhi_ep_loopback_dl_callback, + .ul_xfer_cb =3D mhi_ep_loopback_ul_callback, + .id_table =3D mhi_ep_loopback_id_table, + .driver =3D { + .name =3D "mhi_ep_loopback", + }, +}; + +module_mhi_ep_driver(mhi_ep_loopback_driver); + +MODULE_AUTHOR("Krishna Chaitanya Chundru "); +MODULE_AUTHOR("Sumit Kumar "); +MODULE_DESCRIPTION("MHI Endpoint Loopback driver"); +MODULE_LICENSE("GPL"); --=20 2.34.1