// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
 */

#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

struct ti_syscon_gate_clk_priv {
	struct clk_hw hw;
	struct regmap *regmap;
	u32 reg;
	u32 idx;
};

struct ti_syscon_gate_clk_data {
	char *name;
	u32 offset;
	u32 bit_idx;
};

static struct
ti_syscon_gate_clk_priv *to_ti_syscon_gate_clk_priv(struct clk_hw *hw)
{
	return container_of(hw, struct ti_syscon_gate_clk_priv, hw);
}

static int ti_syscon_gate_clk_enable(struct clk_hw *hw)
{
	struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw);

	return regmap_write_bits(priv->regmap, priv->reg, priv->idx,
				 priv->idx);
}

static void ti_syscon_gate_clk_disable(struct clk_hw *hw)
{
	struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw);

	regmap_write_bits(priv->regmap, priv->reg, priv->idx, 0);
}

static int ti_syscon_gate_clk_is_enabled(struct clk_hw *hw)
{
	unsigned int val;
	struct ti_syscon_gate_clk_priv *priv = to_ti_syscon_gate_clk_priv(hw);

	regmap_read(priv->regmap, priv->reg, &val);

	return !!(val & priv->idx);
}

static const struct clk_ops ti_syscon_gate_clk_ops = {
	.enable		= ti_syscon_gate_clk_enable,
	.disable	= ti_syscon_gate_clk_disable,
	.is_enabled	= ti_syscon_gate_clk_is_enabled,
};

static struct clk_hw
*ti_syscon_gate_clk_register(struct device *dev, struct regmap *regmap,
			     const struct ti_syscon_gate_clk_data *data)
{
	struct ti_syscon_gate_clk_priv *priv;
	struct clk_init_data init;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return ERR_PTR(-ENOMEM);

	init.name = data->name;
	init.ops = &ti_syscon_gate_clk_ops;
	init.parent_names = NULL;
	init.num_parents = 0;
	init.flags = 0;

	priv->regmap = regmap;
	priv->reg = data->offset;
	priv->idx = BIT(data->bit_idx);
	priv->hw.init = &init;

	ret = devm_clk_hw_register(dev, &priv->hw);
	if (ret)
		return ERR_PTR(ret);

	return &priv->hw;
}

static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
{
	const struct ti_syscon_gate_clk_data *data, *p;
	struct clk_hw_onecell_data *hw_data;
	struct device *dev = &pdev->dev;
	struct regmap *regmap;
	int num_clks, i;

	data = device_get_match_data(dev);
	if (!data)
		return -EINVAL;

	regmap = syscon_node_to_regmap(dev->of_node);
	if (IS_ERR(regmap)) {
		if (PTR_ERR(regmap) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		dev_err(dev, "failed to find parent regmap\n");
		return PTR_ERR(regmap);
	}

	num_clks = 0;
	for (p = data; p->name; p++)
		num_clks++;

	hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks),
			       GFP_KERNEL);
	if (!hw_data)
		return -ENOMEM;

	hw_data->num = num_clks;

	for (i = 0; i < num_clks; i++) {
		hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap,
							      &data[i]);
		if (IS_ERR(hw_data->hws[i]))
			dev_warn(dev, "failed to register %s\n",
				 data[i].name);
	}

	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
					   hw_data);
}

#define TI_SYSCON_CLK_GATE(_name, _offset, _bit_idx)	\
	{						\
		.name = _name,				\
		.offset = (_offset),			\
		.bit_idx = (_bit_idx),			\
	}

static const struct ti_syscon_gate_clk_data am654_clk_data[] = {
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk0", 0x0, 0),
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk1", 0x4, 0),
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk2", 0x8, 0),
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk3", 0xc, 0),
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk4", 0x10, 0),
	TI_SYSCON_CLK_GATE("ehrpwm_tbclk5", 0x14, 0),
	{ /* Sentinel */ },
};

static const struct of_device_id ti_syscon_gate_clk_ids[] = {
	{
		.compatible = "ti,am654-ehrpwm-tbclk",
		.data = &am654_clk_data,
	},
	{ }
};
MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);

static struct platform_driver ti_syscon_gate_clk_driver = {
	.probe = ti_syscon_gate_clk_probe,
	.driver = {
		.name = "ti-syscon-gate-clk",
		.of_match_table = ti_syscon_gate_clk_ids,
	},
};
module_platform_driver(ti_syscon_gate_clk_driver);

MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>");
MODULE_DESCRIPTION("Syscon backed gate-clock driver");
MODULE_LICENSE("GPL");
