X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fclk%2Fh8300%2Fclk-div.c;fp=kernel%2Fdrivers%2Fclk%2Fh8300%2Fclk-div.c;h=d71d01157dbb0ee0fe468db4f6f3156675936ce9;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hp=0000000000000000000000000000000000000000;hpb=f93b97fd65072de626c074dbe099a1fff05ce060;p=kvmfornfv.git diff --git a/kernel/drivers/clk/h8300/clk-div.c b/kernel/drivers/clk/h8300/clk-div.c new file mode 100644 index 000000000..d71d01157 --- /dev/null +++ b/kernel/drivers/clk/h8300/clk-div.c @@ -0,0 +1,55 @@ +/* + * H8/300 divide clock driver + * + * Copyright 2015 Yoshinori Sato + */ + +#include +#include +#include +#include + +static DEFINE_SPINLOCK(clklock); + +static void __init h8300_div_clk_setup(struct device_node *node) +{ + int num_parents; + struct clk *clk; + const char *clk_name = node->name; + const char *parent_name; + void __iomem *divcr = NULL; + int width; + int offset; + + num_parents = of_clk_get_parent_count(node); + if (num_parents < 1) { + pr_err("%s: no parent found", clk_name); + return; + } + + divcr = of_iomap(node, 0); + if (divcr == NULL) { + pr_err("%s: failed to map divide register", clk_name); + goto error; + } + offset = (unsigned long)divcr & 3; + offset = (3 - offset) * 8; + divcr = (void *)((unsigned long)divcr & ~3); + + parent_name = of_clk_get_parent_name(node, 0); + of_property_read_u32(node, "renesas,width", &width); + clk = clk_register_divider(NULL, clk_name, parent_name, + CLK_SET_RATE_GATE, divcr, offset, width, + CLK_DIVIDER_POWER_OF_TWO, &clklock); + if (!IS_ERR(clk)) { + of_clk_add_provider(node, of_clk_src_simple_get, clk); + return; + } + pr_err("%s: failed to register %s div clock (%ld)\n", + __func__, clk_name, PTR_ERR(clk)); +error: + if (divcr) + iounmap(divcr); +} + +CLK_OF_DECLARE(h8300_div_clk, "renesas,h8300-div-clock", h8300_div_clk_setup);