From: mturquette@linaro.org (Mike Turquette)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 1/4] clk: sunxi: Rework MMC phase clocks
Date: Mon, 12 Jan 2015 16:25:10 -0800 [thread overview]
Message-ID: <20150113002510.20842.84605@quantum> (raw)
In-Reply-To: <1421006457-23631-2-git-send-email-maxime.ripard@free-electrons.com>
Quoting Maxime Ripard (2015-01-11 12:00:54)
> Instead of having three different clocks for the main MMC clock and the two
> phase sub-clocks, which involved having three different drivers sharing the
> same register, rework it to have the same single driver registering three
> different clocks.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> Reviewed-by: Chen-Yu Tsai <wens@csie.org>
> Tested-by: Chen-Yu Tsai <wens@csie.org>
Looks good to me.
Regards,
Mike
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 13 ++-
> drivers/clk/sunxi/clk-mod0.c | 131 ++++++++++++----------
> 2 files changed, 77 insertions(+), 67 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 9dc4f55a04ad..e4c42276c577 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -55,8 +55,7 @@ Required properties:
> "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
> "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
> "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
> - "allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
> - "allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
> + "allwinner,sun4i-a10-mmc-clk" - for the MMC clock
> "allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
> "allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
> "allwinner,sun7i-a20-out-clk" - for the external output clocks
> @@ -95,6 +94,10 @@ For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output
> is the normal PLL6 output, or "pll6". The second output is rate doubled
> PLL6, or "pll6x2".
>
> +The "allwinner,sun4i-a10-mmc-clk" has three different outputs: the
> +main clock, with the ID 0, and the output and sample clocks, with the
> +IDs 1 and 2, respectively.
> +
> For example:
>
> osc24M: clk at 01c20050 {
> @@ -138,11 +141,11 @@ cpu: cpu at 01c20054 {
> };
>
> mmc0_clk: clk at 01c20088 {
> - #clock-cells = <0>;
> - compatible = "allwinner,sun4i-mod0-clk";
> + #clock-cells = <1>;
> + compatible = "allwinner,sun4i-a10-mmc-clk";
> reg = <0x01c20088 0x4>;
> clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
> - clock-output-names = "mmc0";
> + clock-output-names = "mmc0", "mmc0_output", "mmc0_sample";
> };
>
> mii_phy_tx_clk: clk at 2 {
> diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c
> index bf8fcd8c940e..e37eb6fe19e8 100644
> --- a/drivers/clk/sunxi/clk-mod0.c
> +++ b/drivers/clk/sunxi/clk-mod0.c
> @@ -152,14 +152,10 @@ static void __init sun5i_a13_mbus_setup(struct device_node *node)
> }
> CLK_OF_DECLARE(sun5i_a13_mbus, "allwinner,sun5i-a13-mbus-clk", sun5i_a13_mbus_setup);
>
> -struct mmc_phase_data {
> - u8 offset;
> -};
> -
> struct mmc_phase {
> struct clk_hw hw;
> + u8 offset;
> void __iomem *reg;
> - struct mmc_phase_data *data;
> spinlock_t *lock;
> };
>
> @@ -175,7 +171,7 @@ static int mmc_get_phase(struct clk_hw *hw)
> u8 delay;
>
> value = readl(phase->reg);
> - delay = (value >> phase->data->offset) & 0x3;
> + delay = (value >> phase->offset) & 0x3;
>
> if (!delay)
> return 180;
> @@ -263,8 +259,8 @@ static int mmc_set_phase(struct clk_hw *hw, int degrees)
>
> spin_lock_irqsave(phase->lock, flags);
> value = readl(phase->reg);
> - value &= ~GENMASK(phase->data->offset + 3, phase->data->offset);
> - value |= delay << phase->data->offset;
> + value &= ~GENMASK(phase->offset + 3, phase->offset);
> + value |= delay << phase->offset;
> writel(value, phase->reg);
> spin_unlock_irqrestore(phase->lock, flags);
>
> @@ -276,66 +272,77 @@ static const struct clk_ops mmc_clk_ops = {
> .set_phase = mmc_set_phase,
> };
>
> -static void __init sun4i_a10_mmc_phase_setup(struct device_node *node,
> - struct mmc_phase_data *data)
> -{
> - const char *parent_names[1] = { of_clk_get_parent_name(node, 0) };
> - struct clk_init_data init = {
> - .num_parents = 1,
> - .parent_names = parent_names,
> - .ops = &mmc_clk_ops,
> - };
> -
> - struct mmc_phase *phase;
> - struct clk *clk;
> -
> - phase = kmalloc(sizeof(*phase), GFP_KERNEL);
> - if (!phase)
> - return;
> -
> - phase->hw.init = &init;
> +static DEFINE_SPINLOCK(sun4i_a10_mmc_lock);
>
> - phase->reg = of_iomap(node, 0);
> - if (!phase->reg)
> - goto err_free;
> +static void __init sun4i_a10_mmc_setup(struct device_node *node)
> +{
> + struct clk_onecell_data *clk_data;
> + const char *parent;
> + void __iomem *reg;
> + int i;
>
> - phase->data = data;
> - phase->lock = &sun4i_a10_mod0_lock;
> + reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> + if (IS_ERR(reg)) {
> + pr_err("Couldn't map the %s clock registers\n", node->name);
> + return;
> + }
>
> - if (of_property_read_string(node, "clock-output-names", &init.name))
> - init.name = node->name;
> + clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL);
> + if (!clk_data)
> + return;
>
> - clk = clk_register(NULL, &phase->hw);
> - if (IS_ERR(clk))
> - goto err_unmap;
> + clk_data->clks = kcalloc(3, sizeof(*clk_data->clks), GFP_KERNEL);
> + if (!clk_data->clks)
> + goto err_free_data;
> +
> + clk_data->clk_num = 3;
> + clk_data->clks[0] = sunxi_factors_register(node,
> + &sun4i_a10_mod0_data,
> + &sun4i_a10_mmc_lock, reg);
> + if (!clk_data->clks[0])
> + goto err_free_clks;
> +
> + parent = __clk_get_name(clk_data->clks[0]);
> +
> + for (i = 1; i < 3; i++) {
> + struct clk_init_data init = {
> + .num_parents = 1,
> + .parent_names = &parent,
> + .ops = &mmc_clk_ops,
> + };
> + struct mmc_phase *phase;
> +
> + phase = kmalloc(sizeof(*phase), GFP_KERNEL);
> + if (!phase)
> + continue;
> +
> + phase->hw.init = &init;
> + phase->reg = reg;
> + phase->lock = &sun4i_a10_mmc_lock;
> +
> + if (i == 1)
> + phase->offset = 8;
> + else
> + phase->offset = 20;
> +
> + if (of_property_read_string_index(node, "clock-output-names",
> + i, &init.name))
> + init.name = node->name;
> +
> + clk_data->clks[i] = clk_register(NULL, &phase->hw);
> + if (IS_ERR(clk_data->clks[i])) {
> + kfree(phase);
> + continue;
> + }
> + }
>
> - of_clk_add_provider(node, of_clk_src_simple_get, clk);
> + of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>
> return;
>
> -err_unmap:
> - iounmap(phase->reg);
> -err_free:
> - kfree(phase);
> -}
> -
> -
> -static struct mmc_phase_data mmc_output_clk = {
> - .offset = 8,
> -};
> -
> -static struct mmc_phase_data mmc_sample_clk = {
> - .offset = 20,
> -};
> -
> -static void __init sun4i_a10_mmc_output_setup(struct device_node *node)
> -{
> - sun4i_a10_mmc_phase_setup(node, &mmc_output_clk);
> -}
> -CLK_OF_DECLARE(sun4i_a10_mmc_output, "allwinner,sun4i-a10-mmc-output-clk", sun4i_a10_mmc_output_setup);
> -
> -static void __init sun4i_a10_mmc_sample_setup(struct device_node *node)
> -{
> - sun4i_a10_mmc_phase_setup(node, &mmc_sample_clk);
> +err_free_clks:
> + kfree(clk_data->clks);
> +err_free_data:
> + kfree(clk_data);
> }
> -CLK_OF_DECLARE(sun4i_a10_mmc_sample, "allwinner,sun4i-a10-mmc-sample-clk", sun4i_a10_mmc_sample_setup);
> +CLK_OF_DECLARE(sun4i_a10_mmc, "allwinner,sun4i-a10-mmc-clk", sun4i_a10_mmc_setup);
> --
> 2.2.1
>
next prev parent reply other threads:[~2015-01-13 0:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-11 20:00 [PATCH v3 0/4] clk: sunxi: mmc: Last bits of phase handling Maxime Ripard
2015-01-11 20:00 ` [PATCH v3 1/4] clk: sunxi: Rework MMC phase clocks Maxime Ripard
2015-01-13 0:25 ` Mike Turquette [this message]
2015-01-11 20:00 ` [PATCH v3 2/4] ARM: sunxi: dt: Add sample and output mmc clocks Maxime Ripard
2015-01-11 20:00 ` [PATCH v3 3/4] mmc: sunxi: Convert MMC driver to the standard clock phase API Maxime Ripard
2015-01-11 20:00 ` [PATCH v3 4/4] clk: sunxi: Remove custom phase function Maxime Ripard
2015-01-14 9:46 ` [PATCH v3 0/4] clk: sunxi: mmc: Last bits of phase handling Maxime Ripard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150113002510.20842.84605@quantum \
--to=mturquette@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.