diff -drupN a/drivers/clk/sunxi/clk-sun4i-display.c b/drivers/clk/sunxi/clk-sun4i-display.c --- a/drivers/clk/sunxi/clk-sun4i-display.c 2018-08-06 17:23:04.000000000 +0300 +++ b/drivers/clk/sunxi/clk-sun4i-display.c 1970-01-01 03:00:00.000000000 +0300 @@ -1,264 +0,0 @@ -/* - * Copyright 2015 Maxime Ripard - * - * Maxime Ripard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -struct sun4i_a10_display_clk_data { - bool has_div; - u8 num_rst; - u8 parents; - - u8 offset_en; - u8 offset_div; - u8 offset_mux; - u8 offset_rst; - - u8 width_div; - u8 width_mux; - - u32 flags; -}; - -struct reset_data { - void __iomem *reg; - spinlock_t *lock; - struct reset_controller_dev rcdev; - u8 offset; -}; - -static DEFINE_SPINLOCK(sun4i_a10_display_lock); - -static inline struct reset_data *rcdev_to_reset_data(struct reset_controller_dev *rcdev) -{ - return container_of(rcdev, struct reset_data, rcdev); -}; - -static int sun4i_a10_display_assert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct reset_data *data = rcdev_to_reset_data(rcdev); - unsigned long flags; - u32 reg; - - spin_lock_irqsave(data->lock, flags); - - reg = readl(data->reg); - writel(reg & ~BIT(data->offset + id), data->reg); - - spin_unlock_irqrestore(data->lock, flags); - - return 0; -} - -static int sun4i_a10_display_deassert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct reset_data *data = rcdev_to_reset_data(rcdev); - unsigned long flags; - u32 reg; - - spin_lock_irqsave(data->lock, flags); - - reg = readl(data->reg); - writel(reg | BIT(data->offset + id), data->reg); - - spin_unlock_irqrestore(data->lock, flags); - - return 0; -} - -static int sun4i_a10_display_status(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct reset_data *data = rcdev_to_reset_data(rcdev); - - return !(readl(data->reg) & BIT(data->offset + id)); -} - -static const struct reset_control_ops sun4i_a10_display_reset_ops = { - .assert = sun4i_a10_display_assert, - .deassert = sun4i_a10_display_deassert, - .status = sun4i_a10_display_status, -}; - -static int sun4i_a10_display_reset_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *spec) -{ - /* We only have a single reset signal */ - return 0; -} - -static void __init sun4i_a10_display_init(struct device_node *node, - const struct sun4i_a10_display_clk_data *data) -{ - const char *parents[4]; - const char *clk_name = node->name; - struct reset_data *reset_data; - struct clk_divider *div = NULL; - struct clk_gate *gate; - struct resource res; - struct clk_mux *mux; - void __iomem *reg; - struct clk *clk; - int ret; - - of_property_read_string(node, "clock-output-names", &clk_name); - - reg = of_io_request_and_map(node, 0, of_node_full_name(node)); - if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", clk_name); - return; - } - - ret = of_clk_parent_fill(node, parents, data->parents); - if (ret != data->parents) { - pr_err("%s: Could not retrieve the parents\n", clk_name); - goto unmap; - } - - mux = kzalloc(sizeof(*mux), GFP_KERNEL); - if (!mux) - goto unmap; - - mux->reg = reg; - mux->shift = data->offset_mux; - mux->mask = (1 << data->width_mux) - 1; - mux->lock = &sun4i_a10_display_lock; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) - goto free_mux; - - gate->reg = reg; - gate->bit_idx = data->offset_en; - gate->lock = &sun4i_a10_display_lock; - - if (data->has_div) { - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - goto free_gate; - - div->reg = reg; - div->shift = data->offset_div; - div->width = data->width_div; - div->lock = &sun4i_a10_display_lock; - } - - clk = clk_register_composite(NULL, clk_name, - parents, data->parents, - &mux->hw, &clk_mux_ops, - data->has_div ? &div->hw : NULL, - data->has_div ? &clk_divider_ops : NULL, - &gate->hw, &clk_gate_ops, - data->flags); - if (IS_ERR(clk)) { - pr_err("%s: Couldn't register the clock\n", clk_name); - goto free_div; - } - - ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); - if (ret) { - pr_err("%s: Couldn't register DT provider\n", clk_name); - goto free_clk; - } - - if (!data->num_rst) - return; - - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); - if (!reset_data) - goto free_of_clk; - - reset_data->reg = reg; - reset_data->offset = data->offset_rst; - reset_data->lock = &sun4i_a10_display_lock; - reset_data->rcdev.nr_resets = data->num_rst; - reset_data->rcdev.ops = &sun4i_a10_display_reset_ops; - reset_data->rcdev.of_node = node; - - if (data->num_rst == 1) { - reset_data->rcdev.of_reset_n_cells = 0; - reset_data->rcdev.of_xlate = &sun4i_a10_display_reset_xlate; - } else { - reset_data->rcdev.of_reset_n_cells = 1; - } - - if (reset_controller_register(&reset_data->rcdev)) { - pr_err("%s: Couldn't register the reset controller\n", - clk_name); - goto free_reset; - } - - return; - -free_reset: - kfree(reset_data); -free_of_clk: - of_clk_del_provider(node); -free_clk: - clk_unregister_composite(clk); -free_div: - kfree(div); -free_gate: - kfree(gate); -free_mux: - kfree(mux); -unmap: - iounmap(reg); - of_address_to_resource(node, 0, &res); - release_mem_region(res.start, resource_size(&res)); -} - -static const struct sun4i_a10_display_clk_data sun4i_a10_tcon_ch0_data __initconst = { - .num_rst = 2, - .parents = 4, - .offset_en = 31, - .offset_rst = 29, - .offset_mux = 24, - .width_mux = 2, - .flags = CLK_SET_RATE_PARENT, -}; - -static void __init sun4i_a10_tcon_ch0_setup(struct device_node *node) -{ - sun4i_a10_display_init(node, &sun4i_a10_tcon_ch0_data); -} -CLK_OF_DECLARE(sun4i_a10_tcon_ch0, "allwinner,sun4i-a10-tcon-ch0-clk", - sun4i_a10_tcon_ch0_setup); - -static const struct sun4i_a10_display_clk_data sun4i_a10_display_data __initconst = { - .has_div = true, - .num_rst = 1, - .parents = 3, - .offset_en = 31, - .offset_rst = 30, - .offset_mux = 24, - .offset_div = 0, - .width_mux = 2, - .width_div = 4, -}; - -static void __init sun4i_a10_display_setup(struct device_node *node) -{ - sun4i_a10_display_init(node, &sun4i_a10_display_data); -} -CLK_OF_DECLARE(sun4i_a10_display, "allwinner,sun4i-a10-display-clk", - sun4i_a10_display_setup);