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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox