From: Mike Turquette <mturquette@linaro.org>
To: Ian Lartey <ian@slimlogic.co.uk>, linux-kernel@vger.kernel.org
Cc: linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-leds@vger.kernel.org, linux-watchdog@vger.kernel.org,
swarren@wwwdotorg.org, grant.likely@secretlab.ca,
broonie@opensource.wolfsonmicro.com, rob.herring@calxeda.com,
rob@landley.net, linus.walleij@linaro.org, cooloney@gmail.com,
rpurdie@rpsys.net, sameo@linux.intel.com, wim@iguana.be,
lgirdwood@gmail.com, gg@slimlogic.co.uk, j-keerthy@ti.com,
ldewangan@nvidia.com, t-kristo@ti.com,
Ian Lartey <ian@slimlogic.co.uk>
Subject: Re: [PATCH v8 12/12] clk: add a clock driver for palmas
Date: Thu, 21 Mar 2013 14:23:04 -0700 [thread overview]
Message-ID: <20130321212304.834.58588@quantum> (raw)
In-Reply-To: <1362662276-20792-12-git-send-email-ian@slimlogic.co.uk>
Quoting Ian Lartey (2013-03-07 05:17:56)
> Palmas has two clock generators in it, clk32kg and clk32kg audio. They
> are fixed frequency clocks that only have enable/disable functionality.
>
> Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk>
> Signed-off-by: J Keerthy <j-keerthy@ti.com>
> Signed-off-by: Ian Lartey <ian@slimlogic.co.uk>
My only complaint with this driver is that there are two sets of ops and
prepare/unprepare functions when there could be just one set. If there
existed some struct palmas_clk_hw which included members "reg" and
"ctrl_mode" (or even "enable_bit") then a single set of ops would do
just fine, instead of hard-coding those values into the functions.
Either way it's a small thing and there are only two clocks per palmas
here. Hopefully it will get cleaned up in an update some day.
Acked-by: Mike Turquette <mturquette@linaro.org>
> ---
> drivers/clk/clk-palmas.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 268 insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/clk-palmas.c
>
> diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
> new file mode 100644
> index 0000000..328eea4
> --- /dev/null
> +++ b/drivers/clk/clk-palmas.c
> @@ -0,0 +1,268 @@
> +/*
> + * PALMAS resource clock module driver
> + *
> + * Copyright (C) 2011-2013 Texas Instruments Inc.
> + * Graeme Gregory <gg@slimlogic.co.uk>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/palmas.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_platform.h>
> +
> +struct palmas_clk {
> + struct palmas *palmas;
> + struct device *dev;
> + struct clk_hw clk32kg;
> + struct clk_hw clk32kgaudio;
> + int clk32kgaudio_mode_sleep;
> + int clk32kg_mode_sleep;
> +};
> +
> +static int palmas_clock_setbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, data);
> +}
> +
> +static int palmas_clock_clrbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, 0);
> +}
> +
> +static int palmas_prepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kg_ops = {
> + .prepare = palmas_prepare_clk32kg,
> + .unprepare = palmas_unprepare_clk32kg,
> +};
> +
> +static int palmas_prepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kgaudio_ops = {
> + .prepare = palmas_prepare_clk32kgaudio,
> + .unprepare = palmas_unprepare_clk32kgaudio,
> +};
> +
> +static int palmas_initialise_clk(struct palmas_clk *palmas_clk)
> +{
> + int ret;
> +
> + if (palmas_clk->clk32kg_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + if (palmas_clk->clk32kgaudio_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL,
> + PALMAS_CLK32KGAUDIO_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void palmas_dt_to_pdata(struct device_node *node,
> + struct palmas_clk_platform_data *pdata)
> +{
> + int ret;
> + u32 prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kg-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kg_mode_sleep = prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kgaudio-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kgaudio_mode_sleep = prop;
> +}
> +
> +static int palmas_clk_probe(struct platform_device *pdev)
> +{
> + struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
> + struct palmas_clk_platform_data *pdata = pdev->dev.platform_data;
> + struct device_node *node = pdev->dev.of_node;
> + struct palmas_clk *palmas_clk;
> + struct clk *clk;
> + struct clk_init_data init_clk32g, init_clk32gaudio;
> + int ret;
> +
> + if (node && !pdata) {
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +
> + if (!pdata)
> + return -ENOMEM;
> +
> + palmas_dt_to_pdata(node, pdata);
> + }
> +
> + palmas_clk = devm_kzalloc(&pdev->dev, sizeof(*palmas_clk), GFP_KERNEL);
> + if (!palmas_clk)
> + return -ENOMEM;
> +
> + palmas_clk->palmas = palmas;
> + palmas_clk->dev = &pdev->dev;
> +
> + init_clk32g.name = "clk32kg";
> + init_clk32g.ops = &palmas_clk32kg_ops;
> + init_clk32g.parent_names = NULL;
> + init_clk32g.num_parents = 0;
> + palmas_clk->clk32kg.init = &init_clk32g;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kg);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kg clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_clk32kg;
> + }
> +
> + init_clk32gaudio.name = "clk32kgaudio";
> + init_clk32gaudio.ops = &palmas_clk32kgaudio_ops;
> + init_clk32gaudio.parent_names = NULL;
> + init_clk32gaudio.num_parents = 0;
> + palmas_clk->clk32kgaudio.init = &init_clk32gaudio;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kgaudio);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kgaudio clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_audio;
> + }
> +
> + ret = palmas_initialise_clk(palmas_clk);
> + if (ret)
> + goto err;
> +
> + dev_set_drvdata(&pdev->dev, palmas_clk);
> +
> + return 0;
> +
> +err:
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> +err_audio:
> + clk_unregister(palmas_clk->clk32kg.clk);
> +err_clk32kg:
> +
> + return ret;
> +}
> +
> +static int palmas_clk_remove(struct platform_device *pdev)
> +{
> + struct palmas_clk *palmas_clk = dev_get_drvdata(&pdev->dev);
> +
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> + clk_unregister(palmas_clk->clk32kg.clk);
> +
> + return 0;
> +}
> +
> +static struct of_device_id of_palmas_match_tbl[] = {
> + { .compatible = "ti,palmas-clk", },
> + { .compatible = "ti,palmas-charger-clk", },
> + { .compatible = "ti,twl6035-clk", },
> + { .compatible = "ti,twl6036-clk", },
> + { .compatible = "ti,twl6037-clk", },
> + { .compatible = "ti,tps65913-clk", },
> + { .compatible = "ti,tps65914-clk", },
> + { .compatible = "ti,tps80036-clk", },
> + { /* end */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
> +
> +static struct platform_driver palmas_clk_driver = {
> + .probe = palmas_clk_probe,
> + .remove = palmas_clk_remove,
> + .driver = {
> + .name = "palmas-clk",
> + .of_match_table = of_palmas_match_tbl,
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +module_platform_driver(palmas_clk_driver);
> +
> +MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
> +MODULE_DESCRIPTION("PALMAS clock driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:palmas-clk");
> --
> 1.7.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
WARNING: multiple messages have this Message-ID (diff)
From: mturquette@linaro.org (Mike Turquette)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v8 12/12] clk: add a clock driver for palmas
Date: Thu, 21 Mar 2013 14:23:04 -0700 [thread overview]
Message-ID: <20130321212304.834.58588@quantum> (raw)
In-Reply-To: <1362662276-20792-12-git-send-email-ian@slimlogic.co.uk>
Quoting Ian Lartey (2013-03-07 05:17:56)
> Palmas has two clock generators in it, clk32kg and clk32kg audio. They
> are fixed frequency clocks that only have enable/disable functionality.
>
> Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk>
> Signed-off-by: J Keerthy <j-keerthy@ti.com>
> Signed-off-by: Ian Lartey <ian@slimlogic.co.uk>
My only complaint with this driver is that there are two sets of ops and
prepare/unprepare functions when there could be just one set. If there
existed some struct palmas_clk_hw which included members "reg" and
"ctrl_mode" (or even "enable_bit") then a single set of ops would do
just fine, instead of hard-coding those values into the functions.
Either way it's a small thing and there are only two clocks per palmas
here. Hopefully it will get cleaned up in an update some day.
Acked-by: Mike Turquette <mturquette@linaro.org>
> ---
> drivers/clk/clk-palmas.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 268 insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/clk-palmas.c
>
> diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
> new file mode 100644
> index 0000000..328eea4
> --- /dev/null
> +++ b/drivers/clk/clk-palmas.c
> @@ -0,0 +1,268 @@
> +/*
> + * PALMAS resource clock module driver
> + *
> + * Copyright (C) 2011-2013 Texas Instruments Inc.
> + * Graeme Gregory <gg@slimlogic.co.uk>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/palmas.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_platform.h>
> +
> +struct palmas_clk {
> + struct palmas *palmas;
> + struct device *dev;
> + struct clk_hw clk32kg;
> + struct clk_hw clk32kgaudio;
> + int clk32kgaudio_mode_sleep;
> + int clk32kg_mode_sleep;
> +};
> +
> +static int palmas_clock_setbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, data);
> +}
> +
> +static int palmas_clock_clrbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, 0);
> +}
> +
> +static int palmas_prepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kg_ops = {
> + .prepare = palmas_prepare_clk32kg,
> + .unprepare = palmas_unprepare_clk32kg,
> +};
> +
> +static int palmas_prepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kgaudio_ops = {
> + .prepare = palmas_prepare_clk32kgaudio,
> + .unprepare = palmas_unprepare_clk32kgaudio,
> +};
> +
> +static int palmas_initialise_clk(struct palmas_clk *palmas_clk)
> +{
> + int ret;
> +
> + if (palmas_clk->clk32kg_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + if (palmas_clk->clk32kgaudio_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL,
> + PALMAS_CLK32KGAUDIO_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void palmas_dt_to_pdata(struct device_node *node,
> + struct palmas_clk_platform_data *pdata)
> +{
> + int ret;
> + u32 prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kg-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kg_mode_sleep = prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kgaudio-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kgaudio_mode_sleep = prop;
> +}
> +
> +static int palmas_clk_probe(struct platform_device *pdev)
> +{
> + struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
> + struct palmas_clk_platform_data *pdata = pdev->dev.platform_data;
> + struct device_node *node = pdev->dev.of_node;
> + struct palmas_clk *palmas_clk;
> + struct clk *clk;
> + struct clk_init_data init_clk32g, init_clk32gaudio;
> + int ret;
> +
> + if (node && !pdata) {
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +
> + if (!pdata)
> + return -ENOMEM;
> +
> + palmas_dt_to_pdata(node, pdata);
> + }
> +
> + palmas_clk = devm_kzalloc(&pdev->dev, sizeof(*palmas_clk), GFP_KERNEL);
> + if (!palmas_clk)
> + return -ENOMEM;
> +
> + palmas_clk->palmas = palmas;
> + palmas_clk->dev = &pdev->dev;
> +
> + init_clk32g.name = "clk32kg";
> + init_clk32g.ops = &palmas_clk32kg_ops;
> + init_clk32g.parent_names = NULL;
> + init_clk32g.num_parents = 0;
> + palmas_clk->clk32kg.init = &init_clk32g;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kg);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kg clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_clk32kg;
> + }
> +
> + init_clk32gaudio.name = "clk32kgaudio";
> + init_clk32gaudio.ops = &palmas_clk32kgaudio_ops;
> + init_clk32gaudio.parent_names = NULL;
> + init_clk32gaudio.num_parents = 0;
> + palmas_clk->clk32kgaudio.init = &init_clk32gaudio;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kgaudio);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kgaudio clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_audio;
> + }
> +
> + ret = palmas_initialise_clk(palmas_clk);
> + if (ret)
> + goto err;
> +
> + dev_set_drvdata(&pdev->dev, palmas_clk);
> +
> + return 0;
> +
> +err:
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> +err_audio:
> + clk_unregister(palmas_clk->clk32kg.clk);
> +err_clk32kg:
> +
> + return ret;
> +}
> +
> +static int palmas_clk_remove(struct platform_device *pdev)
> +{
> + struct palmas_clk *palmas_clk = dev_get_drvdata(&pdev->dev);
> +
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> + clk_unregister(palmas_clk->clk32kg.clk);
> +
> + return 0;
> +}
> +
> +static struct of_device_id of_palmas_match_tbl[] = {
> + { .compatible = "ti,palmas-clk", },
> + { .compatible = "ti,palmas-charger-clk", },
> + { .compatible = "ti,twl6035-clk", },
> + { .compatible = "ti,twl6036-clk", },
> + { .compatible = "ti,twl6037-clk", },
> + { .compatible = "ti,tps65913-clk", },
> + { .compatible = "ti,tps65914-clk", },
> + { .compatible = "ti,tps80036-clk", },
> + { /* end */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
> +
> +static struct platform_driver palmas_clk_driver = {
> + .probe = palmas_clk_probe,
> + .remove = palmas_clk_remove,
> + .driver = {
> + .name = "palmas-clk",
> + .of_match_table = of_palmas_match_tbl,
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +module_platform_driver(palmas_clk_driver);
> +
> +MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
> +MODULE_DESCRIPTION("PALMAS clock driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:palmas-clk");
> --
> 1.7.0.4
WARNING: multiple messages have this Message-ID (diff)
From: Mike Turquette <mturquette@linaro.org>
To: Ian Lartey <ian@slimlogic.co.uk>, linux-kernel@vger.kernel.org
Cc: linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-leds@vger.kernel.org, linux-watchdog@vger.kernel.org,
swarren@wwwdotorg.org, grant.likely@secretlab.ca,
broonie@opensource.wolfsonmicro.com, rob.herring@calxeda.com,
rob@landley.net, linus.walleij@linaro.org, cooloney@gmail.com,
rpurdie@rpsys.net, sameo@linux.intel.com, wim@iguana.be,
lgirdwood@gmail.com, gg@slimlogic.co.uk, j-keerthy@ti.com,
ldewangan@nvidia.com, t-kristo@ti.com,
Ian Lartey <ian@slimlogic.co.uk>
Subject: Re: [PATCH v8 12/12] clk: add a clock driver for palmas
Date: Thu, 21 Mar 2013 14:23:04 -0700 [thread overview]
Message-ID: <20130321212304.834.58588@quantum> (raw)
In-Reply-To: <1362662276-20792-12-git-send-email-ian@slimlogic.co.uk>
Quoting Ian Lartey (2013-03-07 05:17:56)
> Palmas has two clock generators in it, clk32kg and clk32kg audio. They
> are fixed frequency clocks that only have enable/disable functionality.
>
> Signed-off-by: Graeme Gregory <gg@slimlogic.co.uk>
> Signed-off-by: J Keerthy <j-keerthy@ti.com>
> Signed-off-by: Ian Lartey <ian@slimlogic.co.uk>
My only complaint with this driver is that there are two sets of ops and
prepare/unprepare functions when there could be just one set. If there
existed some struct palmas_clk_hw which included members "reg" and
"ctrl_mode" (or even "enable_bit") then a single set of ops would do
just fine, instead of hard-coding those values into the functions.
Either way it's a small thing and there are only two clocks per palmas
here. Hopefully it will get cleaned up in an update some day.
Acked-by: Mike Turquette <mturquette@linaro.org>
> ---
> drivers/clk/clk-palmas.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 268 insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/clk-palmas.c
>
> diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
> new file mode 100644
> index 0000000..328eea4
> --- /dev/null
> +++ b/drivers/clk/clk-palmas.c
> @@ -0,0 +1,268 @@
> +/*
> + * PALMAS resource clock module driver
> + *
> + * Copyright (C) 2011-2013 Texas Instruments Inc.
> + * Graeme Gregory <gg@slimlogic.co.uk>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/palmas.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_platform.h>
> +
> +struct palmas_clk {
> + struct palmas *palmas;
> + struct device *dev;
> + struct clk_hw clk32kg;
> + struct clk_hw clk32kgaudio;
> + int clk32kgaudio_mode_sleep;
> + int clk32kg_mode_sleep;
> +};
> +
> +static int palmas_clock_setbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, data);
> +}
> +
> +static int palmas_clock_clrbits(struct palmas *palmas, unsigned int reg,
> + unsigned int data)
> +{
> + return palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + reg, data, 0);
> +}
> +
> +static int palmas_prepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kg(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kg);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev, "Failed to enable clk32kg: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kg_ops = {
> + .prepare = palmas_prepare_clk32kg,
> + .unprepare = palmas_unprepare_clk32kg,
> +};
> +
> +static int palmas_prepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static void palmas_unprepare_clk32kgaudio(struct clk_hw *hw)
> +{
> + struct palmas_clk *palmas_clk = container_of(hw, struct palmas_clk,
> + clk32kgaudio);
> + int ret;
> +
> + ret = palmas_clock_clrbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL, PALMAS_CLK32KGAUDIO_CTRL_MODE_ACTIVE);
> + if (ret)
> + dev_err(palmas_clk->dev,
> + "Failed to enable clk32kgaudio: %d\n", ret);
> +
> + return;
> +}
> +
> +static const struct clk_ops palmas_clk32kgaudio_ops = {
> + .prepare = palmas_prepare_clk32kgaudio,
> + .unprepare = palmas_unprepare_clk32kgaudio,
> +};
> +
> +static int palmas_initialise_clk(struct palmas_clk *palmas_clk)
> +{
> + int ret;
> +
> + if (palmas_clk->clk32kg_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KG_CTRL, PALMAS_CLK32KG_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + if (palmas_clk->clk32kgaudio_mode_sleep) {
> + ret = palmas_clock_setbits(palmas_clk->palmas,
> + PALMAS_CLK32KGAUDIO_CTRL,
> + PALMAS_CLK32KGAUDIO_CTRL_MODE_SLEEP);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static void palmas_dt_to_pdata(struct device_node *node,
> + struct palmas_clk_platform_data *pdata)
> +{
> + int ret;
> + u32 prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kg-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kg_mode_sleep = prop;
> +
> + ret = of_property_read_u32(node, "ti,clk32kgaudio-mode-sleep", &prop);
> + if (!ret)
> + pdata->clk32kgaudio_mode_sleep = prop;
> +}
> +
> +static int palmas_clk_probe(struct platform_device *pdev)
> +{
> + struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
> + struct palmas_clk_platform_data *pdata = pdev->dev.platform_data;
> + struct device_node *node = pdev->dev.of_node;
> + struct palmas_clk *palmas_clk;
> + struct clk *clk;
> + struct clk_init_data init_clk32g, init_clk32gaudio;
> + int ret;
> +
> + if (node && !pdata) {
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +
> + if (!pdata)
> + return -ENOMEM;
> +
> + palmas_dt_to_pdata(node, pdata);
> + }
> +
> + palmas_clk = devm_kzalloc(&pdev->dev, sizeof(*palmas_clk), GFP_KERNEL);
> + if (!palmas_clk)
> + return -ENOMEM;
> +
> + palmas_clk->palmas = palmas;
> + palmas_clk->dev = &pdev->dev;
> +
> + init_clk32g.name = "clk32kg";
> + init_clk32g.ops = &palmas_clk32kg_ops;
> + init_clk32g.parent_names = NULL;
> + init_clk32g.num_parents = 0;
> + palmas_clk->clk32kg.init = &init_clk32g;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kg);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kg clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_clk32kg;
> + }
> +
> + init_clk32gaudio.name = "clk32kgaudio";
> + init_clk32gaudio.ops = &palmas_clk32kgaudio_ops;
> + init_clk32gaudio.parent_names = NULL;
> + init_clk32gaudio.num_parents = 0;
> + palmas_clk->clk32kgaudio.init = &init_clk32gaudio;
> +
> + clk = clk_register(palmas_clk->dev, &palmas_clk->clk32kgaudio);
> + if (IS_ERR(clk)) {
> + dev_dbg(&pdev->dev, "clk32kgaudio clock register failed %ld\n",
> + PTR_ERR(clk));
> + ret = PTR_ERR(clk);
> + goto err_audio;
> + }
> +
> + ret = palmas_initialise_clk(palmas_clk);
> + if (ret)
> + goto err;
> +
> + dev_set_drvdata(&pdev->dev, palmas_clk);
> +
> + return 0;
> +
> +err:
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> +err_audio:
> + clk_unregister(palmas_clk->clk32kg.clk);
> +err_clk32kg:
> +
> + return ret;
> +}
> +
> +static int palmas_clk_remove(struct platform_device *pdev)
> +{
> + struct palmas_clk *palmas_clk = dev_get_drvdata(&pdev->dev);
> +
> + clk_unregister(palmas_clk->clk32kgaudio.clk);
> + clk_unregister(palmas_clk->clk32kg.clk);
> +
> + return 0;
> +}
> +
> +static struct of_device_id of_palmas_match_tbl[] = {
> + { .compatible = "ti,palmas-clk", },
> + { .compatible = "ti,palmas-charger-clk", },
> + { .compatible = "ti,twl6035-clk", },
> + { .compatible = "ti,twl6036-clk", },
> + { .compatible = "ti,twl6037-clk", },
> + { .compatible = "ti,tps65913-clk", },
> + { .compatible = "ti,tps65914-clk", },
> + { .compatible = "ti,tps80036-clk", },
> + { /* end */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
> +
> +static struct platform_driver palmas_clk_driver = {
> + .probe = palmas_clk_probe,
> + .remove = palmas_clk_remove,
> + .driver = {
> + .name = "palmas-clk",
> + .of_match_table = of_palmas_match_tbl,
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +module_platform_driver(palmas_clk_driver);
> +
> +MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
> +MODULE_DESCRIPTION("PALMAS clock driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:palmas-clk");
> --
> 1.7.0.4
next prev parent reply other threads:[~2013-03-21 21:31 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-07 13:17 [PATCH v8 01/12] mfd: DT bindings for the palmas family MFD Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 02/12] mfd: palmas: is_palmas_charger needed by multiple drivers Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 03/12] mfd: palmas add variant and OTP detection Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 04/12] regulator: palmas correct dt parsing Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-08 9:44 ` Mark Brown
2013-03-08 9:44 ` Mark Brown
2013-03-07 13:17 ` [PATCH v8 05/12] watchdog: add Palmas Watchdog support Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 06/12] watchdog: Kconfig for Palmas watchdog Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 07/12] gpio: palmas: add in GPIO support for palmas charger Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-13 14:15 ` Linus Walleij
2013-03-13 14:15 ` Linus Walleij
2013-03-14 11:58 ` Ian Lartey
2013-03-14 11:58 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 08/12] gpio: palmas: Enable DT support for palmas gpio Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-13 14:20 ` Linus Walleij
2013-03-13 14:20 ` Linus Walleij
2013-03-07 13:17 ` [PATCH v8 09/12] leds: Add support for Palmas LEDs Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-08 1:13 ` Kim, Milo
2013-03-11 15:16 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 10/12] clk: Kconfig for Palmas clock driver Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-08 1:13 ` Kim, Milo
2013-03-08 17:14 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 11/12] leds: Kconfig for Palmas LEDs Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-08 1:13 ` Kim, Milo
2013-03-08 17:13 ` Ian Lartey
2013-03-13 20:31 ` Stephen Warren
2013-03-13 23:48 ` Ian Lartey
2013-03-07 13:17 ` [PATCH v8 12/12] clk: add a clock driver for palmas Ian Lartey
2013-03-07 13:17 ` Ian Lartey
2013-03-21 21:23 ` Mike Turquette [this message]
2013-03-21 21:23 ` Mike Turquette
2013-03-21 21:23 ` Mike Turquette
2013-03-07 13:23 ` [PATCH v8 0/12] Palmas Updates Ian Lartey
2013-03-07 13:23 ` Ian Lartey
2013-03-08 7:12 ` Linus Walleij
2013-03-08 7:12 ` Linus Walleij
2013-03-08 17:12 ` Ian Lartey
2013-03-08 17:12 ` Ian Lartey
2013-03-13 20:28 ` [PATCH v8 01/12] mfd: DT bindings for the palmas family MFD Stephen Warren
2013-03-13 20:28 ` Stephen Warren
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=20130321212304.834.58588@quantum \
--to=mturquette@linaro.org \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=cooloney@gmail.com \
--cc=gg@slimlogic.co.uk \
--cc=grant.likely@secretlab.ca \
--cc=ian@slimlogic.co.uk \
--cc=j-keerthy@ti.com \
--cc=ldewangan@nvidia.com \
--cc=lgirdwood@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=linux-watchdog@vger.kernel.org \
--cc=rob.herring@calxeda.com \
--cc=rob@landley.net \
--cc=rpurdie@rpsys.net \
--cc=sameo@linux.intel.com \
--cc=swarren@wwwdotorg.org \
--cc=t-kristo@ti.com \
--cc=wim@iguana.be \
/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.