From: mark.rutland@arm.com (Mark Rutland)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH RFC 2/3] ARM: regulator: add Freescale MXS regulator driver
Date: Tue, 9 Sep 2014 19:22:11 +0100 [thread overview]
Message-ID: <20140909182211.GG3896@leverpostej> (raw)
In-Reply-To: <1410089869-6611-3-git-send-email-info@lategoodbye.de>
[...]
> + regs = (__raw_readl(sreg->base_addr) & ~BM_POWER_LEVEL_TRG);
I suspect you should be using the *_relaxed accessors rather than the
__raw_* accessors.
[...]
> +static int mxs_regulator_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *parent;
> + struct regulator_desc *rdesc;
> + struct regulator_dev *rdev;
> + struct mxs_regulator *sreg;
> + struct regulator_init_data *initdata;
> + struct regulation_constraints *con;
> + struct regulator_config config = { };
> + void __iomem *base_addr = NULL;
> + void __iomem *power_addr = NULL;
> + u64 regaddr64 = 0;
> + const u32 *regaddr_p;
> + u32 val = 0;
> + int ret;
> +
> + if (!np) {
> + dev_err(dev, "missing device tree\n");
> + return -EINVAL;
> + }
> +
> + /* get device base address */
> + base_addr = of_iomap(np, 0);
> + if (!base_addr)
> + return -ENXIO;
> +
> + parent = of_get_parent(np);
> + if (!parent)
> + return -ENXIO;
Leak of the (successfully mapped) base_addr.
> +
> + power_addr = of_iomap(parent, 0);
> + if (!power_addr)
> + return -ENXIO;
Leak of base_addr and dangling refcount on parent. These apply to all
subsequent returns.
> +
> + regaddr_p = of_get_address(np, 0, NULL, NULL);
of_get_address returns a __be32*, not a u32*, so sparse will be very
unhappy here...
> + if (regaddr_p)
> + regaddr64 = of_translate_address(np, regaddr_p);
...and as of_translate_address returns a u64 you'll need a separate
variable for the input and output.
> +
> + if (!regaddr64) {
> + dev_err(dev, "no or invalid reg property set\n");
> + return -EINVAL;
> + }
> +
> + initdata = of_get_regulator_init_data(dev, np);
> + if (!initdata)
> + return -EINVAL;
> +
> + ret = of_property_read_u32(np, "mxs-max-reg-val",
> + &val);
> + if (!val) {
> + dev_err(dev, "no or invalid mxs-max-reg-val property set\n");
> + return ret;
> + }
> +
> + dev_info(dev, "regulator found\n");
> +
> + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
> + if (!sreg)
> + return -ENOMEM;
> + sreg->initdata = initdata;
> + sreg->name = of_get_property(np, "regulator-name", NULL);
I'm not keen on using of_get_property here. We have no idea if
regulator-name is even a string (it should be, but we have no
guarantee).
> + sreg->cur_uA = 0;
> + sreg->cur_uV = 0;
> + sreg->base_addr = base_addr;
> + sreg->power_addr = power_addr;
> + init_waitqueue_head(&sreg->wait_q);
> + spin_lock_init(&sreg->lock);
> + sreg->max_reg_val = val;
> +
> + rdesc = &sreg->rdesc;
> + rdesc->name = sreg->name;
> + rdesc->owner = THIS_MODULE;
> + rdesc->ops = &mxs_rops;
> +
> + if (strcmp(rdesc->name, "overall_current") == 0)
> + rdesc->type = REGULATOR_CURRENT;
> + else
> + rdesc->type = REGULATOR_VOLTAGE;
Wouldn't it make more sense to explicitly match the names you expect?
> + con = &initdata->constraints;
> + rdesc->n_voltages = sreg->max_reg_val;
> + rdesc->min_uV = con->min_uV;
> + rdesc->uV_step = (con->max_uV - con->min_uV) / sreg->max_reg_val;
> + rdesc->linear_min_sel = 0;
> + rdesc->vsel_reg = regaddr64;
> + rdesc->vsel_mask = BM_POWER_LEVEL_TRG;
> +
> + config.dev = &pdev->dev;
> + config.init_data = initdata;
> + config.driver_data = sreg;
> + config.of_node = np;
> +
> + pr_debug("probing regulator %s %s %d\n",
> + sreg->name,
> + rdesc->name,
> + pdev->id);
Aren't those two names always the same per the code above?
> +
> + /* register regulator */
> + rdev = devm_regulator_register(dev, rdesc, &config);
> +
> + if (IS_ERR(rdev)) {
> + dev_err(&pdev->dev, "failed to register %s\n",
> + rdesc->name);
> + return PTR_ERR(rdev);
> + }
> +
> + if (sreg->max_uA) {
> + struct regulator *regu;
> +
> + regu = regulator_get(NULL, sreg->name);
> + sreg->nb.notifier_call = reg_callback;
> + regulator_register_notifier(regu, &sreg->nb);
> + }
> +
> + platform_set_drvdata(pdev, rdev);
> +
> + of_property_read_u32(np, "mxs-default-microvolt",
> + &val);
> +
> + if (val)
> + mxs_set_voltage(rdev, val, val, NULL);
As I mentioned in my comments on the binding, I'd like to know why this
is necessary and if it is why it shouldn't be a standardised property.
Mark.
WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
To: Stefan Wahren <info-saaNCTdWVBT7BZbvpMY5sg@public.gmane.org>
Cc: "lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org"
<lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
"broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org"
<broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
"shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org"
<shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
"robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org"
<robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Pawel Moll <Pawel.Moll-5wv7dgnIgG8@public.gmane.org>,
"ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org"
<ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org>,
"galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org"
<galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
"stefan.wahren-eS4NqCHxEME@public.gmane.org"
<stefan.wahren-eS4NqCHxEME@public.gmane.org>,
"devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
<devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
"linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
"festevam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org"
<festevam-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>
Subject: Re: [PATCH RFC 2/3] ARM: regulator: add Freescale MXS regulator driver
Date: Tue, 9 Sep 2014 19:22:11 +0100 [thread overview]
Message-ID: <20140909182211.GG3896@leverpostej> (raw)
In-Reply-To: <1410089869-6611-3-git-send-email-info-saaNCTdWVBT7BZbvpMY5sg@public.gmane.org>
[...]
> + regs = (__raw_readl(sreg->base_addr) & ~BM_POWER_LEVEL_TRG);
I suspect you should be using the *_relaxed accessors rather than the
__raw_* accessors.
[...]
> +static int mxs_regulator_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *parent;
> + struct regulator_desc *rdesc;
> + struct regulator_dev *rdev;
> + struct mxs_regulator *sreg;
> + struct regulator_init_data *initdata;
> + struct regulation_constraints *con;
> + struct regulator_config config = { };
> + void __iomem *base_addr = NULL;
> + void __iomem *power_addr = NULL;
> + u64 regaddr64 = 0;
> + const u32 *regaddr_p;
> + u32 val = 0;
> + int ret;
> +
> + if (!np) {
> + dev_err(dev, "missing device tree\n");
> + return -EINVAL;
> + }
> +
> + /* get device base address */
> + base_addr = of_iomap(np, 0);
> + if (!base_addr)
> + return -ENXIO;
> +
> + parent = of_get_parent(np);
> + if (!parent)
> + return -ENXIO;
Leak of the (successfully mapped) base_addr.
> +
> + power_addr = of_iomap(parent, 0);
> + if (!power_addr)
> + return -ENXIO;
Leak of base_addr and dangling refcount on parent. These apply to all
subsequent returns.
> +
> + regaddr_p = of_get_address(np, 0, NULL, NULL);
of_get_address returns a __be32*, not a u32*, so sparse will be very
unhappy here...
> + if (regaddr_p)
> + regaddr64 = of_translate_address(np, regaddr_p);
...and as of_translate_address returns a u64 you'll need a separate
variable for the input and output.
> +
> + if (!regaddr64) {
> + dev_err(dev, "no or invalid reg property set\n");
> + return -EINVAL;
> + }
> +
> + initdata = of_get_regulator_init_data(dev, np);
> + if (!initdata)
> + return -EINVAL;
> +
> + ret = of_property_read_u32(np, "mxs-max-reg-val",
> + &val);
> + if (!val) {
> + dev_err(dev, "no or invalid mxs-max-reg-val property set\n");
> + return ret;
> + }
> +
> + dev_info(dev, "regulator found\n");
> +
> + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
> + if (!sreg)
> + return -ENOMEM;
> + sreg->initdata = initdata;
> + sreg->name = of_get_property(np, "regulator-name", NULL);
I'm not keen on using of_get_property here. We have no idea if
regulator-name is even a string (it should be, but we have no
guarantee).
> + sreg->cur_uA = 0;
> + sreg->cur_uV = 0;
> + sreg->base_addr = base_addr;
> + sreg->power_addr = power_addr;
> + init_waitqueue_head(&sreg->wait_q);
> + spin_lock_init(&sreg->lock);
> + sreg->max_reg_val = val;
> +
> + rdesc = &sreg->rdesc;
> + rdesc->name = sreg->name;
> + rdesc->owner = THIS_MODULE;
> + rdesc->ops = &mxs_rops;
> +
> + if (strcmp(rdesc->name, "overall_current") == 0)
> + rdesc->type = REGULATOR_CURRENT;
> + else
> + rdesc->type = REGULATOR_VOLTAGE;
Wouldn't it make more sense to explicitly match the names you expect?
> + con = &initdata->constraints;
> + rdesc->n_voltages = sreg->max_reg_val;
> + rdesc->min_uV = con->min_uV;
> + rdesc->uV_step = (con->max_uV - con->min_uV) / sreg->max_reg_val;
> + rdesc->linear_min_sel = 0;
> + rdesc->vsel_reg = regaddr64;
> + rdesc->vsel_mask = BM_POWER_LEVEL_TRG;
> +
> + config.dev = &pdev->dev;
> + config.init_data = initdata;
> + config.driver_data = sreg;
> + config.of_node = np;
> +
> + pr_debug("probing regulator %s %s %d\n",
> + sreg->name,
> + rdesc->name,
> + pdev->id);
Aren't those two names always the same per the code above?
> +
> + /* register regulator */
> + rdev = devm_regulator_register(dev, rdesc, &config);
> +
> + if (IS_ERR(rdev)) {
> + dev_err(&pdev->dev, "failed to register %s\n",
> + rdesc->name);
> + return PTR_ERR(rdev);
> + }
> +
> + if (sreg->max_uA) {
> + struct regulator *regu;
> +
> + regu = regulator_get(NULL, sreg->name);
> + sreg->nb.notifier_call = reg_callback;
> + regulator_register_notifier(regu, &sreg->nb);
> + }
> +
> + platform_set_drvdata(pdev, rdev);
> +
> + of_property_read_u32(np, "mxs-default-microvolt",
> + &val);
> +
> + if (val)
> + mxs_set_voltage(rdev, val, val, NULL);
As I mentioned in my comments on the binding, I'd like to know why this
is necessary and if it is why it shouldn't be a standardised property.
Mark.
--
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
WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland@arm.com>
To: Stefan Wahren <info@lategoodbye.de>
Cc: "lgirdwood@gmail.com" <lgirdwood@gmail.com>,
"broonie@kernel.org" <broonie@kernel.org>,
"shawn.guo@linaro.org" <shawn.guo@linaro.org>,
"robh+dt@kernel.org" <robh+dt@kernel.org>,
Pawel Moll <Pawel.Moll@arm.com>,
"ijc+devicetree@hellion.org.uk" <ijc+devicetree@hellion.org.uk>,
"galak@codeaurora.org" <galak@codeaurora.org>,
"stefan.wahren@i2se.com" <stefan.wahren@i2se.com>,
"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"festevam@gmail.com" <festevam@gmail.com>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH RFC 2/3] ARM: regulator: add Freescale MXS regulator driver
Date: Tue, 9 Sep 2014 19:22:11 +0100 [thread overview]
Message-ID: <20140909182211.GG3896@leverpostej> (raw)
In-Reply-To: <1410089869-6611-3-git-send-email-info@lategoodbye.de>
[...]
> + regs = (__raw_readl(sreg->base_addr) & ~BM_POWER_LEVEL_TRG);
I suspect you should be using the *_relaxed accessors rather than the
__raw_* accessors.
[...]
> +static int mxs_regulator_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *parent;
> + struct regulator_desc *rdesc;
> + struct regulator_dev *rdev;
> + struct mxs_regulator *sreg;
> + struct regulator_init_data *initdata;
> + struct regulation_constraints *con;
> + struct regulator_config config = { };
> + void __iomem *base_addr = NULL;
> + void __iomem *power_addr = NULL;
> + u64 regaddr64 = 0;
> + const u32 *regaddr_p;
> + u32 val = 0;
> + int ret;
> +
> + if (!np) {
> + dev_err(dev, "missing device tree\n");
> + return -EINVAL;
> + }
> +
> + /* get device base address */
> + base_addr = of_iomap(np, 0);
> + if (!base_addr)
> + return -ENXIO;
> +
> + parent = of_get_parent(np);
> + if (!parent)
> + return -ENXIO;
Leak of the (successfully mapped) base_addr.
> +
> + power_addr = of_iomap(parent, 0);
> + if (!power_addr)
> + return -ENXIO;
Leak of base_addr and dangling refcount on parent. These apply to all
subsequent returns.
> +
> + regaddr_p = of_get_address(np, 0, NULL, NULL);
of_get_address returns a __be32*, not a u32*, so sparse will be very
unhappy here...
> + if (regaddr_p)
> + regaddr64 = of_translate_address(np, regaddr_p);
...and as of_translate_address returns a u64 you'll need a separate
variable for the input and output.
> +
> + if (!regaddr64) {
> + dev_err(dev, "no or invalid reg property set\n");
> + return -EINVAL;
> + }
> +
> + initdata = of_get_regulator_init_data(dev, np);
> + if (!initdata)
> + return -EINVAL;
> +
> + ret = of_property_read_u32(np, "mxs-max-reg-val",
> + &val);
> + if (!val) {
> + dev_err(dev, "no or invalid mxs-max-reg-val property set\n");
> + return ret;
> + }
> +
> + dev_info(dev, "regulator found\n");
> +
> + sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
> + if (!sreg)
> + return -ENOMEM;
> + sreg->initdata = initdata;
> + sreg->name = of_get_property(np, "regulator-name", NULL);
I'm not keen on using of_get_property here. We have no idea if
regulator-name is even a string (it should be, but we have no
guarantee).
> + sreg->cur_uA = 0;
> + sreg->cur_uV = 0;
> + sreg->base_addr = base_addr;
> + sreg->power_addr = power_addr;
> + init_waitqueue_head(&sreg->wait_q);
> + spin_lock_init(&sreg->lock);
> + sreg->max_reg_val = val;
> +
> + rdesc = &sreg->rdesc;
> + rdesc->name = sreg->name;
> + rdesc->owner = THIS_MODULE;
> + rdesc->ops = &mxs_rops;
> +
> + if (strcmp(rdesc->name, "overall_current") == 0)
> + rdesc->type = REGULATOR_CURRENT;
> + else
> + rdesc->type = REGULATOR_VOLTAGE;
Wouldn't it make more sense to explicitly match the names you expect?
> + con = &initdata->constraints;
> + rdesc->n_voltages = sreg->max_reg_val;
> + rdesc->min_uV = con->min_uV;
> + rdesc->uV_step = (con->max_uV - con->min_uV) / sreg->max_reg_val;
> + rdesc->linear_min_sel = 0;
> + rdesc->vsel_reg = regaddr64;
> + rdesc->vsel_mask = BM_POWER_LEVEL_TRG;
> +
> + config.dev = &pdev->dev;
> + config.init_data = initdata;
> + config.driver_data = sreg;
> + config.of_node = np;
> +
> + pr_debug("probing regulator %s %s %d\n",
> + sreg->name,
> + rdesc->name,
> + pdev->id);
Aren't those two names always the same per the code above?
> +
> + /* register regulator */
> + rdev = devm_regulator_register(dev, rdesc, &config);
> +
> + if (IS_ERR(rdev)) {
> + dev_err(&pdev->dev, "failed to register %s\n",
> + rdesc->name);
> + return PTR_ERR(rdev);
> + }
> +
> + if (sreg->max_uA) {
> + struct regulator *regu;
> +
> + regu = regulator_get(NULL, sreg->name);
> + sreg->nb.notifier_call = reg_callback;
> + regulator_register_notifier(regu, &sreg->nb);
> + }
> +
> + platform_set_drvdata(pdev, rdev);
> +
> + of_property_read_u32(np, "mxs-default-microvolt",
> + &val);
> +
> + if (val)
> + mxs_set_voltage(rdev, val, val, NULL);
As I mentioned in my comments on the binding, I'd like to know why this
is necessary and if it is why it shouldn't be a standardised property.
Mark.
next prev parent reply other threads:[~2014-09-09 18:22 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-07 11:37 [PATCH RFC 0/3] ARM: regulator: add Freescale MXS regulator driver Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 11:37 ` [PATCH RFC 1/3] DT: add binding for MXS regulator Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 13:35 ` Sergei Shtylyov
2014-09-07 13:35 ` Sergei Shtylyov
2014-09-09 17:59 ` Mark Rutland
2014-09-09 17:59 ` Mark Rutland
2014-09-09 18:48 ` Stefan Wahren
2014-09-09 18:48 ` Stefan Wahren
2014-09-09 18:48 ` Stefan Wahren
2014-09-07 11:37 ` [PATCH RFC 2/3] ARM: regulator: add Freescale MXS regulator driver Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-09 18:22 ` Mark Rutland [this message]
2014-09-09 18:22 ` Mark Rutland
2014-09-09 18:22 ` Mark Rutland
2014-09-09 19:17 ` Stefan Wahren
2014-09-09 19:17 ` Stefan Wahren
2014-09-10 14:18 ` Mark Rutland
2014-09-10 14:18 ` Mark Rutland
2014-09-10 14:18 ` Mark Rutland
2014-09-10 15:13 ` Mark Brown
2014-09-10 15:13 ` Mark Brown
2014-09-10 17:32 ` Stefan Wahren
2014-09-10 17:32 ` Stefan Wahren
2014-09-10 18:54 ` Fabio Estevam
2014-09-10 18:54 ` Fabio Estevam
2014-09-11 5:53 ` Stefan Wahren
2014-09-11 5:53 ` Stefan Wahren
2014-09-11 5:53 ` Stefan Wahren
2014-09-10 19:50 ` Mark Brown
2014-09-10 19:50 ` Mark Brown
2014-09-10 19:50 ` Mark Brown
2014-09-10 17:24 ` Stefan Wahren
2014-09-10 17:24 ` Stefan Wahren
2014-09-10 17:24 ` Stefan Wahren
2014-09-10 17:06 ` Fabio Estevam
2014-09-10 17:06 ` Fabio Estevam
2014-09-10 17:06 ` Fabio Estevam
2014-09-07 11:37 ` [PATCH RFC 3/3] DT: ARM: mxs: enable regulator support for i.MX28 Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
2014-09-07 11:37 ` Stefan Wahren
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=20140909182211.GG3896@leverpostej \
--to=mark.rutland@arm.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 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.