// SPDX-License-Identifier: GPL-2.0
/*
 * Zynq UltraScale+ MPSoC clock controller
 *
 *  Copyright (C) 2016-2019 Xilinx
 *
 * Based on drivers/clk/zynq/clkc.c
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>

#include "clk-zynqmp.h"

#define MAX_PARENT			100
#define MAX_NODES			6
#define MAX_NAME_LEN			50

/* Flags for parents */
#define PARENT_CLK_SELF			0
#define PARENT_CLK_NODE1		1
#define PARENT_CLK_NODE2		2
#define PARENT_CLK_NODE3		3
#define PARENT_CLK_NODE4		4
#define PARENT_CLK_EXTERNAL		5

#define END_OF_CLK_NAME			"END_OF_CLK"
#define END_OF_TOPOLOGY_NODE		1
#define END_OF_PARENTS			1
#define RESERVED_CLK_NAME		""

#define CLK_GET_NAME_RESP_LEN		16
#define CLK_GET_TOPOLOGY_RESP_WORDS	3
#define CLK_GET_PARENTS_RESP_WORDS	3
#define CLK_GET_ATTR_RESP_WORDS		1

enum clk_type {
	CLK_TYPE_OUTPUT,
	CLK_TYPE_EXTERNAL,
};

/**
 * struct clock_parent - Clock parent
 * @name:	Parent name
 * @id:		Parent clock ID
 * @flag:	Parent flags
 */
struct clock_parent {
	char name[MAX_NAME_LEN];
	int id;
	u32 flag;
};

/**
 * struct zynqmp_clock - Clock
 * @clk_name:		Clock name
 * @valid:		Validity flag of clock
 * @type:		Clock type (Output/External)
 * @node:		Clock topology nodes
 * @num_nodes:		Number of nodes present in topology
 * @parent:		Parent of clock
 * @num_parents:	Number of parents of clock
 * @clk_id:		Clock id
 */
struct zynqmp_clock {
	char clk_name[MAX_NAME_LEN];
	u32 valid;
	enum clk_type type;
	struct clock_topology node[MAX_NODES];
	u32 num_nodes;
	struct clock_parent parent[MAX_PARENT];
	u32 num_parents;
	u32 clk_id;
};

struct name_resp {
	char name[CLK_GET_NAME_RESP_LEN];
};

struct topology_resp {
#define CLK_TOPOLOGY_TYPE		GENMASK(3, 0)
#define CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS	GENMASK(7, 4)
#define CLK_TOPOLOGY_FLAGS		GENMASK(23, 8)
#define CLK_TOPOLOGY_TYPE_FLAGS		GENMASK(31, 24)
	u32 topology[CLK_GET_TOPOLOGY_RESP_WORDS];
};

struct parents_resp {
#define NA_PARENT			0xFFFFFFFF
#define DUMMY_PARENT			0xFFFFFFFE
#define CLK_PARENTS_ID			GENMASK(15, 0)
#define CLK_PARENTS_FLAGS		GENMASK(31, 16)
	u32 parents[CLK_GET_PARENTS_RESP_WORDS];
};

struct attr_resp {
#define CLK_ATTR_VALID			BIT(0)
#define CLK_ATTR_TYPE			BIT(2)
#define CLK_ATTR_NODE_INDEX		GENMASK(13, 0)
#define CLK_ATTR_NODE_TYPE		GENMASK(19, 14)
#define CLK_ATTR_NODE_SUBCLASS		GENMASK(25, 20)
#define CLK_ATTR_NODE_CLASS		GENMASK(31, 26)
	u32 attr[CLK_GET_ATTR_RESP_WORDS];
};

static const char clk_type_postfix[][10] = {
	[TYPE_INVALID] = "",
	[TYPE_MUX] = "_mux",
	[TYPE_GATE] = "",
	[TYPE_DIV1] = "_div1",
	[TYPE_DIV2] = "_div2",
	[TYPE_FIXEDFACTOR] = "_ff",
	[TYPE_PLL] = ""
};

