Commit f918cfc0 authored by Ronak Jain's avatar Ronak Jain Committed by Greg Kroah-Hartman
Browse files

firmware: xilinx: add support for IOCTL and QUERY ID feature check



Add support to check if IOCTL ID or QUERY ID is supported in firmware
or not.

Signed-off-by: default avatarRonak Jain <ronak.jain@xilinx.com>
Link: https://lore.kernel.org/r/1649242526-17493-2-git-send-email-ronak.jain@xilinx.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d8a54d2e
Loading
Loading
Loading
Loading
+61 −1
Original line number Diff line number Diff line
@@ -36,8 +36,16 @@
/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */
#define CRL_APB_BOOTPIN_CTRL_MASK	0xF0FU

/* IOCTL/QUERY feature payload size */
#define FEATURE_PAYLOAD_SIZE		2

/* Firmware feature check version mask */
#define FIRMWARE_VERSION_MASK		GENMASK(15, 0)

static bool feature_check_enabled;
static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
static u32 ioctl_features[FEATURE_PAYLOAD_SIZE];
static u32 query_features[FEATURE_PAYLOAD_SIZE];

static struct platform_device *em_dev;

@@ -168,7 +176,8 @@ static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
}

/**
 * zynqmp_pm_feature() - Check weather given feature is supported or not
 * zynqmp_pm_feature() - Check whether given feature is supported or not and
 *			 store supported IOCTL/QUERY ID mask
 * @api_id:		API ID to check
 *
 * Return: Returns status, either success or error+reason
@@ -208,10 +217,61 @@ int zynqmp_pm_feature(const u32 api_id)
	feature_data->feature_status = ret;
	hash_add(pm_api_features_map, &feature_data->hentry, api_id);

	if (api_id == PM_IOCTL)
		/* Store supported IOCTL IDs mask */
		memcpy(ioctl_features, &ret_payload[2], FEATURE_PAYLOAD_SIZE * 4);
	else if (api_id == PM_QUERY_DATA)
		/* Store supported QUERY IDs mask */
		memcpy(query_features, &ret_payload[2], FEATURE_PAYLOAD_SIZE * 4);

	return ret;
}
EXPORT_SYMBOL_GPL(zynqmp_pm_feature);

/**
 * zynqmp_pm_is_function_supported() - Check whether given IOCTL/QUERY function
 *				       is supported or not
 * @api_id:		PM_IOCTL or PM_QUERY_DATA
 * @id:			IOCTL or QUERY function IDs
 *
 * Return: Returns status, either success or error+reason
 */
int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
{
	int ret;
	u32 *bit_mask;

	/* Input arguments validation */
	if (id >= 64 || (api_id != PM_IOCTL && api_id != PM_QUERY_DATA))
		return -EINVAL;

	/* Check feature check API version */
	ret = zynqmp_pm_feature(PM_FEATURE_CHECK);
	if (ret < 0)
		return ret;

	/* Check if feature check version 2 is supported or not */
	if ((ret & FIRMWARE_VERSION_MASK) == PM_API_VERSION_2) {
		/*
		 * Call feature check for IOCTL/QUERY API to get IOCTL ID or
		 * QUERY ID feature status.
		 */
		ret = zynqmp_pm_feature(api_id);
		if (ret < 0)
			return ret;

		bit_mask = (api_id == PM_IOCTL) ? ioctl_features : query_features;

		if ((bit_mask[(id / 32)] & BIT((id % 32))) == 0U)
			return -EOPNOTSUPP;
	} else {
		return -ENODATA;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported);

/**
 * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
 *			   caller function depending on the configuration
+11 −0
Original line number Diff line number Diff line
@@ -29,6 +29,11 @@

/* SMC SIP service Call Function Identifier Prefix */
#define PM_SIP_SVC			0xC2000000

/* PM API versions */
#define PM_API_VERSION_2	2

/* ATF only commands */
#define PM_GET_TRUSTZONE_VERSION	0xa03
#define PM_SET_SUSPEND_MODE		0xa02
#define GET_CALLBACK_DATA		0xa01
@@ -460,6 +465,7 @@ int zynqmp_pm_load_pdi(const u32 src, const u64 address);
int zynqmp_pm_register_notifier(const u32 node, const u32 event,
				const u32 wake, const u32 enable);
int zynqmp_pm_feature(const u32 api_id);
int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value);
int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload);
#else
@@ -678,6 +684,11 @@ static inline int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id)
	return -ENODEV;
}

static inline int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
{
	return -ENODEV;
}

static inline int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id)
{
	return -ENODEV;