From: u.kleine-koenig@pengutronix.de (Uwe Kleine-König)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] [RFC] pinctrl: add a driver for Energy Micro's efm32 SoCs
Date: Fri, 9 Dec 2011 10:31:23 +0100 [thread overview]
Message-ID: <20111209093123.GS4585@pengutronix.de> (raw)
In-Reply-To: <74CDBE0F657A3D45AFBB94109FB122FF1750B77BD8@HQMAIL01.nvidia.com>
On Thu, Dec 08, 2011 at 03:14:40PM -0800, Stephen Warren wrote:
> Uwe Kleine-K?nig wrote at Thursday, December 08, 2011 3:41 PM:
>
> > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>
> > +config PINMUX_EFM32
> > + bool "EFM32 pinmux driver"
> > + depends on ARCH_EFM32
> > + default y
> > + select PINMUX
>
> LinusW,
>
> Since this is the pinctrl not pinmux subsystem now, does it make sense
> to name the driver Kconfig options PINCTRL_FOO and the files pinctrl-
> foo.c? I see that the coh901 driver already does that, and I followed
> that convention in my Tegra pinctrl patches.
+1
>
> Uwe,
>
> > diff --git a/drivers/pinctrl/pinmux-efm32.c b/drivers/pinctrl/pinmux-efm32.c
>
> > +#define DRIVER_NAME "efm32-pinctl"
>
> pinctrl (with an r) would match the subsystem name better.
yeah, I saw some names with and some without r. I can switch to the
other variant for the next round.
> > +static const char *efm32_pinctl_pctl_get_group_name(struct pinctrl_dev *pctldev,
> > + unsigned selector)
> > +{
> > + struct efm32_pinctrl_ddata *ddata = pctldev->driver_data;
> > + const struct efm32_pinctl_pdata *pdata = ddata->pdata;
> > +
> > + return pdata->groups[selector]->name;
> > +}
>
> Presumably, the set of pins, groups, and functions is determined by the
> SoC HW. Platform data is usually board-specific rather than SoC specific.
There is nothing stoping me putting both machine and SoC specific stuff
into pdata, isn't it?
> You have two choices here: You could either parse this data from device
> tree as Arnd suggested (and I think as the TI OMAP pinctrl driver will),
> or do what I've done in the Tegra pinctrl driver, and simply put each
> SoC's data into the driver and select which one to use based on the DT
> compatible flag; I didn't see the point of putting data in to the DT that
> was identical for every board using a given SoC.
>
> > +struct efm32_pmx_func {
> > + const char *name;
> > + const char **groups;
> > + const unsigned ngroups;
> > + const unsigned *mode;
> > +};
> > +
> > +static const char *efm32_us1_groups[] = {
> > + "us1_loc0",
> > + "us1_loc1",
> > + "us1_loc2",
> > +};
> > +
> > +/* order: TX, RX, CS, CLK */
> > +static const unsigned efm32_us_modes[] = {
> > + EFM32_MODE_PUSHPULL_HIGH, EFM32_MODE_INPUT,
> > + EFM32_MODE_DISABLE, EFM32_MODE_DISABLE
> > +};
> > +
> > +#define EFM32_PMXFUNC(_name, num) { \
> > + .name = #_name #num, \
> > + .groups = efm32_ ## _name ## num ## _groups, \
> > + .ngroups = ARRAY_SIZE(efm32_ ## _name ## num ## _groups),\
> > + .mode = efm32_ ## _name ## _modes, \
> > + }
> > +
> > +static const struct efm32_pmx_func efm32_pmx_funcs[] = {
> > + EFM32_PMXFUNC(us, 1),
> > +};
>
> If you're getting all your information from pdata, I'm not sure why
> part of it is hard-coded into the driver...
I forgot to remove these. My first running driver had all the data
hardcoded as is done here. Then I switched to platform_data.
> > +static int efm32_pinctrl_pmx_enable(struct pinctrl_dev *pctldev,
> > + unsigned func_selector,
> > + unsigned group_selector)
> > +{
> > + struct efm32_pinctrl_ddata *ddata = pctldev->driver_data;
> > +
> > + const struct efm32_pmx_func *func;
> > + const char *groupname;
> > + const struct efm32_pinctl_group *group;
> > + unsigned i;
> > +
> > + efm32_pinctrl_dbg(ddata, "%s(%u, %u)\n",
> > + __func__, func_selector, group_selector);
> > +
> > + func = &efm32_pmx_funcs[func_selector];
> > + groupname = func->groups[group_selector];
> > + group = efm32_pinctrl_lookup_group(pctldev, groupname);
>
> I'm not sure that's correct; group_selector is a global identifier, not
> something that can only be interpreted relative to a particular function.
Ah, I thought it were relative to the function. IMHO that would make
sence. Then maybe we don't need the explicit per pin controller group
enumeration?!
> In other words, shouldn't those last 3 lines be:
>
> func = &efm32_pmx_funcs[func_selector];
> group = pdata->groups[group_selector];
>
> or something like that?
>
> > +static int __devinit efm32_pinctrl_probe(struct platform_device *pdev)
> > +{
> > + int ret = -ENOMEM;
> > + struct efm32_pinctrl_ddata *ddata;
> > + const struct resource *res;
> > +
> > + ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
>
> I think there's an indentation error there.
uups, I shouldn't post patches that late in the night.
> If you use devm_kzalloc, and also devm_ioremap below, you can avoid
> having to write some of the cleanup code at all.
I'll look into that. I'm keen to save memory as long as it's reasonable
as the RAM size is quite tight. I need to do xip with (up to now) enough
flash. So a cleanup routine doesn't hurt much.
> > + ddata->pinctrldev = pinctrl_register(&ddata->pinctrldesc,
> > + &pdev->dev, ddata);
> > + if (!ddata->pinctrldev) {
> > + ret = -EINVAL;
> > + dev_dbg(&pdev->dev, "failed to register pinctrl device");
> > +
> > + clk_unprepare(ddata->clk);
> > +err_clk_prepare:
> > +
> > + clk_put(ddata->clk);
> > +err_clk_get:
> > +
> > + iounmap(ddata->base);
> > +err_ioremap:
> > +err_get_base:
> > +err_platdata:
> > + kfree(ddata);
> > + } else
> > + efm32_pinctrl_dbg(ddata, "initialized (%p, %p)\n", ddata, ddata->pinctrldev);
> > +
> > +err_ddata_kzalloc:
> > + return ret;
> > +}
>
> That's a pretty unusual code structure. You'd usually put all the err_foo:
> labels right at the end of the function, and have even that last if()
> condition jump to an error:
>
> ddata->pinctrldev = pinctrl_register(&ddata->pinctrldesc,
> &pdev->dev, ddata);
> if (!ddata->pinctrldev) {
> ret = -EINVAL;
> dev_dbg(&pdev->dev, "failed to register pinctrl device");
> goto err_register;
> } else
> efm32_pinctrl_dbg(ddata, "initialized (%p, %p)\n", ddata, ddata->pinctrldev);
>
> return 0;
>
> err_register:
> clk_unprepare(ddata->clk);
> err_clk_prepare:
> clk_put(ddata->clk);
> err_clk_get:
> iounmap(ddata->base);
> err_ioremap:
> err_get_base:
> err_platdata:
> kfree(ddata);
> err_ddata_kzalloc:
> return ret;
> }
>
> ... that keeps all the error if() blocks looking the same.
personally I prefer my layout. It saves one goto :-)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
next prev parent reply other threads:[~2011-12-09 9:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-08 22:40 [PATCH] [RFC] pinctrl: add a driver for Energy Micro's efm32 SoCs Uwe Kleine-König
2011-12-08 22:55 ` Arnd Bergmann
2011-12-09 9:23 ` Uwe Kleine-König
2011-12-09 13:55 ` Arnd Bergmann
2011-12-09 14:15 ` Uwe Kleine-König
2011-12-08 23:14 ` Stephen Warren
2011-12-09 1:01 ` Shawn Guo
2011-12-09 3:44 ` Stephen Warren
2011-12-09 4:32 ` Shawn Guo
2011-12-09 4:47 ` Stephen Warren
2011-12-09 5:14 ` Shawn Guo
2011-12-09 11:08 ` Sascha Hauer
2011-12-09 13:01 ` Uwe Kleine-König
2011-12-10 0:18 ` Linus Walleij
2011-12-12 14:37 ` Sascha Hauer
2011-12-12 15:29 ` Uwe Kleine-König
2011-12-13 0:41 ` Linus Walleij
2011-12-09 16:53 ` Stephen Warren
2011-12-09 15:03 ` Dong Aisheng
2011-12-09 16:49 ` Stephen Warren
2011-12-09 17:24 ` Tony Lindgren
2011-12-09 17:53 ` Tony Lindgren
2011-12-10 0:14 ` Stephen Warren
2011-12-11 19:34 ` Tony Lindgren
2011-12-09 9:31 ` Uwe Kleine-König [this message]
2011-12-10 0:04 ` Linus Walleij
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=20111209093123.GS4585@pengutronix.de \
--to=u.kleine-koenig@pengutronix.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 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).