static struct clk_hw *(* const clk_topology[]) (const char *name, u32 clk_id,
					const char * const *parents,
					u8 num_parents,
					const struct clock_topology *nodes)
					= {
	[TYPE_INVALID] = NULL,
	[TYPE_MUX] = zynqmp_clk_register_mux,
	[TYPE_PLL] = zynqmp_clk_register_pll,
	[TYPE_FIXEDFACTOR] = zynqmp_clk_register_fixed_factor,
	[TYPE_DIV1] = zynqmp_clk_register_divider,
	[TYPE_DIV2] = zynqmp_clk_register_divider,
	[TYPE_GATE] = zynqmp_clk_register_gate
};

static struct zynqmp_clock *clock;
static struct clk_hw_onecell_data *zynqmp_data;
static unsigned int clock_max_idx;

/**
 * zynqmp_is_valid_clock() - Check whether clock is valid or not
 * @clk_id:	Clock index
 *
 * Return: 1 if clock is valid, 0 if clock is invalid else error code
 */
static inline int zynqmp_is_valid_clock(u32 clk_id)
{
	if (clk_id >= clock_max_idx)
		return -ENODEV;

	return clock[clk_id].valid;
}

/**
 * zynqmp_get_clock_name() - Get name of clock from Clock index
 * @clk_id:	Clock index
 * @clk_name:	Name of clock
 *
 * Return: 0 on success else error code
 */
static int zynqmp_get_clock_name(u32 clk_id, char *clk_name)
{
	int ret;

	ret = zynqmp_is_valid_clock(clk_id);
	if (ret == 1) {
		strscpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN);
		return 0;
	}

	return ret == 0 ? -EINVAL : ret;
}

/**
 * zynqmp_get_clock_type() - Get type of clock
 * @clk_id:	Clock index
 * @type:	Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL
 *
 * Return: 0 on success else error code
 */
static int zynqmp_get_clock_type(u32 clk_id, u32 *type)
{
	int ret;

	ret = zynqmp_is_valid_clock(clk_id);
	if (ret == 1) {
		*type = clock[clk_id].type;
		return 0;
	}

	return ret == 0 ? -EINVAL : ret;
}

/**
 * zynqmp_pm_clock_get_num_clocks() - Get number of clocks in system
 * @nclocks:	Number of clocks in system/board.
 *
 * Call firmware API to get number of clocks.
 *
 * Return: 0 on success else error code.
 */
static int zynqmp_pm_clock_get_num_clocks(u32 *nclocks)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_NUM_CLOCKS;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	*nclocks = ret_payload[1];

	return ret;
}

/**
 * zynqmp_pm_clock_get_name() - Get the name of clock for given id
 * @clock_id:	ID of the clock to be queried
 * @response:	Name of the clock with the given id
 *
 * This function is used to get name of clock specified by given
 * clock ID.
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_name(u32 clock_id,
				    struct name_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_NAME;
	qdata.arg1 = clock_id;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	if (ret)
		return ret;

	memcpy(response, ret_payload, sizeof(*response));

	return 0;
}

/**
 * zynqmp_pm_clock_get_topology() - Get the topology of clock for given id
 * @clock_id:	ID of the clock to be queried
 * @index:	Node index of clock topology
 * @response:	Buffer used for the topology response
 *
 * This function is used to get topology information for the clock
 * specified by given clock ID.
 *
 * This API will return 3 node of topology with a single response. To get
 * other nodes, master should call same API in loop with new
 * index till error is returned. E.g First call should have
 * index 0 which will return nodes 0,1 and 2. Next call, index
 * should be 3 which will return nodes 3,4 and 5 and so on.
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index,
					struct topology_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY;
	qdata.arg1 = clock_id;
	qdata.arg2 = index;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag)
{
	unsigned long ccf_flag = 0;

	if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_GATE)
		ccf_flag |= CLK_SET_RATE_GATE;
	if (zynqmp_flag & ZYNQMP_CLK_SET_PARENT_GATE)
		ccf_flag |= CLK_SET_PARENT_GATE;
	if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_PARENT)
		ccf_flag |= CLK_SET_RATE_PARENT;
	if (zynqmp_flag & ZYNQMP_CLK_IGNORE_UNUSED)
		ccf_flag |= CLK_IGNORE_UNUSED;
	if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_NO_REPARENT)
		ccf_flag |= CLK_SET_RATE_NO_REPARENT;
	if (zynqmp_flag & ZYNQMP_CLK_IS_CRITICAL)
		ccf_flag |= CLK_IS_CRITICAL;

	return ccf_flag;
}

/**
 * zynqmp_clk_register_fixed_factor() - Register fixed factor with the
 *					clock framework
 * @name:		Name of this clock
 * @clk_id:		Clock ID
 * @parents:		Name of this clock's parents
 * @num_parents:	Number of parents
 * @nodes:		Clock topology node
 *
 * Return: clock hardware to the registered clock
 */
struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id,
					const char * const *parents,
					u8 num_parents,
					const struct clock_topology *nodes)
{
	u32 mult, div;
	struct clk_hw *hw;
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;
	unsigned long flag;

	qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS;
	qdata.arg1 = clk_id;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	if (ret)
		return ERR_PTR(ret);

	mult = ret_payload[1];
	div = ret_payload[2];

	flag = zynqmp_clk_map_common_ccf_flags(nodes->flag);

	hw = clk_hw_register_fixed_factor(NULL, name,
					  parents[0],
					  flag, mult,
					  div);

	return hw;
}

/**
 * zynqmp_pm_clock_get_parents() - Get the first 3 parents of clock for given id
 * @clock_id:	Clock ID
 * @index:	Parent index
 * @response:	Parents of the given clock
 *
 * This function is used to get 3 parents for the clock specified by
 * given clock ID.
 *
 * This API will return 3 parents with a single response. To get
 * other parents, master should call same API in loop with new
 * parent index till error is returned. E.g First call should have
 * index 0 which will return parents 0,1 and 2. Next call, index
 * should be 3 which will return parent 3,4 and 5 and so on.
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index,
				       struct parents_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_PARENTS;
	qdata.arg1 = clock_id;
	qdata.arg2 = index;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

/**
 * zynqmp_pm_clock_get_attributes() - Get the attributes of clock for given id
 * @clock_id:	Clock ID
 * @response:	Clock attributes response
 *
 * This function is used to get clock's attributes(e.g. valid, clock type, etc).
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_pm_clock_get_attributes(u32 clock_id,
					  struct attr_resp *response)
{
	struct zynqmp_pm_query_data qdata = {0};
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES;
	qdata.arg1 = clock_id;

	ret = zynqmp_pm_query_data(qdata, ret_payload);
	memcpy(response, &ret_payload[1], sizeof(*response));

	return ret;
}

/**
 * __zynqmp_clock_get_topology() - Get topology data of clock from firmware
 *				   response data
 * @topology:		Clock topology
 * @response:		Clock topology data received from firmware
 * @nnodes:		Number of nodes
 *
 * Return: 0 on success else error+reason
 */
static int __zynqmp_clock_get_topology(struct clock_topology *topology,
				       struct topology_resp *response,
				       u32 *nnodes)
{
	int i;
	u32 type;

	for (i = 0; i < ARRAY_SIZE(response->topology); i++) {
		type = FIELD_GET(CLK_TOPOLOGY_TYPE, response->topology[i]);
		if (type == TYPE_INVALID)
			return END_OF_TOPOLOGY_NODE;
		topology[*nnodes].type = type;
		topology[*nnodes].flag = FIELD_GET(CLK_TOPOLOGY_FLAGS,
						   response->topology[i]);
		topology[*nnodes].type_flag =
				FIELD_GET(CLK_TOPOLOGY_TYPE_FLAGS,
					  response->topology[i]);
		topology[*nnodes].custom_type_flag =
			FIELD_GET(CLK_TOPOLOGY_CUSTOM_TYPE_FLAGS,
				  response->topology[i]);
		(*nnodes)++;
	}

	return 0;
}

