Re: [PATCH 2/3] pinctrl: Add pincontrol driver for ARTPEC-6 SoC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 30, 2017 at 1:33 PM, Jesper Nilsson <jesper.nilsson@xxxxxxxx> wrote:

> Add pinctrl driver support for the Axis ARTPEC-6 SoC.
> There are only some pins that actually have different
> functions available, but all can control bias (pull-up/-down)
> and drive strength.
> Code originally written by Chris Paterson.
>
> Signed-off-by: Jesper Nilsson <jesper.nilsson@xxxxxxxx>

Very good start, but look at this:


> +#define ARTPEC6_PINMUX_P0_0_CTRL       0x000
> +#define ARTPEC6_PINMUX_P0_1_CTRL       0x004
> +#define ARTPEC6_PINMUX_P0_2_CTRL       0x008
> +#define ARTPEC6_PINMUX_P0_3_CTRL       0x00C
> +#define ARTPEC6_PINMUX_P0_4_CTRL       0x010
> +#define ARTPEC6_PINMUX_P0_5_CTRL       0x014
> +#define ARTPEC6_PINMUX_P0_6_CTRL       0x018
> +#define ARTPEC6_PINMUX_P0_7_CTRL       0x01C
> +#define ARTPEC6_PINMUX_P0_8_CTRL       0x020
> +#define ARTPEC6_PINMUX_P0_9_CTRL       0x024
> +#define ARTPEC6_PINMUX_P0_10_CTRL      0x028
> +#define ARTPEC6_PINMUX_P0_11_CTRL      0x02C
> +#define ARTPEC6_PINMUX_P0_12_CTRL      0x030
> +#define ARTPEC6_PINMUX_P0_13_CTRL      0x034
> +#define ARTPEC6_PINMUX_P0_14_CTRL      0x038
> +#define ARTPEC6_PINMUX_P0_15_CTRL      0x03C

It's pretty clear that the stride is always 4 bytes is it not.


> +static const unsigned int pin_regs[] = {
> +       ARTPEC6_PINMUX_P0_0_CTRL,       /* Pin 0 */
> +       ARTPEC6_PINMUX_P0_1_CTRL,
> +       ARTPEC6_PINMUX_P0_2_CTRL,
> +       ARTPEC6_PINMUX_P0_3_CTRL,
> +       ARTPEC6_PINMUX_P0_4_CTRL,
> +       ARTPEC6_PINMUX_P0_5_CTRL,
> +       ARTPEC6_PINMUX_P0_6_CTRL,
> +       ARTPEC6_PINMUX_P0_7_CTRL,
> +       ARTPEC6_PINMUX_P0_8_CTRL,
> +       ARTPEC6_PINMUX_P0_9_CTRL,
> +       ARTPEC6_PINMUX_P0_10_CTRL,
> +       ARTPEC6_PINMUX_P0_11_CTRL,
> +       ARTPEC6_PINMUX_P0_12_CTRL,
> +       ARTPEC6_PINMUX_P0_13_CTRL,
> +       ARTPEC6_PINMUX_P0_14_CTRL,
> +       ARTPEC6_PINMUX_P0_15_CTRL,

The oceans of redundant information are rising ;)

> +static const unsigned int uart0_regs0[] = {
> +       ARTPEC6_PINMUX_P1_0_CTRL,
> +       ARTPEC6_PINMUX_P1_1_CTRL,
> +       ARTPEC6_PINMUX_P1_2_CTRL,
> +       ARTPEC6_PINMUX_P1_3_CTRL,
> +       ARTPEC6_PINMUX_P1_4_CTRL,
> +       ARTPEC6_PINMUX_P1_5_CTRL,
> +       ARTPEC6_PINMUX_P1_6_CTRL,
> +       ARTPEC6_PINMUX_P1_7_CTRL,
> +       ARTPEC6_PINMUX_P1_8_CTRL,
> +       ARTPEC6_PINMUX_P1_9_CTRL,
> +};

And rising.

> +       {
> +               .name = "uart0grp0",
> +               .pins = uart0_pins0,
> +               .num_pins = ARRAY_SIZE(uart0_pins0),
> +               .reg_offsets = uart0_regs0,
> +               .num_regs = ARRAY_SIZE(uart0_regs0),
> +               .config = ARTPEC6_CONFIG_1,
> +       },

So what if the struct artpec6_pin_group...

> +struct artpec6_pin_group {
> +       const char         *name;
> +       const unsigned int *pins;
> +       const unsigned int num_pins;
> +       const unsigned int *reg_offsets;
> +       const unsigned int num_regs;
> +       unsigned char      config;
> +};

Instead of reg_offsets had reg_offset_base, and you just
calculate it with base + pin * 4 when you need it?

I also highly suspect that num_pins and num_regs above
are exactly the same number in all cases, correct? You
probably only need num_pins.

> +static struct artpec6_pmx_func artpec6_pmx_functions[] = {

Needs const

> +static void artpec6_pmx_select_func(struct pinctrl_dev *pctldev,
> +                                   unsigned int function, unsigned int group,
> +                                   bool enable)
> +{
> +       unsigned int regval, val;
> +       int i;
> +       const unsigned int *pmx_regs;
> +       struct artpec6_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
> +
> +       pmx_regs = artpec6_pin_groups[group].reg_offsets;
> +
> +       for (i = 0; i < artpec6_pin_groups[group].num_regs; i++) {
> +               /* Ports 4-8 do not have a SEL field and are always selected */
> +               if (pmx_regs[i] >= ARTPEC6_PINMUX_P4_0_CTRL)
> +                       continue;
> +
> +               if (!strcmp(artpec6_pmx_get_fname(pctldev, function), "gpio")) {
> +                       /* GPIO is always config 0 */
> +                       val = ARTPEC6_CONFIG_0 << ARTPEC6_PINMUX_SEL_SHIFT;
> +               } else {
> +                       if (enable)
> +                               val = artpec6_pin_groups[group].config
> +                                       << ARTPEC6_PINMUX_SEL_SHIFT;
> +                       else
> +                               val = ARTPEC6_CONFIG_0
> +                                       << ARTPEC6_PINMUX_SEL_SHIFT;
> +               }
> +
> +               regval = readl(pmx->base + pmx_regs[i]);
> +               regval &= ~ARTPEC6_PINMUX_SEL_MASK;
> +               regval |= val;
> +               writel(regval, pmx->base + pmx_regs[i]);
> +       }

So thus look can be different and include something like +=4 for the registers
for each iteration.

> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-artpec6.h

You don't need to have these defines in their own file, just copy it into
the top of the driver file.

> +/* Pinmux control register offset definitions */
> +
> +#define ARTPEC6_PINMUX_P1_0_CTRL       0x040
> +#define ARTPEC6_PINMUX_P1_1_CTRL       0x044
(...)

So for these defines you only need the first one.

With these things fixes I'm pretty sure it is close to finished.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux