From nobody Tue Apr 7 12:53:41 2026 Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72]) (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 9FDB538F622; Fri, 13 Mar 2026 10:08:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.20.114.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773396513; cv=none; b=qaQyC/ybqRx2jhYmbP6d8JX8/2jfLbxq3FePFioWDxmKhG0MLQFYqBS9Al9m7XEiPTIFLiCx8Y6Lk72e8N3fMzI/sNYxGQgwBuIFwLjSgYnxPhfizJUPPIrVDGXA3BUSAvT640EnQ64INzC/6MOYhfIZPoA//LpeAaz+oK9xCbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773396513; c=relaxed/simple; bh=78sBqzD/xgUaZNF42FudqCrohUeibR7beHp9FUjNNAs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=EUZ4Zugre4aL98ZsX9FZ9sh8HEKxGnnGri+QMIbAsjL3AT/uuhcnhZYEOu7Sh+GN46ql2RMNK+Uxf5EU5lu+HYzg1m6ZglkOcVbmsagXaxtTJxKjsZpb0HU8tlZkUU3j41aA7nY1Qm0pMc5nJKPQBOrYpvtrJ4cTOu1Kv0x6p/0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com; spf=pass smtp.mailfrom=aspeedtech.com; arc=none smtp.client-ip=211.20.114.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aspeedtech.com Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Fri, 13 Mar 2026 18:08:12 +0800 Received: from [127.0.1.1] (192.168.10.13) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1748.10 via Frontend Transport; Fri, 13 Mar 2026 18:08:12 +0800 From: aspeedyh Date: Fri, 13 Mar 2026 18:07:41 +0800 Subject: [PATCH 6/7] soc: aspeed: Add sysfs controls for flash backend selection 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: <20260313-upstream_espi-v1-6-9504428e1f43@aspeedtech.com> References: <20260313-upstream_espi-v1-0-9504428e1f43@aspeedtech.com> In-Reply-To: <20260313-upstream_espi-v1-0-9504428e1f43@aspeedtech.com> To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Joel Stanley , "Andrew Jeffery" , Ryan Chen , Philipp Zabel CC: , , , , , , aspeedyh X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773396491; l=6770; i=yh_chung@aspeedtech.com; s=20260313; h=from:subject:message-id; bh=78sBqzD/xgUaZNF42FudqCrohUeibR7beHp9FUjNNAs=; b=QGkIR8fhoTHKqHX7qiGYNnqJAwkWw+OA6BoXb4376Fz9jYQGG7DV9cJp65M1QyLvL9AJD+q8M 11B5HHphtSQDoNhDjDx6Jkwl5ne3yiNzTyotfRqUcwsySxms7ps06WA X-Developer-Key: i=yh_chung@aspeedtech.com; a=ed25519; pk=o71dz0J8lpN+v0f3Mk4gT9PfVngADPC1Pex4aK6VigM= add following attributes to select backend storage for eSPI TAFS LUN interface: - flash_lun_path: specify path of backend storage for eSPI TAFS to share with host. - flash_lun_readonly: set flash LUN to read-only or read-write mode to block host write operations. - flash_lun_enable: open storage according to flash_lun_path as file for eSPI TAFS access. Example usage: - Select /dev/mtdblock8 as backend storage for eSPI TAFS LUN interface echo /dev/mtdblock8 > \ /sys/bus/platform/devices/1e6ee000.espi/flash_lun_path - Set LUN to read-only mode to block host write operations echo 1 > /sys/bus/platform/devices/1e6ee000.espi/flash_lun_readonly - Enable flash LUN for eSPI TAFS access echo 1 > /sys/bus/platform/devices/1e6ee000.espi/flash_lun_enable Signed-off-by: aspeedyh --- drivers/soc/aspeed/espi/aspeed-espi.c | 218 ++++++++++++++++++++++++++++++= ++++ 1 file changed, 218 insertions(+) diff --git a/drivers/soc/aspeed/espi/aspeed-espi.c b/drivers/soc/aspeed/esp= i/aspeed-espi.c index 7d58c78ed397..2c8f9641174d 100644 --- a/drivers/soc/aspeed/espi/aspeed-espi.c +++ b/drivers/soc/aspeed/espi/aspeed-espi.c @@ -12,12 +12,224 @@ #include #include #include +#include +#include +#include =20 #include "aspeed-espi.h" #include "aspeed-espi-comm.h" #include "ast2600-espi.h" #include "espi_storage.h" =20 +static ssize_t flash_lun_path_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + ssize_t rc; + + espi =3D dev_get_drvdata(dev); + + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + mutex_lock(&flash->lun_mtx); + rc =3D scnprintf(buf, PAGE_SIZE, "%s\n", flash->lun_path); + mutex_unlock(&flash->lun_mtx); + + return rc; +} + +static ssize_t flash_lun_path_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char tmp[ASPEED_ESPI_LUN_PATH_MAX]; + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + size_t len; + + espi =3D dev_get_drvdata(dev); + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + len =3D strnlen(buf, count); + if (len && buf[len - 1] =3D=3D '\n') + len--; + + if (len >=3D sizeof(tmp)) + return -ENAMETOOLONG; + + memcpy(tmp, buf, len); + tmp[len] =3D '\0'; + + mutex_lock(&flash->lun_mtx); + if (flash->lun && flash->lun->filp) { + mutex_unlock(&flash->lun_mtx); + return -EBUSY; + } + + strscpy(flash->lun_path, tmp, sizeof(flash->lun_path)); + dev_info(dev, "flash lun path set to %s\n", flash->lun_path); + mutex_unlock(&flash->lun_mtx); + + return count; +} + +static ssize_t flash_lun_readonly_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + ssize_t rc; + + espi =3D dev_get_drvdata(dev); + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + mutex_lock(&flash->lun_mtx); + rc =3D scnprintf(buf, PAGE_SIZE, "%u\n", flash->lun_ro); + mutex_unlock(&flash->lun_mtx); + + return rc; +} + +static ssize_t flash_lun_readonly_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + bool ro; + int rc; + + espi =3D dev_get_drvdata(dev); + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + rc =3D kstrtobool(buf, &ro); + if (rc) + return rc; + + mutex_lock(&flash->lun_mtx); + if (flash->lun && flash->lun->filp) { + mutex_unlock(&flash->lun_mtx); + return -EBUSY; + } + + flash->lun_ro =3D ro; + dev_info(dev, "flash lun readonly set to %u\n", flash->lun_ro); + mutex_unlock(&flash->lun_mtx); + + return count; +} + +static ssize_t flash_lun_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + bool enabled; + ssize_t rc; + + espi =3D dev_get_drvdata(dev); + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + mutex_lock(&flash->lun_mtx); + enabled =3D flash->lun && flash->lun->filp; + mutex_unlock(&flash->lun_mtx); + + rc =3D scnprintf(buf, PAGE_SIZE, "%u\n", enabled); + return rc; +} + +static ssize_t flash_lun_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aspeed_espi_flash *flash; + struct aspeed_espi *espi; + bool enable; + int rc =3D 0; + + espi =3D dev_get_drvdata(dev); + if (!espi) + return -ENODEV; + + flash =3D &espi->flash; + + rc =3D kstrtobool(buf, &enable); + if (rc) + return rc; + + mutex_lock(&flash->lun_mtx); + if (!flash->lun) { + flash->lun =3D devm_kzalloc(dev, sizeof(*flash->lun), GFP_KERNEL); + if (!flash->lun) { + rc =3D -ENOMEM; + goto out_unlock; + } + } + + if (enable) { + if (flash->lun->filp) + goto out_unlock; + if (!flash->lun_path[0]) { + rc =3D -EINVAL; + goto out_unlock; + } + + dev_info(dev, "flash lun enable: path=3D%s ro=3D%u\n", + flash->lun_path, flash->lun_ro); + mutex_lock(&flash->tx_mtx); + rc =3D aspeed_espi_lun_open(flash->lun, flash->lun_path, + flash->lun_ro, false); + mutex_unlock(&flash->tx_mtx); + } else { + if (!flash->lun->filp) + goto out_unlock; + + dev_info(dev, "flash lun disable\n"); + mutex_lock(&flash->tx_mtx); + aspeed_espi_lun_close(flash->lun); + mutex_unlock(&flash->tx_mtx); + } + +out_unlock: + mutex_unlock(&flash->lun_mtx); + if (rc) { + dev_err(dev, "flash lun enable=3D%u failed: %d\n", enable, rc); + return rc; + } + + return count; +} + +static DEVICE_ATTR_RW(flash_lun_path); +static DEVICE_ATTR_RW(flash_lun_readonly); +static DEVICE_ATTR_RW(flash_lun_enable); + +static struct attribute *aspeed_espi_flash_attrs[] =3D { + &dev_attr_flash_lun_path.attr, + &dev_attr_flash_lun_readonly.attr, + &dev_attr_flash_lun_enable.attr, + NULL, +}; + +static const struct attribute_group aspeed_espi_flash_attr_group =3D { + .attrs =3D aspeed_espi_flash_attrs, +}; =20 struct aspeed_espi_ops { void (*espi_pre_init)(struct aspeed_espi *espi); @@ -336,6 +548,12 @@ static int aspeed_espi_probe(struct platform_device *p= dev) goto err_remove_perif; } =20 + rc =3D devm_device_add_group(dev, &aspeed_espi_flash_attr_group); + if (rc) { + dev_err(dev, "cannot add flash LUN sysfs group, rc=3D%d\n", rc); + goto err_remove_flash; + } + rc =3D devm_request_irq(dev, espi->irq, espi->ops->espi_isr, 0, dev_name(dev), espi); if (rc) { --=20 2.34.1