Revert "firmware: zynqmp: Add dynamic CSU register discovery and sysfs interface"

This reverts commit 47d7bca76d, which was
merged by accident.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann
2026-06-15 13:41:05 +02:00
parent 218462fb8e
commit 2b31e94bef
6 changed files with 2 additions and 296 deletions

View File

@@ -29271,16 +29271,6 @@ F: drivers/dma/xilinx/xdma.c
F: include/linux/dma/amd_xdma.h
F: include/linux/platform_data/amd_xdma.h
XILINX ZYNQMP CSU REGISTER DRIVER
M: Senthil Nathan Thangaraj <senthilnathan.thangaraj@amd.com>
R: Michal Simek <michal.simek@amd.com>
R: Ronak Jain <ronak.jain@amd.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
F: drivers/firmware/xilinx/zynqmp-csu-reg.c
F: drivers/firmware/xilinx/zynqmp-csu-reg.h
XILINX ZYNQMP DPDMA DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: dmaengine@vger.kernel.org

View File

@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for Xilinx firmwares
obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o zynqmp-ufs.o zynqmp-crypto.o zynqmp-csu-reg.o
obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o zynqmp-ufs.o zynqmp-crypto.o
obj-$(CONFIG_ZYNQMP_FIRMWARE_DEBUG) += zynqmp-debug.o

View File

@@ -1,258 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Xilinx Zynq MPSoC CSU Register Access
*
* Copyright (C) 2026 Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Ronak Jain <ronak.jain@amd.com>
*/
#include <linux/firmware/xlnx-zynqmp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "zynqmp-csu-reg.h"
/* Node ID for CSU module in firmware */
#define CSU_NODE_ID 0
/* Maximum number of CSU registers supported */
#define MAX_CSU_REGS 50
/* Size of register name returned by firmware (3 u32 words = 12 bytes) */
#define CSU_REG_NAME_LEN 12
/**
* struct zynqmp_csu_reg - CSU register information
* @id: Register index from firmware
* @name: Register name
* @attr: Device attribute for sysfs
*/
struct zynqmp_csu_reg {
u32 id;
char name[CSU_REG_NAME_LEN];
struct device_attribute attr;
};
/**
* struct zynqmp_csu_data - Per-device CSU data
* @csu_regs: Array of CSU registers
* @csu_attr_group: Attribute group for sysfs
*/
struct zynqmp_csu_data {
struct zynqmp_csu_reg *csu_regs;
struct attribute_group csu_attr_group;
};
/**
* zynqmp_pm_get_node_count() - Get number of supported nodes via QUERY_DATA
*
* Return: Number of nodes on success, or negative error code
*/
static int zynqmp_pm_get_node_count(void)
{
struct zynqmp_pm_query_data qdata = {0};
u32 ret_payload[PAYLOAD_ARG_CNT];
int ret;
qdata.qid = PM_QID_GET_NODE_COUNT;
ret = zynqmp_pm_query_data(qdata, ret_payload);
if (ret)
return ret;
return ret_payload[1];
}
/**
* zynqmp_pm_get_node_name() - Get node name via QUERY_DATA
* @index: Register index
* @name: Buffer to store register name
*
* Return: 0 on success, error code otherwise
*/
static int zynqmp_pm_get_node_name(u32 index, char *name)
{
struct zynqmp_pm_query_data qdata = {0};
u32 ret_payload[PAYLOAD_ARG_CNT];
int ret;
qdata.qid = PM_QID_GET_NODE_NAME;
qdata.arg1 = index;
ret = zynqmp_pm_query_data(qdata, ret_payload);
if (ret)
return ret;
memcpy(name, &ret_payload[1], CSU_REG_NAME_LEN);
name[CSU_REG_NAME_LEN - 1] = '\0';
return 0;
}
/**
* zynqmp_csu_reg_show() - Generic show function for all registers
* @dev: Device pointer
* @attr: Device attribute
* @buf: Output buffer
*
* Return: Number of bytes written to buffer, or error code
*/
static ssize_t zynqmp_csu_reg_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct zynqmp_csu_reg *reg;
u32 value;
int ret;
/* Use container_of to get register directly */
reg = container_of(attr, struct zynqmp_csu_reg, attr);
ret = zynqmp_pm_sec_read_reg(CSU_NODE_ID, reg->id, &value);
if (ret)
return ret;
return sysfs_emit(buf, "0x%08x\n", value);
}
/**
* zynqmp_csu_reg_store() - Generic store function for writable registers
* @dev: Device pointer
* @attr: Device attribute
* @buf: Input buffer
* @count: Buffer size
*
* Format: "mask value" - both mask and value required
* Example: echo "0xFFFFFFFF 0x12345678" > register
*
* Return: count on success, error code otherwise
*/
static ssize_t zynqmp_csu_reg_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct zynqmp_csu_reg *reg;
u32 mask, value;
int ret;
reg = container_of(attr, struct zynqmp_csu_reg, attr);
if (sscanf(buf, "%x %x", &mask, &value) != 2)
return -EINVAL;
ret = zynqmp_pm_sec_mask_write_reg(CSU_NODE_ID, reg->id, mask, value);
if (ret)
return ret;
return count;
}
/**
* zynqmp_csu_discover_registers() - Discover CSU registers from firmware
* @pdev: Platform device pointer
*
* This function uses PM_QUERY_DATA to discover all available CSU registers
* and creates sysfs group under /sys/devices/platform/firmware:zynqmp-firmware/
*
* Return: 0 on success, error code otherwise
*/
int zynqmp_csu_discover_registers(struct platform_device *pdev)
{
struct zynqmp_csu_data *csu_data;
struct attribute **attrs;
int count, ret, i;
ret = zynqmp_pm_is_function_supported(PM_QUERY_DATA, PM_QID_GET_NODE_COUNT);
if (ret) {
dev_dbg(&pdev->dev, "CSU register discovery not supported by current firmware\n");
return 0;
}
ret = zynqmp_pm_is_function_supported(PM_QUERY_DATA, PM_QID_GET_NODE_NAME);
if (ret) {
dev_dbg(&pdev->dev, "CSU register name query not supported by current firmware\n");
return 0;
}
count = zynqmp_pm_get_node_count();
if (count < 0)
return count;
if (count == 0) {
dev_dbg(&pdev->dev, "No nodes available from firmware\n");
return 0;
}
/* Validate count to prevent excessive memory allocation */
if (count > MAX_CSU_REGS) {
dev_err(&pdev->dev, "Register count %d exceeds maximum %d\n",
count, MAX_CSU_REGS);
return -EINVAL;
}
dev_dbg(&pdev->dev, "Discovered %d nodes from firmware\n", count);
csu_data = devm_kzalloc(&pdev->dev, sizeof(*csu_data), GFP_KERNEL);
if (!csu_data)
return -ENOMEM;
csu_data->csu_regs = devm_kcalloc(&pdev->dev, count, sizeof(*csu_data->csu_regs),
GFP_KERNEL);
if (!csu_data->csu_regs) {
devm_kfree(&pdev->dev, csu_data);
return -ENOMEM;
}
attrs = devm_kcalloc(&pdev->dev, count + 1, sizeof(*attrs), GFP_KERNEL);
if (!attrs) {
devm_kfree(&pdev->dev, csu_data->csu_regs);
devm_kfree(&pdev->dev, csu_data);
return -ENOMEM;
}
for (i = 0; i < count; i++) {
struct zynqmp_csu_reg *reg = &csu_data->csu_regs[i];
struct device_attribute *dev_attr = &reg->attr;
reg->id = i;
ret = zynqmp_pm_get_node_name(i, reg->name);
if (ret) {
dev_warn(&pdev->dev, "Failed to get name for register %d\n", i);
snprintf(reg->name, sizeof(reg->name), "csu_reg_%d", i);
}
/*
* The firmware does not expose per-register access mode via
* PM_QUERY_DATA today, so the kernel cannot tell read-only
* registers from read-write ones at discovery time. Expose
* every register as 0644 and rely on the firmware to reject
* IOCTL_MASK_WRITE_REG on read-only registers; the error is
* propagated back to userspace from the store callback.
*/
sysfs_attr_init(&dev_attr->attr);
dev_attr->attr.name = reg->name;
dev_attr->attr.mode = 0644;
dev_attr->show = zynqmp_csu_reg_show;
dev_attr->store = zynqmp_csu_reg_store;
attrs[i] = &dev_attr->attr;
dev_dbg(&pdev->dev, "Register %d: id=%d name=%s\n", i, reg->id, reg->name);
}
csu_data->csu_attr_group.name = "csu_registers";
csu_data->csu_attr_group.attrs = attrs;
ret = devm_device_add_group(&pdev->dev, &csu_data->csu_attr_group);
if (ret) {
devm_kfree(&pdev->dev, attrs);
devm_kfree(&pdev->dev, csu_data->csu_regs);
devm_kfree(&pdev->dev, csu_data);
}
return ret;
}
EXPORT_SYMBOL_GPL(zynqmp_csu_discover_registers);