/**
 * zynqmp_clock_get_topology() - Get topology of clock from firmware using
 *				 PM_API
 * @clk_id:		Clock index
 * @topology:		Clock topology
 * @num_nodes:		Number of nodes
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_clock_get_topology(u32 clk_id,
				     struct clock_topology *topology,
				     u32 *num_nodes)
{
	int j, ret;
	struct topology_resp response = { };

	*num_nodes = 0;
	for (j = 0; j <= MAX_NODES; j += ARRAY_SIZE(response.topology)) {
		ret = zynqmp_pm_clock_get_topology(clock[clk_id].clk_id, j,
						   &response);
		if (ret)
			return ret;
		ret = __zynqmp_clock_get_topology(topology, &response,
						  num_nodes);
		if (ret == END_OF_TOPOLOGY_NODE)
			return 0;
	}

	return 0;
}

/**
 * __zynqmp_clock_get_parents() - Get parents info of clock from firmware
 *				   response data
 * @parents:		Clock parents
 * @response:		Clock parents data received from firmware
 * @nparent:		Number of parent
 *
 * Return: 0 on success else error+reason
 */
static int __zynqmp_clock_get_parents(struct clock_parent *parents,
				      struct parents_resp *response,
				      u32 *nparent)
{
	int i;
	struct clock_parent *parent;

	for (i = 0; i < ARRAY_SIZE(response->parents); i++) {
		if (response->parents[i] == NA_PARENT)
			return END_OF_PARENTS;

		parent = &parents[i];
		parent->id = FIELD_GET(CLK_PARENTS_ID, response->parents[i]);
		if (response->parents[i] == DUMMY_PARENT) {
			strcpy(parent->name, "dummy_name");
			parent->flag = 0;
		} else {
			parent->flag = FIELD_GET(CLK_PARENTS_FLAGS,
						 response->parents[i]);
			if (zynqmp_get_clock_name(parent->id, parent->name))
				continue;
		}
		*nparent += 1;
	}

	return 0;
}

/**
 * zynqmp_clock_get_parents() - Get parents info from firmware using PM_API
 * @clk_id:		Clock index
 * @parents:		Clock parents
 * @num_parents:	Total number of parents
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_clock_get_parents(u32 clk_id, struct clock_parent *parents,
				    u32 *num_parents)
{
	int j = 0, ret;
	struct parents_resp response = { };

	*num_parents = 0;
	do {
		/* Get parents from firmware */
		ret = zynqmp_pm_clock_get_parents(clock[clk_id].clk_id, j,
						  &response);
		if (ret)
			return ret;

		ret = __zynqmp_clock_get_parents(&parents[j], &response,
						 num_parents);
		if (ret == END_OF_PARENTS)
			return 0;
		j += ARRAY_SIZE(response.parents);
	} while (*num_parents <= MAX_PARENT);

	return 0;
}

/**
 * zynqmp_get_parent_list() - Create list of parents name
 * @np:			Device node
 * @clk_id:		Clock index
 * @parent_list:	List of parent's name
 * @num_parents:	Total number of parents
 *
 * Return: 0 on success else error+reason
 */
