From: sebastian.hesselbarth@gmail.com (Sebastian Hesselbarth)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6] clk: add si5351 i2c common clock driver
Date: Mon, 08 Apr 2013 20:24:08 +0200 [thread overview]
Message-ID: <51630B48.9050005@gmail.com> (raw)
In-Reply-To: <20130408174636.GA1885@roeck-us.net>
On 04/08/2013 07:46 PM, Guenter Roeck wrote:
> On Mon, Apr 08, 2013 at 06:46:57PM +0200, Sebastian Hesselbarth wrote:
>> This patch adds a common clock driver for Silicon Labs Si5351a/b/c
>> i2c programmable clock generators. Currently, the driver does not
>> support VXCO feature of si5351b. Passing platform_data or DT bindings
>> selectively allow to overwrite stored Si5351 configuration which is
>> very helpful for clock generators with empty eeprom configuration.
>> Corresponding device tree binding documentation is also added.
>>
>> Signed-off-by: Sebastian Hesselbarth<sebastian.hesselbarth@gmail.com>
>
> [ ... ]
>
>> +
>> +/*
>> + * Si5351 i2c probe and DT
>> + */
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id si5351_dt_ids[] = {
>> + { .compatible = "silabs,si5351a", .data = (void *)SI5351_VARIANT_A, },
>> + { .compatible = "silabs,si5351a-msop",
>> + .data = (void *)SI5351_VARIANT_A3, },
>> + { .compatible = "silabs,si5351b", .data = (void *)SI5351_VARIANT_B, },
>> + { .compatible = "silabs,si5351c", .data = (void *)SI5351_VARIANT_C, },
>> + { }
>> +};
>> +MODULE_DEVICE_TABLE(of, si5351_dt_ids);
>> +
>> +static int si5351_dt_parse(struct i2c_client *client)
>> +{
>> + struct device_node *child, *np = client->dev.of_node;
>> + struct si5351_platform_data *pdata;
>> + const struct of_device_id *match;
>> + struct property *prop;
>> + const __be32 *p;
>> + int num = 0;
>> + u32 val;
>> +
>> + if (np == NULL)
>> + return 0;
>> +
>> + match = of_match_node(si5351_dt_ids, np);
>> + if (match == NULL)
>> + return -EINVAL;
>> +
>> + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return -ENOMEM;
>> +
>> + pdata->variant = (enum si5351_variant)match->data;
>> + pdata->clk_xtal = of_clk_get(np, 0);
>> + if (!IS_ERR(pdata->clk_xtal))
>> + clk_put(pdata->clk_xtal);
>> + pdata->clk_clkin = of_clk_get(np, 1);
>> + if (!IS_ERR(pdata->clk_clkin))
>> + clk_put(pdata->clk_clkin);
>> +
>> + /*
>> + * property silabs,pll-source :<num src>, [<..>]
>> + * allow to selectively set pll source
>> + */
>> + of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
>> + if (num>= 2) {
>> + dev_err(&client->dev,
>> + "invalid pll %d on pll-source prop\n", num);
>> + break;
>
> You report dev_err here, but you don't return an error to the caller.
> Is this on purpose ? If it is not a fatal error, maybe it should be dev_info ?
This shouldn't break but continue with one u32 skipped. Actually, it is
a warning because somebody passed an invalid value and should be
dev_warn(). But see my note below, I will make them all fatal.
>> + }
>> +
>> + p = of_prop_next_u32(prop, p,&val);
>> + if (!p)
>> + break;
>> +
>> + switch (val) {
>> + case 0:
>> + pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
>> + break;
>> + case 1:
>> + pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
>> + break;
>> + default:
>> + dev_warn(&client->dev,
>> + "invalid parent %d for pll %d\n", val, num);
>> + continue;
>
> Same here, and a couple of times below. Given the context, I think it would
> be better if the error cases would return an error. After all, the condition
> suggests that the device tree data is wrong, meaning one has to assume it
> won't work anyway and should be fixed in the device tree and not be ignored
> by the driver.
I am skipping invalid DT data enties here, but I can make them all
fatal. I will also add more variant checks in the corresponding
_si5351_* functions.
>> + }
>> + }
>> +
>> + /* per clkout properties */
>> + num = of_get_child_count(np);
>> +
>> + if (num == 0)
>> + return 0;
>> +
>
> This doesn't set client->dev.platform_data yet returns no error, meaning the
> calling code will either use provided platform data or fail after all if it is
> NULL. That seems to be inconsistent, given that a dt entry was already detected.
> The user might end up wondering why the provided device tree data is not used,
> not realizing that it is incomplete.
>
> If children are not mandatory, you could just drop the code above and go through
> for_each_child_of_node() anyway; it won't do anything and set
> client->dev.platform_data at the end. If children are mandatory, it might make
> sense to return an eror here (if there is dt information, it should be complete
> and consistent).
Not having children is valid as you only provide them if you want to
overwrite the current config stored in the eeprom. But yes, skipping
for_each_child_of_node below is a left-over from an implementation where
I used dynamically allocated ->pll/->clkout.
>> + for_each_child_of_node(np, child) {
>> + if (of_property_read_u32(child, "reg",&num)) {
>> + dev_err(&client->dev, "missing reg property of %s\n",
>> + child->name);
>> + continue;
>> + }
>> +
> What if "num" returns 100 ? Or 1000 ?
Segmentation fault? ;) I will add a check for 0 <= num < 8.
Thanks for the review,
Sebastian
next prev parent reply other threads:[~2013-04-08 18:24 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-09 12:59 [PATCH] clk: add si5351 i2c common clock driver Sebastian Hesselbarth
2013-02-11 5:46 ` Mike Turquette
2013-02-11 9:52 ` Sebastian Hesselbarth
2013-02-18 10:19 ` Daniel Mack
2013-02-19 19:15 ` Daniel Mack
2013-02-27 10:01 ` Sebastian Hesselbarth
2013-03-01 15:01 ` Daniel Mack
2013-03-16 13:10 ` [PATCH v2] " Sebastian Hesselbarth
2013-03-16 15:10 ` Daniel Mack
2013-03-18 10:43 ` [PATCH v3] " Sebastian Hesselbarth
2013-03-18 11:37 ` Daniel Mack
2013-03-20 0:26 ` Mike Turquette
2013-03-20 8:20 ` Sebastian Hesselbarth
2013-03-21 18:09 ` Lars-Peter Clausen
2013-03-21 21:32 ` Sebastian Hesselbarth
2013-03-23 10:07 ` Lars-Peter Clausen
2013-03-23 14:46 ` [PATCH v4] " Sebastian Hesselbarth
2013-04-02 23:46 ` Mike Turquette
2013-04-03 11:10 ` Sebastian Hesselbarth
2013-04-05 5:23 ` [PATCH v5] " Sebastian Hesselbarth
2013-04-07 22:50 ` [v5] " Guenter Roeck
2013-04-07 23:49 ` Sebastian Hesselbarth
2013-04-08 0:17 ` Guenter Roeck
2013-04-08 6:11 ` Sebastian Hesselbarth
2013-04-08 14:54 ` Guenter Roeck
2013-04-08 15:38 ` Sebastian Hesselbarth
2013-04-08 17:36 ` Mike Turquette
2013-04-08 18:32 ` Sebastian Hesselbarth
2013-04-08 16:46 ` [PATCH v6] " Sebastian Hesselbarth
2013-04-08 17:46 ` Guenter Roeck
2013-04-08 18:24 ` Sebastian Hesselbarth [this message]
2013-04-10 9:40 ` [PATCH v7] " Sebastian Hesselbarth
2013-04-10 10:17 ` Daniel Mack
2013-04-10 14:48 ` Michal Bachraty
2013-04-10 17:27 ` Sebastian Hesselbarth
2013-04-11 7:44 ` Michal Bachraty
2013-04-11 8:22 ` Sebastian Hesselbarth
2013-04-10 19:34 ` Guenter Roeck
2013-04-11 19:42 ` [PATCH v8] " Sebastian Hesselbarth
2013-04-12 11:43 ` Michal Bachraty
2013-04-12 18:19 ` Mike Turquette
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=51630B48.9050005@gmail.com \
--to=sebastian.hesselbarth@gmail.com \
--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;
as well as URLs for NNTP newsgroup(s).