/*
 * Copyright (C) 2014 Chen-Yu Tsai
 * Author: Chen-Yu Tsai <wens@csie.org>
 *
 * Allwinner A23 APB0 clock driver
 *
 * License Terms: GNU General Public License v2
 *
 * Based on clk-sun6i-apb0.c
 * Allwinner A31 APB0 clock driver
 *
 * Copyright (C) 2014 Free Electrons
 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
 *
 */

#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>

static struct clk *sun8i_a23_apb0_register(struct device_node *node,
					   void __iomem *reg)
{
	const char *clk_name = node->name;
	const char *clk_parent;
	struct clk *clk;
	int ret;

	clk_parent = of_clk_get_parent_name(node, 0);
	if (!clk_parent)
		return ERR_PTR(-EINVAL);

	of_property_read_string(node, "clock-output-names", &clk_name);

	/* The A23 APB0 clock is a standard 2 bit wide divider clock */
	clk = clk_register_divider(NULL, clk_name, clk_parent, 0, reg,
				   0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
	if (IS_ERR(clk))
		return clk;

	ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
	if (ret)
		goto err_unregister;

	return clk;

err_unregister:
	clk_unregister_divider(clk);

	return ERR_PTR(ret);
}

static void sun8i_a23_apb0_setup(struct device_node *node)
{
	void __iomem *reg;
	struct resource res;
	struct clk *clk;

	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(reg)) {
		/*
		 * This happens with clk nodes instantiated through mfd,
		 * as those do not have their resources assigned in the
		 * device tree. Do not print an error in this case.
		 */
		if (PTR_ERR(reg) != -EINVAL)
			pr_err("Could not get registers for a23-apb0-clk\n");

		return;
	}

	clk = sun8i_a23_apb0_register(node, reg);
	if (IS_ERR(clk))
		goto err_unmap;

	return;

err_unmap:
	iounmap(reg);
	of_address_to_resource(node, 0, &res);
	release_mem_region(res.start, resource_size(&res));
}
CLK_OF_DECLARE(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk",
	       sun8i_a23_apb0_setup);

static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct resource *r;
	void __iomem *reg;
	struct clk *clk;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	reg = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(reg))
		return PTR_ERR(reg);

	clk = sun8i_a23_apb0_register(np, reg);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	return 0;
}

static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
	{ .compatible = "allwinner,sun8i-a23-apb0-clk" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids);

static struct platform_driver sun8i_a23_apb0_clk_driver = {
	.driver = {
		.name = "sun8i-a23-apb0-clk",
		.of_match_table = sun8i_a23_apb0_clk_dt_ids,
	},
	.probe = sun8i_a23_apb0_clk_probe,
};
module_platform_driver(sun8i_a23_apb0_clk_driver);

MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
MODULE_DESCRIPTION("Allwinner A23 APB0 clock Driver");
MODULE_LICENSE("GPL v2");
