From: sassmann@kpanic.de (Stefan Assmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] clk: initial clock driver for TWL6030
Date: Wed, 30 Jul 2014 16:02:29 +0200 [thread overview]
Message-ID: <1406728949-7560-3-git-send-email-sassmann@kpanic.de> (raw)
In-Reply-To: <1406728949-7560-1-git-send-email-sassmann@kpanic.de>
Adding a clock driver for the TI TWL6030. The driver prepares the
CLK32KG clock, which is required for the wireless LAN.
Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
---
.../devicetree/bindings/clock/ti/twl6030.txt | 4 +
drivers/clk/Kconfig | 7 +
drivers/clk/ti/Makefile | 1 +
drivers/clk/ti/clk-6030.c | 141 +++++++++++++++++++++
drivers/mfd/twl-core.c | 3 +
5 files changed, 156 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/twl6030.txt
create mode 100644 drivers/clk/ti/clk-6030.c
diff --git a/Documentation/devicetree/bindings/clock/ti/twl6030.txt b/Documentation/devicetree/bindings/clock/ti/twl6030.txt
new file mode 100644
index 0000000..d290ad4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/twl6030.txt
@@ -0,0 +1,4 @@
+Binding for TI TWL6030.
+
+Required properties:
+- compatible: "ti,twl6030-clk32kg"
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9f9c5ae..4e89e8b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -65,6 +65,13 @@ config COMMON_CLK_S2MPS11
clock. These multi-function devices have two (S2MPS14) or three
(S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
+config CLK_TWL6030
+ tristate "Clock driver for twl6030"
+ depends on TWL4030_CORE
+ ---help---
+ Enable the TWL6030 clock CLK32KG which is disabled by default.
+ Needed on the Pandaboard for the wireless LAN.
+
config CLK_TWL6040
tristate "External McPDM functional clock from twl6040"
depends on TWL6040_CORE
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index ed4d0aa..04f25ea 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o
obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o \
clk-dra7-atl.o
obj-$(CONFIG_SOC_AM43XX) += $(clk-common) clk-43xx.o
+obj-$(CONFIG_CLK_TWL6030) += $(clk-common) clk-6030.o
endif
diff --git a/drivers/clk/ti/clk-6030.c b/drivers/clk/ti/clk-6030.c
new file mode 100644
index 0000000..baa965b
--- /dev/null
+++ b/drivers/clk/ti/clk-6030.c
@@ -0,0 +1,141 @@
+/*
+ * drivers/clk/ti/clk-6030.c
+ *
+ * Copyright (C) 2014 Stefan Assmann <sassmann@kpanic.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Clock driver for ti twl6030.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+
+struct twl6030_desc {
+ struct clk *clk;
+ struct clk_hw hw;
+ bool enabled;
+};
+
+#define to_twl6030_desc(_hw) container_of(_hw, struct twl6030_desc, hw)
+
+static int twl6030_clk32kg_prepare(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+ int ret;
+
+ ret = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+ TWL6030_GRP_CON << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_ON,
+ TWL6030_PM_RECEIVER_CLK32KG_CFG_STATE);
+ if (ret == 0)
+ desc->enabled = true;
+
+ return ret;
+}
+void twl6030_clk32kg_unprepare(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+ TWL6030_GRP_CON << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_OFF,
+ TWL6030_PM_RECEIVER_CLK32KG_CFG_STATE);
+ desc->enabled = false;
+}
+
+static int twl6030_clk32kg_is_prepared(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+
+ return desc->enabled;
+}
+
+static const struct clk_ops twl6030_clk32kg_ops = {
+ .prepare = twl6030_clk32kg_prepare,
+ .unprepare = twl6030_clk32kg_unprepare,
+ .is_prepared = twl6030_clk32kg_is_prepared,
+};
+
+static void __init of_ti_twl6030_clk32kg_setup(struct device_node *node)
+{
+ struct twl6030_desc *clk_hw = NULL;
+ struct clk_init_data init = { 0 };
+ struct clk_lookup *clookup;
+ struct clk *clk;
+
+ clookup = kzalloc(sizeof(*clookup), GFP_KERNEL);
+ if (!clookup) {
+ pr_err("%s: could not allocate clookup\n", __func__);
+ return;
+ }
+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+ if (!clk_hw) {
+ pr_err("%s: could not allocate clk_hw\n", __func__);
+ goto err_clk_hw;
+ }
+
+ clk_hw->hw.init = &init;
+
+ init.name = node->name;
+ init.ops = &twl6030_clk32kg_ops;
+ init.flags = CLK_IS_ROOT;
+
+ clk = clk_register(NULL, &clk_hw->hw);
+ if (!IS_ERR(clk)) {
+ clookup->con_id = kstrdup("clk32kg", GFP_KERNEL);
+ clookup->clk = clk;
+ clkdev_add(clookup);
+
+ return;
+ }
+
+ kfree(clookup);
+err_clk_hw:
+ kfree(clk_hw);
+}
+CLK_OF_DECLARE(of_ti_twl6030_clk32kg, "ti,twl6030-clk32kg", of_ti_twl6030_clk32kg_setup);
+
+static int of_twl6030_clk32kg_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct clk *clk;
+ int ret = 0;
+
+ if (!node)
+ return -ENODEV;
+
+ clk = clk_get(&pdev->dev, "clk32kg");
+ if (IS_ERR(clk))
+ ret = -EPROBE_DEFER;
+ else
+ clk_prepare(clk);
+
+ return ret;
+}
+
+static struct of_device_id of_twl6030_clk32kg_match_tbl[] = {
+ { .compatible = "ti,twl6030-clk32kg", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_twl6030_clk32kg_match_tbl);
+
+static struct platform_driver twl6030_clk_driver = {
+ .driver = {
+ .name = "twl6030-clk32kg",
+ .owner = THIS_MODULE,
+ .of_match_table = of_twl6030_clk32kg_match_tbl,
+ },
+ .probe = of_twl6030_clk32kg_probe,
+};
+module_platform_driver(twl6030_clk_driver);
+
+MODULE_AUTHOR("Stefan Assmann <sassmann@kpanic.de>");
+MODULE_DESCRIPTION("clock driver for TI SoC based boards with twl6030");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index db11b4f..440fe4e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/of.h>
@@ -1012,6 +1013,8 @@ static void clocks_init(struct device *dev,
u32 rate;
u8 ctrl = HFCLK_FREQ_26_MHZ;
+ of_clk_init(NULL);
+
osc = clk_get(dev, "fck");
if (IS_ERR(osc)) {
printk(KERN_WARNING "Skipping twl internal clock init and "
--
1.9.3
WARNING: multiple messages have this Message-ID (diff)
From: Stefan Assmann <sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org>
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
pawel.moll-5wv7dgnIgG8@public.gmane.org,
peter.ujfalusi-l0cyMroinI0@public.gmane.org,
t-kristo-l0cyMroinI0@public.gmane.org,
sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org
Subject: [PATCH 2/2] clk: initial clock driver for TWL6030
Date: Wed, 30 Jul 2014 16:02:29 +0200 [thread overview]
Message-ID: <1406728949-7560-3-git-send-email-sassmann@kpanic.de> (raw)
In-Reply-To: <1406728949-7560-1-git-send-email-sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org>
Adding a clock driver for the TI TWL6030. The driver prepares the
CLK32KG clock, which is required for the wireless LAN.
Signed-off-by: Stefan Assmann <sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org>
---
.../devicetree/bindings/clock/ti/twl6030.txt | 4 +
drivers/clk/Kconfig | 7 +
drivers/clk/ti/Makefile | 1 +
drivers/clk/ti/clk-6030.c | 141 +++++++++++++++++++++
drivers/mfd/twl-core.c | 3 +
5 files changed, 156 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti/twl6030.txt
create mode 100644 drivers/clk/ti/clk-6030.c
diff --git a/Documentation/devicetree/bindings/clock/ti/twl6030.txt b/Documentation/devicetree/bindings/clock/ti/twl6030.txt
new file mode 100644
index 0000000..d290ad4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/twl6030.txt
@@ -0,0 +1,4 @@
+Binding for TI TWL6030.
+
+Required properties:
+- compatible: "ti,twl6030-clk32kg"
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9f9c5ae..4e89e8b 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -65,6 +65,13 @@ config COMMON_CLK_S2MPS11
clock. These multi-function devices have two (S2MPS14) or three
(S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
+config CLK_TWL6030
+ tristate "Clock driver for twl6030"
+ depends on TWL4030_CORE
+ ---help---
+ Enable the TWL6030 clock CLK32KG which is disabled by default.
+ Needed on the Pandaboard for the wireless LAN.
+
config CLK_TWL6040
tristate "External McPDM functional clock from twl6040"
depends on TWL6040_CORE
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index ed4d0aa..04f25ea 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o
obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o \
clk-dra7-atl.o
obj-$(CONFIG_SOC_AM43XX) += $(clk-common) clk-43xx.o
+obj-$(CONFIG_CLK_TWL6030) += $(clk-common) clk-6030.o
endif
diff --git a/drivers/clk/ti/clk-6030.c b/drivers/clk/ti/clk-6030.c
new file mode 100644
index 0000000..baa965b
--- /dev/null
+++ b/drivers/clk/ti/clk-6030.c
@@ -0,0 +1,141 @@
+/*
+ * drivers/clk/ti/clk-6030.c
+ *
+ * Copyright (C) 2014 Stefan Assmann <sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Clock driver for ti twl6030.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+
+struct twl6030_desc {
+ struct clk *clk;
+ struct clk_hw hw;
+ bool enabled;
+};
+
+#define to_twl6030_desc(_hw) container_of(_hw, struct twl6030_desc, hw)
+
+static int twl6030_clk32kg_prepare(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+ int ret;
+
+ ret = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+ TWL6030_GRP_CON << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_ON,
+ TWL6030_PM_RECEIVER_CLK32KG_CFG_STATE);
+ if (ret == 0)
+ desc->enabled = true;
+
+ return ret;
+}
+void twl6030_clk32kg_unprepare(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+
+ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
+ TWL6030_GRP_CON << TWL6030_CFG_STATE_GRP_SHIFT |
+ TWL6030_CFG_STATE_OFF,
+ TWL6030_PM_RECEIVER_CLK32KG_CFG_STATE);
+ desc->enabled = false;
+}
+
+static int twl6030_clk32kg_is_prepared(struct clk_hw *hw)
+{
+ struct twl6030_desc *desc = to_twl6030_desc(hw);
+
+ return desc->enabled;
+}
+
+static const struct clk_ops twl6030_clk32kg_ops = {
+ .prepare = twl6030_clk32kg_prepare,
+ .unprepare = twl6030_clk32kg_unprepare,
+ .is_prepared = twl6030_clk32kg_is_prepared,
+};
+
+static void __init of_ti_twl6030_clk32kg_setup(struct device_node *node)
+{
+ struct twl6030_desc *clk_hw = NULL;
+ struct clk_init_data init = { 0 };
+ struct clk_lookup *clookup;
+ struct clk *clk;
+
+ clookup = kzalloc(sizeof(*clookup), GFP_KERNEL);
+ if (!clookup) {
+ pr_err("%s: could not allocate clookup\n", __func__);
+ return;
+ }
+ clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+ if (!clk_hw) {
+ pr_err("%s: could not allocate clk_hw\n", __func__);
+ goto err_clk_hw;
+ }
+
+ clk_hw->hw.init = &init;
+
+ init.name = node->name;
+ init.ops = &twl6030_clk32kg_ops;
+ init.flags = CLK_IS_ROOT;
+
+ clk = clk_register(NULL, &clk_hw->hw);
+ if (!IS_ERR(clk)) {
+ clookup->con_id = kstrdup("clk32kg", GFP_KERNEL);
+ clookup->clk = clk;
+ clkdev_add(clookup);
+
+ return;
+ }
+
+ kfree(clookup);
+err_clk_hw:
+ kfree(clk_hw);
+}
+CLK_OF_DECLARE(of_ti_twl6030_clk32kg, "ti,twl6030-clk32kg", of_ti_twl6030_clk32kg_setup);
+
+static int of_twl6030_clk32kg_probe(struct platform_device *pdev)
+{
+ struct device_node *node = pdev->dev.of_node;
+ struct clk *clk;
+ int ret = 0;
+
+ if (!node)
+ return -ENODEV;
+
+ clk = clk_get(&pdev->dev, "clk32kg");
+ if (IS_ERR(clk))
+ ret = -EPROBE_DEFER;
+ else
+ clk_prepare(clk);
+
+ return ret;
+}
+
+static struct of_device_id of_twl6030_clk32kg_match_tbl[] = {
+ { .compatible = "ti,twl6030-clk32kg", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_twl6030_clk32kg_match_tbl);
+
+static struct platform_driver twl6030_clk_driver = {
+ .driver = {
+ .name = "twl6030-clk32kg",
+ .owner = THIS_MODULE,
+ .of_match_table = of_twl6030_clk32kg_match_tbl,
+ },
+ .probe = of_twl6030_clk32kg_probe,
+};
+module_platform_driver(twl6030_clk_driver);
+
+MODULE_AUTHOR("Stefan Assmann <sassmann-llIHtaV5axyzQB+pC5nmwQ@public.gmane.org>");
+MODULE_DESCRIPTION("clock driver for TI SoC based boards with twl6030");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index db11b4f..440fe4e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/of.h>
@@ -1012,6 +1013,8 @@ static void clocks_init(struct device *dev,
u32 rate;
u8 ctrl = HFCLK_FREQ_26_MHZ;
+ of_clk_init(NULL);
+
osc = clk_get(dev, "fck");
if (IS_ERR(osc)) {
printk(KERN_WARNING "Skipping twl internal clock init and "
--
1.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2014-07-30 14:02 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-30 14:02 [PATCH 0/2] Enable wifi on pandaboard Stefan Assmann
2014-07-30 14:02 ` Stefan Assmann
2014-07-30 14:02 ` [PATCH 1/2] mfd: twl-core: move TWL6030 defines to twl.h Stefan Assmann
2014-07-30 14:02 ` Stefan Assmann
2014-07-31 8:36 ` Lee Jones
2014-07-31 8:36 ` Lee Jones
2014-07-31 8:46 ` Stefan Assmann
2014-07-31 8:46 ` Stefan Assmann
2014-07-30 14:02 ` Stefan Assmann [this message]
2014-07-30 14:02 ` [PATCH 2/2] clk: initial clock driver for TWL6030 Stefan Assmann
2014-07-30 14:29 ` Andreas Färber
2014-07-30 14:29 ` Andreas Färber
2014-07-30 14:36 ` Stefan Assmann
2014-07-30 14:36 ` Stefan Assmann
2014-07-30 17:50 ` Mark Brown
2014-07-30 17:50 ` Mark Brown
2014-07-31 9:56 ` Stefan Assmann
2014-07-31 9:56 ` Stefan Assmann
2014-07-31 11:05 ` Mark Brown
2014-07-31 11:05 ` Mark Brown
2014-07-31 12:04 ` Stefan Assmann
2014-07-31 12:04 ` Stefan Assmann
2014-07-31 19:14 ` Mike Turquette
2014-07-31 19:14 ` Mike Turquette
2014-07-31 11:28 ` Tero Kristo
2014-07-31 11:28 ` Tero Kristo
2014-07-31 11:58 ` Stefan Assmann
2014-07-31 11:58 ` Stefan Assmann
2014-07-31 13:16 ` Tero Kristo
2014-07-31 13:16 ` Tero Kristo
2014-07-31 12:26 ` Peter Ujfalusi
2014-07-31 12:26 ` Peter Ujfalusi
2014-07-31 12:54 ` Stefan Assmann
2014-07-31 12:54 ` Stefan Assmann
2014-07-31 12:58 ` Peter Ujfalusi
2014-07-31 12:58 ` Peter Ujfalusi
2014-07-31 14:05 ` Stefan Assmann
2014-07-31 14:05 ` Stefan Assmann
2014-07-31 19:20 ` Mike Turquette
2014-07-31 19:20 ` Mike Turquette
2014-08-01 10:04 ` Stefan Assmann
2014-08-01 10:04 ` Stefan Assmann
2014-08-01 10:38 ` Mark Brown
2014-08-01 10:38 ` Mark Brown
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=1406728949-7560-3-git-send-email-sassmann@kpanic.de \
--to=sassmann@kpanic.de \
--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.