View File

@@ -1,18 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Xilinx Zynq MPSoC CSU Register Access
*
* Copyright (C) 2026 Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Ronak Jain <ronak.jain@amd.com>
*/
#ifndef __ZYNQMP_CSU_REG_H__
#define __ZYNQMP_CSU_REG_H__
#include <linux/platform_device.h>
int zynqmp_csu_discover_registers(struct platform_device *pdev);
#endif /* __ZYNQMP_CSU_REG_H__ */

View File

@@ -27,7 +27,6 @@
#include <linux/firmware/xlnx-zynqmp.h>
#include <linux/firmware/xlnx-event-manager.h>
#include "zynqmp-csu-reg.h"
#include "zynqmp-debug.h"
/* Max HashMap Order for PM API feature check (1<<7 = 128) */
@@ -2121,11 +2120,6 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n");
}
/* Discover CSU registers dynamically */
ret = zynqmp_csu_discover_registers(pdev);
if (ret)
dev_warn(&pdev->dev, "CSU register discovery failed: %d\n", ret);
return of_platform_populate(dev->of_node, NULL, NULL, dev);
}

View File

@@ -3,7 +3,7 @@
* Xilinx Zynq MPSoC Firmware layer
*
* Copyright (C) 2014-2021 Xilinx
* Copyright (C) 2022 - 2026 Advanced Micro Devices, Inc.
* Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc.
*
* Michal Simek <michal.simek@amd.com>
* Davorin Mista <davorin.mista@aggios.com>
@@ -262,8 +262,6 @@ enum pm_query_id {
PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
PM_QID_PINCTRL_GET_ATTRIBUTES = 15,
PM_QID_GET_NODE_NAME = 16,
PM_QID_GET_NODE_COUNT = 17,
};
enum rpu_oper_mode {