aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk/at91/clk-peripheral.c
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2016-09-27 11:00:29 +0800
committerAndreas Bießmann <andreas@biessmann.org>2016-10-28 18:37:14 +0200
commit6cadaa046b196bebebd7acb13edd840bcfef98e2 (patch)
tree91724b2c42297e4d8f7bc5735f9881ada4a99903 /drivers/clk/at91/clk-peripheral.c
parent3f56b1321593c0081e77a3bc900177e6cf2f21d6 (diff)
clk: at91: Improve the clock implementation
For the peripheral clock, provide the clock ops for the clock provider, such as spi0_clk. The .of_xlate is to get the clk->id, the .enable is to enable the spi0 peripheral clock, the .get_rate is to get the clock frequency. The driver for periph32ck node is responsible for recursively binding its children as clk devices, not provide the clock ops. So do the generated clock and system clock. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> Acked-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/clk/at91/clk-peripheral.c')
-rw-r--r--drivers/clk/at91/clk-peripheral.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 16688e90b4..e1ed447133 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -16,7 +16,32 @@
#define PERIPHERAL_ID_MAX 31
#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
-static int sam9x5_periph_clk_enable(struct clk *clk)
+/**
+ * sam9x5_periph_clk_bind() - for the periph clock driver
+ * Recursively bind its children as clk devices.
+ *
+ * @return: 0 on success, or negative error code on failure
+ */
+static int sam9x5_periph_clk_bind(struct udevice *dev)
+{
+ return at91_clk_sub_device_bind(dev, "periph-clk");
+}
+
+static const struct udevice_id sam9x5_periph_clk_match[] = {
+ { .compatible = "atmel,at91sam9x5-clk-peripheral" },
+ {}
+};
+
+U_BOOT_DRIVER(sam9x5_periph_clk) = {
+ .name = "sam9x5-periph-clk",
+ .id = UCLASS_MISC,
+ .of_match = sam9x5_periph_clk_match,
+ .bind = sam9x5_periph_clk_bind,
+};
+
+/*---------------------------------------------------------*/
+
+static int periph_clk_enable(struct clk *clk)
{
struct pmc_platdata *plat = dev_get_platdata(clk->dev);
struct at91_pmc *pmc = plat->reg_base;
@@ -30,31 +55,36 @@ static int sam9x5_periph_clk_enable(struct clk *clk)
return 0;
}
-static struct clk_ops sam9x5_periph_clk_ops = {
- .enable = sam9x5_periph_clk_enable,
-};
-
-static int sam9x5_periph_clk_bind(struct udevice *dev)
+static ulong periph_get_rate(struct clk *clk)
{
- return at91_pmc_clk_node_bind(dev);
-}
+ struct udevice *dev;
+ struct clk clk_dev;
+ ulong clk_rate;
+ int ret;
-static int sam9x5_periph_clk_probe(struct udevice *dev)
-{
- return at91_pmc_core_probe(dev);
+ dev = dev_get_parent(clk->dev);
+
+ ret = clk_get_by_index(dev, 0, &clk_dev);
+ if (ret)
+ return ret;
+
+ clk_rate = clk_get_rate(&clk_dev);
+
+ clk_free(&clk_dev);
+
+ return clk_rate;
}
-static const struct udevice_id sam9x5_periph_clk_match[] = {
- { .compatible = "atmel,at91sam9x5-clk-peripheral" },
- {}
+static struct clk_ops periph_clk_ops = {
+ .of_xlate = at91_clk_of_xlate,
+ .enable = periph_clk_enable,
+ .get_rate = periph_get_rate,
};
-U_BOOT_DRIVER(sam9x5_periph_clk) = {
- .name = "sam9x5-periph-clk",
- .id = UCLASS_CLK,
- .of_match = sam9x5_periph_clk_match,
- .bind = sam9x5_periph_clk_bind,
- .probe = sam9x5_periph_clk_probe,
+U_BOOT_DRIVER(clk_periph) = {
+ .name = "periph-clk",
+ .id = UCLASS_CLK,
.platdata_auto_alloc_size = sizeof(struct pmc_platdata),
- .ops = &sam9x5_periph_clk_ops,
+ .probe = at91_clk_probe,
+ .ops = &periph_clk_ops,
};