static int zynqmp_get_parent_list(struct device_node *np, u32 clk_id,
				  const char **parent_list, u32 *num_parents)
{
	int i = 0, ret;
	u32 total_parents = clock[clk_id].num_parents;
	struct clock_topology *clk_nodes;
	struct clock_parent *parents;

	clk_nodes = clock[clk_id].node;
	parents = clock[clk_id].parent;

	for (i = 0; i < total_parents; i++) {
		if (!parents[i].flag) {
			parent_list[i] = parents[i].name;
		} else if (parents[i].flag == PARENT_CLK_EXTERNAL) {
			ret = of_property_match_string(np, "clock-names",
						       parents[i].name);
			if (ret < 0)
				strcpy(parents[i].name, "dummy_name");
			parent_list[i] = parents[i].name;
		} else {
			strcat(parents[i].name,
			       clk_type_postfix[clk_nodes[parents[i].flag - 1].
			       type]);
			parent_list[i] = parents[i].name;
		}
	}

	*num_parents = total_parents;
	return 0;
}

/**
 * zynqmp_register_clk_topology() - Register clock topology
 * @clk_id:		Clock index
 * @clk_name:		Clock Name
 * @num_parents:	Total number of parents
 * @parent_names:	List of parents name
 *
 * Return: Returns either clock hardware or error+reason
 */
static struct clk_hw *zynqmp_register_clk_topology(int clk_id, char *clk_name,
						   int num_parents,
						   const char **parent_names)
{
	int j;
	u32 num_nodes, clk_dev_id;
	char *clk_out[MAX_NODES];
	struct clock_topology *nodes;
	struct clk_hw *hw = NULL;

	nodes = clock[clk_id].node;
	num_nodes = clock[clk_id].num_nodes;
	clk_dev_id = clock[clk_id].clk_id;

	for (j = 0; j < num_nodes; j++) {
		/*
		 * Clock name received from firmware is output clock name.
		 * Intermediate clock names are postfixed with type of clock.
		 */
		if (j != (num_nodes - 1)) {
			clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name,
					    clk_type_postfix[nodes[j].type]);
		} else {
			clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name);
		}

		if (!clk_topology[nodes[j].type])
			continue;

		hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id,
						    parent_names,
						    num_parents,
						    &nodes[j]);
		if (IS_ERR(hw))
			pr_warn_once("%s() 0x%x: %s register fail with %ld\n",
				     __func__,  clk_dev_id, clk_name,
				     PTR_ERR(hw));

		parent_names[0] = clk_out[j];
	}

	for (j = 0; j < num_nodes; j++)
		kfree(clk_out[j]);

	return hw;
}

/**
 * zynqmp_register_clocks() - Register clocks
 * @np:		Device node
 *
 * Return: 0 on success else error code
 */
static int zynqmp_register_clocks(struct device_node *np)
{
	int ret;
	u32 i, total_parents = 0, type = 0;
	const char *parent_names[MAX_PARENT];

	for (i = 0; i < clock_max_idx; i++) {
		char clk_name[MAX_NAME_LEN];

		/* get clock name, continue to next clock if name not found */
		if (zynqmp_get_clock_name(i, clk_name))
			continue;

		/* Check if clock is valid and output clock.
		 * Do not register invalid or external clock.
		 */
		ret = zynqmp_get_clock_type(i, &type);
		if (ret || type != CLK_TYPE_OUTPUT)
			continue;

		/* Get parents of clock*/
		if (zynqmp_get_parent_list(np, i, parent_names,
					   &total_parents)) {
			WARN_ONCE(1, "No parents found for %s\n",
				  clock[i].clk_name);
			continue;
		}

		zynqmp_data->hws[i] =
			zynqmp_register_clk_topology(i, clk_name,
						     total_parents,
						     parent_names);
	}

	for (i = 0; i < clock_max_idx; i++) {
		if (IS_ERR(zynqmp_data->hws[i])) {
			pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n",
			       clock[i].clk_name, PTR_ERR(zynqmp_data->hws[i]));
			WARN_ON(1);
		}
	}
	return 0;
}

/**
 * zynqmp_get_clock_info() - Get clock information from firmware using PM_API
 */
static void zynqmp_get_clock_info(void)
{
	int i, ret;
	u32 type = 0;
	u32 nodetype, subclass, class;
	struct attr_resp attr;
	struct name_resp name;

	for (i = 0; i < clock_max_idx; i++) {
		ret = zynqmp_pm_clock_get_attributes(i, &attr);
		if (ret)
			continue;

		clock[i].valid = FIELD_GET(CLK_ATTR_VALID, attr.attr[0]);
		/* skip query for Invalid clock */
		ret = zynqmp_is_valid_clock(i);
		if (ret != CLK_ATTR_VALID)
			continue;

		clock[i].type = FIELD_GET(CLK_ATTR_TYPE, attr.attr[0]) ?
			CLK_TYPE_EXTERNAL : CLK_TYPE_OUTPUT;

		nodetype = FIELD_GET(CLK_ATTR_NODE_TYPE, attr.attr[0]);
		subclass = FIELD_GET(CLK_ATTR_NODE_SUBCLASS, attr.attr[0]);
		class = FIELD_GET(CLK_ATTR_NODE_CLASS, attr.attr[0]);

		clock[i].clk_id = FIELD_PREP(CLK_ATTR_NODE_CLASS, class) |
				  FIELD_PREP(CLK_ATTR_NODE_SUBCLASS, subclass) |
				  FIELD_PREP(CLK_ATTR_NODE_TYPE, nodetype) |
				  FIELD_PREP(CLK_ATTR_NODE_INDEX, i);

		zynqmp_pm_clock_get_name(clock[i].clk_id, &name);

		/*
		 * Terminate with NULL character in case name provided by firmware
		 * is longer and truncated due to size limit.
		 */
		name.name[sizeof(name.name) - 1] = '\0';

		if (!strcmp(name.name, RESERVED_CLK_NAME))
			continue;
		strscpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
	}

	/* Get topology of all clock */
	for (i = 0; i < clock_max_idx; i++) {
		ret = zynqmp_get_clock_type(i, &type);
		if (ret || type != CLK_TYPE_OUTPUT)
			continue;

		ret = zynqmp_clock_get_topology(i, clock[i].node,
						&clock[i].num_nodes);
		if (ret)
			continue;

		ret = zynqmp_clock_get_parents(i, clock[i].parent,
					       &clock[i].num_parents);
		if (ret)
			continue;
	}
}

/**
 * zynqmp_clk_setup() - Setup the clock framework and register clocks
 * @np:		Device node
 *
 * Return: 0 on success else error code
 */
static int zynqmp_clk_setup(struct device_node *np)
{
	int ret;

	ret = zynqmp_pm_clock_get_num_clocks(&clock_max_idx);
	if (ret)
		return ret;

	zynqmp_data = kzalloc(struct_size(zynqmp_data, hws, clock_max_idx),
			      GFP_KERNEL);
	if (!zynqmp_data)
		return -ENOMEM;

	clock = kcalloc(clock_max_idx, sizeof(*clock), GFP_KERNEL);
	if (!clock) {
		kfree(zynqmp_data);
		return -ENOMEM;
	}

	zynqmp_get_clock_info();
	zynqmp_register_clocks(np);

	zynqmp_data->num = clock_max_idx;
	return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, zynqmp_data);
}

static int zynqmp_clock_probe(struct platform_device *pdev)
{
	int ret;
	struct device *dev = &pdev->dev;

	ret = zynqmp_clk_setup(dev->of_node);

	return ret;
}

static const struct of_device_id zynqmp_clock_of_match[] = {
	{.compatible = "xlnx,zynqmp-clk"},
	{.compatible = "xlnx,versal-clk"},
	{},
};
MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match);

static struct platform_driver zynqmp_clock_driver = {
	.driver = {
		.name = "zynqmp_clock",
		.of_match_table = zynqmp_clock_of_match,
	},
	.probe = zynqmp_clock_probe,
};
module_platform_driver(zynqmp_clock_driver);
