RE: [PATCH v2] clk: Document of_parse_clkspec() some more

2019-08-27 Thread Phil Edworthy
Hi Stephen,

On 26 August 2019 22:21 Stephen Boyd wrote:
> The return value of of_parse_clkspec() is peculiar. If the function is
> called with a NULL argument for 'name' it will return -ENOENT, but if
> it's called with a non-NULL argument for 'name' it will return -EINVAL.
> This peculiarity is documented by commit 5c56dfe63b6e ("clk: Add comment
> about __of_clk_get_by_name() error values").
> 
> Let's further document this function so that it's clear what the return
> value is and how to use the arguments to parse clk specifiers.
> 
> Cc: Phil Edworthy 
> Signed-off-by: Stephen Boyd 

Thanks, this is much better than my comment!

Reviewed-by: Phil Edworthy 

> ---
>  drivers/clk/clk.c | 43 +--
>  1 file changed, 37 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c0990703ce54..5c6585eb35d4 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -4316,12 +4316,43 @@ void devm_of_clk_del_provider(struct device
> *dev)
>  }
>  EXPORT_SYMBOL(devm_of_clk_del_provider);
> 
> -/*
> - * Beware the return values when np is valid, but no clock provider is found.
> - * If name == NULL, the function returns -ENOENT.
> - * If name != NULL, the function returns -EINVAL. This is because
> - * of_parse_phandle_with_args() is called even if
> of_property_match_string()
> - * returns an error.
> +/**
> + * of_parse_clkspec() - Parse a DT clock specifier for a given device node
> + * @np: device node to parse clock specifier from
> + * @index: index of phandle to parse clock out of. If index < 0, @name is
> used
> + * @name: clock name to find and parse. If name is NULL, the index is used
> + * @out_args: Result of parsing the clock specifier
> + *
> + * Parses a device node's "clocks" and "clock-names" properties to find the
> + * phandle and cells for the index or name that is desired. The resulting
> clock
> + * specifier is placed into @out_args, or an errno is returned when there's a
> + * parsing error. The @index argument is ignored if @name is non-NULL.
> + *
> + * Example:
> + *
> + * phandle1: clock-controller@1 {
> + *   #clock-cells = <2>;
> + * }
> + *
> + * phandle2: clock-controller@2 {
> + *   #clock-cells = <1>;
> + * }
> + *
> + * clock-consumer@3 {
> + *   clocks = < 1 2  3>;
> + *   clock-names = "name1", "name2";
> + * }
> + *
> + * To get a device_node for `clock-controller@2' node you may call this
> + * function a few different ways:
> + *
> + *   of_parse_clkspec(clock-consumer@3, -1, "name2", );
> + *   of_parse_clkspec(clock-consumer@3, 1, NULL, );
> + *   of_parse_clkspec(clock-consumer@3, 1, "name2", );
> + *
> + * Return: 0 upon successfully parsing the clock specifier. Otherwise, -
> ENOENT
> + * if @name is NULL or -EINVAL if @name is non-NULL and it can't be found
> in
> + * the "clock-names" property of @np.
>   */
>  static int of_parse_clkspec(const struct device_node *np, int index,
>   const char *name, struct of_phandle_args
> *out_args)
> --
> Sent by a computer through tubes



RE: [PATCH v3 1/2] dt-bindings: clock: renesas,r9a06g032-sysctrl: Document power Domains

2019-06-03 Thread Phil Edworthy
Hi Geert,

On 03 June 2019 09:39 Geert Uytterhoeven wrote:
> On Mon, Jun 3, 2019 at 10:29 AM Phil Edworthy wrote:
> > On 28 May 2019 08:29 Geert Uytterhoeven wrote:
> > > On Fri, May 24, 2019 at 5:32 PM Gareth Williams wrote:
> > > > The driver is gaining power domain support, so add the new property to
> > > > the DT binding and update the examples.
> > > >
> > > > Signed-off-by: Gareth Williams 
> 
> > > > ---
> > > > a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> sysctrl.txt
> > > > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> sysctrl.txt
> > > @@ -40,4 +42,5 @@ Examples
> > > > reg-io-width = <4>;
> > > > clocks = < R9A06G032_CLK_UART0>;
> > > > clock-names = "baudclk";
> > > > +   power-domains = <>;
> > >
> > > This is an interesting example: according to the driver,
> > > R9A06G032_CLK_UART0, is not clock used for power management?
> > >
> > > Oh, the real uart0 node in arch/arm/boot/dts/r9a06g032.dtsi uses
> > >
> > > clocks = < R9A06G032_CLK_UART0>, <
> > > R9A06G032_HCLK_UART0>;
> > > clock-names = "baudclk", "apb_pclk";
> > >
> > > That does make sense...
> > Note that the Synopsys DW uart driver already gets the "apb_pclk" clock,
> so
> > we don’t actually need to use clock domains to enable this clock.
> 
> That is not necessarily a problem:
>   1) DT describes hardware, not software policy,
>   2) It doesn't hurt to enable a clock twice.
Yes, that was my take as well.

> There are still some R-Car drivers that manage clocks themselves, but
> we're slowly migrating away from that, where possible. If the driver
> is e.g. shared with a platform without clock domains, we obviously cannot
> do that.
> 
> So you can take out that code again, that's up to you.
I think leaving it as is best.

> > This is also true for many of the peripheral drivers used on rzn1 (Synopsys
> > gpio controller, i2c controller, gmac, dmac, Arasan sdio controller). The
> > commit to add this clock to the i2c controller driver is my fault, as I was
> > following the pattern of the others.
> >
> > Of the few drivers that don't already get the hclk/pclk used to access the
> > peripherals is the Synopsys spi controller (though that currently doesn’t
> > support runtime PM) and the USB Host controller.
> 
> Good, so the latter will start working magically, I assume? ;-)
Yes, except for the usb PLL. The rzn1 has a mode bit that switches USB
between 2xHost and 1xHost + 1xFunc, however the PLL must be started after
the mode bit has been set. That still needs to be implemented...

BR
Phil
 
> Gr{oetje,eeting}s,
> 
> Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
> -- Linus Torvalds


RE: [PATCH v3 1/2] dt-bindings: clock: renesas,r9a06g032-sysctrl: Document power Domains

2019-06-03 Thread Phil Edworthy
Hi Geert,

On 28 May 2019 08:29 Geert Uytterhoeven wrote:
> On Fri, May 24, 2019 at 5:32 PM Gareth Williams wrote:
> > The driver is gaining power domain support, so add the new property to
> > the DT binding and update the examples.
> >
> > Signed-off-by: Gareth Williams 
> 
> Thanks for your patch!
> 
> > ---
> > a/Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.tx
> > t
> > +++ b/Documentation/devicetree/bindings/clock/renesas,r9a06g032-
> sysctr
> > +++ l.txt
> @@ -40,4 +42,5 @@ Examples
> > reg-io-width = <4>;
> > clocks = < R9A06G032_CLK_UART0>;
> > clock-names = "baudclk";
> > +   power-domains = <>;
> 
> This is an interesting example: according to the driver,
> R9A06G032_CLK_UART0, is not clock used for power management?
> 
> Oh, the real uart0 node in arch/arm/boot/dts/r9a06g032.dtsi uses
> 
> clocks = < R9A06G032_CLK_UART0>, <
> R9A06G032_HCLK_UART0>;
> clock-names = "baudclk", "apb_pclk";
> 
> That does make sense...
Note that the Synopsys DW uart driver already gets the "apb_pclk" clock, so
we don’t actually need to use clock domains to enable this clock.

This is also true for many of the peripheral drivers used on rzn1 (Synopsys
gpio controller, i2c controller, gmac, dmac, Arasan sdio controller). The
commit to add this clock to the i2c controller driver is my fault, as I was
following the pattern of the others.

Of the few drivers that don't already get the hclk/pclk used to access the
peripherals is the Synopsys spi controller (though that currently doesn’t
support runtime PM) and the USB Host controller.

BR
Phil
 
> With the above fixed:
> Reviewed-by: Geert Uytterhoeven 
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
> -- Linus Torvalds


RE: [PATCH] clk: renesas: r9a06g032: Add clock domain support

2019-05-20 Thread Phil Edworthy
Hi Gareth,

On 17 May 2019 15:48, Gareth Williams wrote:
> There are several clocks on the r9ag032 which are currently not enabled
> in their drivers that can be delegated to clock domain system for power
> management. Therefore add support for clock domain functionality to the
> r9a06g032 clock driver.
> 
> Signed-off-by: Gareth Williams 

Your patch appears to be on top of some other work that is not in next
or elsewhere.
Please can you rebase it onto Geert's renesas-drivers branch
(kernel/git/geert/renesas-drivers.git).

Thanks
Phil

> ---
>  drivers/clk/renesas/r9a06g032-clocks.c | 243
> -
>  1 file changed, 176 insertions(+), 67 deletions(-)
> 
> diff --git a/drivers/clk/renesas/r9a06g032-clocks.c
> b/drivers/clk/renesas/r9a06g032-clocks.c
> index 0b492b5..8a278da 100644
> --- a/drivers/clk/renesas/r9a06g032-clocks.c
> +++ b/drivers/clk/renesas/r9a06g032-clocks.c
> @@ -15,6 +15,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -49,6 +51,7 @@ struct r9a06g032_gate {
>  /* This is used to describe a clock for instantiation */
>  struct r9a06g032_clkdesc {
>   const char *name;
> + bool managed;
>   u32 type: 3;
>   u32 index: 8;
>   u32 source : 8; /* source index + 1 (0 == none) */
> @@ -81,7 +84,11 @@ struct r9a06g032_clkdesc {
>  #define D_GATE(_idx, _n, _src, ...) \
>   { .type = K_GATE, .index = R9A06G032_##_idx, \
>   .source = 1 + R9A06G032_##_src, .name = _n, \
> - .gate = I_GATE(__VA_ARGS__), }
> + .managed = 0, .gate = I_GATE(__VA_ARGS__) }
> +#define D_MODULE(_idx, _n, _src, ...) \
> + { .type = K_GATE, .index = R9A06G032_##_idx, \
> + .source = 1 + R9A06G032_##_src, .name = _n, \
> + .managed = 1, .gate = I_GATE(__VA_ARGS__) }
>  /* Fixed-factor multipler and divider for root clocks */
>  #define D_ROOT(_idx, _n, _mul, _div) \
>   { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \
> @@ -198,7 +205,7 @@ static const struct r9a06g032_clkdesc
> r9a06g032_clocks[] __initconst = {
>   D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4,
> 0x8a5, 0, 0xb61, 0, 0),
>   D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7,
> 0x8a8, 0, 0xb62, 0, 0),
>   D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa,
> 0x8ab, 0, 0xb63, 0, 0),
> - D_GATE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0, 0,
> 0, 0),
> + D_MODULE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0,
> 0, 0, 0),
>   D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0,
> 0),
>   D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0,
> 0),
>   D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0,
> 0, 0, 0),
> @@ -215,17 +222,17 @@ static const struct r9a06g032_clkdesc
> r9a06g032_clocks[] __initconst = {
>   D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0),
>   D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0,
> 0, 0, 0),
>   D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8),
> - D_GATE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401,
> 0, 0x402, 0, 0x440, 0x441),
> - D_GATE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740,
> 0x741, 0x742, 0, 0xae0, 0, 0),
> - D_GATE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0,
> 0x421, 0, 0x460, 0x461),
> - D_GATE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4,
> 0x8c5, 0, 0xb41, 0, 0),
> - D_GATE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7,
> 0x8c8, 0, 0xb42, 0, 0),
> - D_GATE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca,
> 0x8cb, 0, 0xb43, 0, 0),
> - D_GATE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744,
> 0x745, 0, 0xae1, 0, 0),
> - D_GATE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747,
> 0x748, 0, 0xae2, 0, 0),
> - D_GATE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0,
> 0x102, 0x103),
> - D_GATE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2,
> 0, 0x100, 0x101),
> - D_GATE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0,
> 0, 0),
> + D_MODULE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400,
> 0x401, 0, 0x402, 0, 0x440, 0x441),
> + D_MODULE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40,
> 0x740, 0x741, 0x742, 0, 0xae0, 0, 0),
> + D_MODULE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420,
> 0x422, 0, 0x421, 0, 0x460, 0x461),
> + D_MODULE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4,
> 0x8c5, 0, 0xb41, 0, 0),
> + D_MODULE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7,
> 0x8c8, 0, 0xb42, 0, 0),
> + D_MODULE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca,
> 0x8cb, 0, 0xb43, 0, 0),
> + D_MODULE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743,
> 0x744, 0x745, 0, 0xae1, 0, 0),
> + D_MODULE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746,
> 0x747, 0x748, 0, 0xae2, 0, 0),
> + D_MODULE(HCLK_USBF, "hclk_usbf", 

RE: [PATCH v4 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-25 Thread Phil Edworthy
Hi Marc,

On 20 February 2019 11:33 Phil Edworthy wrote:
> On 20 February 2019 10:05 Marc Zyngier wrote:
> > On Wed, 20 Feb 2019 09:07:02 +0000, Phil Edworthy wrote:
> > > On 19 February 2019 20:29 Marc Zyngier wrote:
> >
> > [...]
> >
> > > > > + for (i = 0; i < MAX_NR_INPUT_IRQS; i++)
> > > > > + irq_create_mapping(priv->irq_domain, i);
> > > >
> > > > This should never happen. Mappings should be created from
> > > > discovering
> > the
> > > > interrupt specifiers for devices in the DT, and not eagerly at probe 
> > > > time.
> > >
> > > The key issue here is that the mappings should not be dynamically
> > > allocated.  On the device that has this hardware, there is a Cortex
> > > M3 that is likely to use some of these GPIO interrupts.  Maybe it
> > > would be better to limit the number of GPIO irqs that Linux can
> > > configure dynamically.
> >
> > But whatever the M3 is going to use is known statically for a given
> > instance of this platform, right? You can always tell from the device
> > tree which pins are available for Linux and which are not. Or can't you?
> Yes, you can tell what pins are available to Linux. You can't tell how many 
> pins
> have been setup as GPIO irqs for use by the M3 though.
> I suppose the DT could describe the M3 as well, though I can imagine that
> could get complicated. I've not seen a DT that covers different cores running
> different software, esp. when the M3 firmware doesn't use DT.
> I was thinking that the DT could have a prop to tell this driver what GPIO 
> irqs
> are already in use.
I've just realised that it doesn't matter if we don't know how many interrupts
are used by the M3, as Linux will not claim more than the remaining interrupts.

Thanks
Phil

> > > Looks like I've gone off in the wrong direction yet again.
> >
> > Nothing we can't help with. If you can explain all the constraints of
> > the platform, we can come up with a fairly simple driver. And surely
> > LinusW can chime in for the DT part, which seems to need some loving
> > too.
> Many thanks, I need some help here!
> 
> Phil


RE: [PATCH v4 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-20 Thread Phil Edworthy
Hi Marc,

On 20 February 2019 10:05 Marc Zyngier wrote:
> On Wed, 20 Feb 2019 09:07:02 +0000, Phil Edworthy wrote:
> > On 19 February 2019 20:29 Marc Zyngier wrote:
> 
> [...]
> 
> > > > +   for (i = 0; i < MAX_NR_INPUT_IRQS; i++)
> > > > +   irq_create_mapping(priv->irq_domain, i);
> > >
> > > This should never happen. Mappings should be created from discovering
> the
> > > interrupt specifiers for devices in the DT, and not eagerly at probe time.
> >
> > The key issue here is that the mappings should not be dynamically
> > allocated.  On the device that has this hardware, there is a Cortex
> > M3 that is likely to use some of these GPIO interrupts.  Maybe it
> > would be better to limit the number of GPIO irqs that Linux can
> > configure dynamically.
> 
> But whatever the M3 is going to use is known statically for a given
> instance of this platform, right? You can always tell from the device
> tree which pins are available for Linux and which are not. Or can't you?
Yes, you can tell what pins are available to Linux. You can't tell how
many pins have been setup as GPIO irqs for use by the M3 though.
I suppose the DT could describe the M3 as well, though I can imagine
that could get complicated. I've not seen a DT that covers different
cores running different software, esp. when the M3 firmware doesn't
use DT.
I was thinking that the DT could have a prop to tell this driver what
GPIO irqs are already in use.
 
> > Looks like I've gone off in the wrong direction yet again.
> 
> Nothing we can't help with. If you can explain all the constraints of
> the platform, we can come up with a fairly simple driver. And surely
> LinusW can chime in for the DT part, which seems to need some loving
> too.
Many thanks, I need some help here!

Phil


RE: [PATCH v4 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-20 Thread Phil Edworthy
Hi Marc

On 19 February 2019 20:29 Marc Zyngier wrote:
> On Tue, 19 Feb 2019 15:55:11 +0000 Phil Edworthy wrote:
> 
> + LinusW, who seem to have taken an interest in irqchip hierarchies...
> 
> > On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
> > configured to have 32 interrupt outputs, so we have a total of 96 GPIO
> > interrupts. All of these are passed to the GPIO IRQ Muxer, which
> > selects
> > 8 of the GPIO interrupts to pass onto the GIC. The interrupt signals
> > aren't latched, so there is nothing to do in this driver when an
> > interrupt is received, other than tell the corresponding GPIO block.
> >
> > Signed-off-by: Phil Edworthy 
> > ---
> > v4:
> >  - No change.
> > v3:
> >  - Use 'interrupt-map' DT property to map the interrupts, this is very 
> > similar
> >to PCIe MSI. The only difference is that we need to get hold of the
> interrupt
> >specifier for the interupts coming into the irqmux.
> >  - Do not use a chained interrupt controller.
> > v2:
> >  - Use interrupt-map to allow the GPIO controller info to be specified
> >as part of the irq.
> >  - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.
> > ---
> >  drivers/irqchip/Kconfig|   9 ++
> >  drivers/irqchip/Makefile   |   1 +
> >  drivers/irqchip/rzn1-irq-mux.c | 205
> > +
> >  3 files changed, 215 insertions(+)
> >  create mode 100644 drivers/irqchip/rzn1-irq-mux.c
> >
> > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index
> > 5dcb5456cd14..369f78d6b521 100644
> > --- a/drivers/irqchip/Kconfig
> > +++ b/drivers/irqchip/Kconfig
> > @@ -211,6 +211,15 @@ config RENESAS_IRQC
> > select GENERIC_IRQ_CHIP
> > select IRQ_DOMAIN
> >
> > +config RENESAS_RZN1_IRQ_MUX
> > +   bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
> > +   depends on ARCH_RZN1
> > +   select IRQ_DOMAIN
> > +   help
> > + Say yes here to add support for the GPIO IRQ multiplexer
> embedded
> > + in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
> > + the interrupts coming from the GPIO controllers are used.
> > +
> >  config ST_IRQCHIP
> > bool
> > select REGMAP
> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index
> > 7acd0e36d0b4..2edd42ef2182 100644
> > --- a/drivers/irqchip/Makefile
> > +++ b/drivers/irqchip/Makefile
> > @@ -46,6 +46,7 @@ obj-$(CONFIG_JCORE_AIC)   +=
> irq-jcore-aic.o
> >  obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
> >  obj-$(CONFIG_RENESAS_INTC_IRQPIN)  += irq-renesas-intc-irqpin.o
> >  obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
> > +obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX) += rzn1-irq-mux.o
> >  obj-$(CONFIG_VERSATILE_FPGA_IRQ)   += irq-versatile-fpga.o
> >  obj-$(CONFIG_ARCH_NSPIRE)  += irq-zevio.o
> >  obj-$(CONFIG_ARCH_VT8500)  += irq-vt8500.o
> > diff --git a/drivers/irqchip/rzn1-irq-mux.c
> > b/drivers/irqchip/rzn1-irq-mux.c new file mode 100644 index
> > ..ee7810b9b3f3
> > --- /dev/null
> > +++ b/drivers/irqchip/rzn1-irq-mux.c
> > @@ -0,0 +1,205 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * RZ/N1 GPIO Interrupt Multiplexer
> > + *
> > + * Copyright (C) 2018 Renesas Electronics Europe Limited
> > + *
> > + * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
> > +configured
> > + * to have 32 interrupt outputs, so we have a total of 96 GPIO interrupts.
> > + * All of these are passed to the GPIO IRQ Muxer, which selects 8 of
> > +the GPIO
> > + * interrupts to pass onto the GIC.
> 
> So that I get it right:
> 
> - 96 inputs
> - 8 outputs
> 
> This driver picks 8 of the inputs (and at most 8), and pass then down to the
> GIC. Do I understand that correctly?
Correct.

> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define MAX_NR_INPUT_IRQS  96
> > +#define MAX_NR_OUTPUT_IRQS 8
> > +
> > +/*
> > + * "interrupt-map" consists of 1 interrupt cell, 0 address cells,
> > +phandle to
> > + * interrupt parent, and parent interrupt specifier (3 cells for
> > +GIC), giving
> > + * a total of 5 cells.
> > + */
> > +#define IMAP_LENGTH5
> 
> Although the maths do check out, I find it rather dangerous. The versat

[PATCH v4 0/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-19 Thread Phil Edworthy
On RZ/N1 devices, there are lots of GPIO interrupts that are multiplexed before
getting to the GIC interrupt controller. Other than the multiplexing, there is
no other logic applied to the signals.

The multiplexing cannot be handled dynamically because there is another CPU that
runs firmware. It's likely that the firmware will use some of these GPIO
interrupts and so we don't want them to move around.

Signed-off-by: Phil Edworthy 
---
v4:
 - Fix DT binding nits
v3:
 - Use 'interrupt-map' DT property to map the interrupts, this is very similar
   to PCIe MSI. The only difference is that we need to get hold of the interrupt
   specifier for the interupts coming into the irqmux.
   I had completely messed up the use of 'interrupt-map' in v2... oops.
 - Do not use a chained interrupt controller.
v2:
 - Split DT bindings into separate patch.
 - Use interrupt-map to allow the GPIO controller info to be specified
   as part of the irq.
 - Don't show status in binding examples.
 - Don't show the soc/board split in binding doc.
 - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.

Phil Edworthy (2):
  dt-bindings/interrupt-controller: rzn1: Add RZ/N1 gpio irq mux binding
  irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

 .../interrupt-controller/renesas,rzn1-mux.txt |  73 +++
 drivers/irqchip/Kconfig   |   9 +
 drivers/irqchip/Makefile  |   1 +
 drivers/irqchip/rzn1-irq-mux.c| 205 ++
 4 files changed, 288 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-mux.txt
 create mode 100644 drivers/irqchip/rzn1-irq-mux.c

-- 
2.17.1



[PATCH v4 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-19 Thread Phil Edworthy
On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
configured to have 32 interrupt outputs, so we have a total of 96 GPIO
interrupts. All of these are passed to the GPIO IRQ Muxer, which selects
8 of the GPIO interrupts to pass onto the GIC. The interrupt signals
aren't latched, so there is nothing to do in this driver when an interrupt
is received, other than tell the corresponding GPIO block.

Signed-off-by: Phil Edworthy 
---
v4:
 - No change.
v3:
 - Use 'interrupt-map' DT property to map the interrupts, this is very similar
   to PCIe MSI. The only difference is that we need to get hold of the interrupt
   specifier for the interupts coming into the irqmux.
 - Do not use a chained interrupt controller.
v2:
 - Use interrupt-map to allow the GPIO controller info to be specified
   as part of the irq.
 - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.
---
 drivers/irqchip/Kconfig|   9 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/rzn1-irq-mux.c | 205 +
 3 files changed, 215 insertions(+)
 create mode 100644 drivers/irqchip/rzn1-irq-mux.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 5dcb5456cd14..369f78d6b521 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -211,6 +211,15 @@ config RENESAS_IRQC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config RENESAS_RZN1_IRQ_MUX
+   bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
+   depends on ARCH_RZN1
+   select IRQ_DOMAIN
+   help
+ Say yes here to add support for the GPIO IRQ multiplexer embedded
+ in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
+ the interrupts coming from the GPIO controllers are used.
+
 config ST_IRQCHIP
bool
select REGMAP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 7acd0e36d0b4..2edd42ef2182 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JCORE_AIC)   += 
irq-jcore-aic.o
 obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)  += irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
+obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX) += rzn1-irq-mux.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)   += irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_NSPIRE)  += irq-zevio.o
 obj-$(CONFIG_ARCH_VT8500)  += irq-vt8500.o
diff --git a/drivers/irqchip/rzn1-irq-mux.c b/drivers/irqchip/rzn1-irq-mux.c
new file mode 100644
index ..ee7810b9b3f3
--- /dev/null
+++ b/drivers/irqchip/rzn1-irq-mux.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/N1 GPIO Interrupt Multiplexer
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each 
configured
+ * to have 32 interrupt outputs, so we have a total of 96 GPIO interrupts.
+ * All of these are passed to the GPIO IRQ Muxer, which selects 8 of the GPIO
+ * interrupts to pass onto the GIC.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MAX_NR_INPUT_IRQS  96
+#define MAX_NR_OUTPUT_IRQS 8
+
+/*
+ * "interrupt-map" consists of 1 interrupt cell, 0 address cells, phandle to
+ * interrupt parent, and parent interrupt specifier (3 cells for GIC), giving
+ * a total of 5 cells.
+ */
+#define IMAP_LENGTH5
+
+struct irqmux_priv;
+struct irqmux_one {
+   unsigned int irq;
+   unsigned int src_hwirq;
+   struct irqmux_priv *priv;
+};
+
+struct irqmux_priv {
+   struct device *dev;
+   struct irq_domain *irq_domain;
+   unsigned int nr_irqs;
+   struct irqmux_one mux[MAX_NR_OUTPUT_IRQS];
+};
+
+static irqreturn_t irqmux_handler(int irq, void *data)
+{
+   struct irqmux_one *mux = data;
+   struct irqmux_priv *priv = mux->priv;
+   unsigned int virq;
+
+   virq = irq_find_mapping(priv->irq_domain, mux->src_hwirq);
+
+   generic_handle_irq(virq);
+
+   return IRQ_HANDLED;
+}
+
+static int irqmux_domain_map(struct irq_domain *h, unsigned int irq,
+irq_hw_number_t hwirq)
+{
+   irq_set_chip_data(irq, h->host_data);
+   irq_set_chip_and_handler(irq, _irq_chip, handle_simple_irq);
+
+   return 0;
+}
+
+static const struct irq_domain_ops irqmux_domain_ops = {
+   .map = irqmux_domain_map,
+};
+
+static int irqmux_probe(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct device_node *np = dev->of_node;
+   struct resource *res;
+   u32 __iomem *regs;
+   struct irqmux_priv *priv;
+   unsigned int i;
+   int nr_irqs;
+   int ret;
+   const __be32 *imap;
+   int imaplen;
+
+   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   ret

RE: [PATCH v3 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-19 Thread Phil Edworthy
Hi Marc,

> On Tue, 19 Feb 2019 15:27:25 +
> Phil Edworthy  wrote:
> 
> > Hello,
> >
> > Any comments on this patch?
> 
> Err... I'm afraid it fell through the cracks. It's been three months, and I've
> paged out most of last year.
> 
> Can you please resend it on top of a recent -rc, and I'll try to have a look. 
> No
> promise though.

Thanks, appreciate it you can!
Phil

> 
> Thanks,
> 
>   M.
> 
> >
> > Thanks
> > Phil
> >
> > > -Original Message-
> > > From: Phil Edworthy 
> > > Sent: 13 November 2018 13:09
> > > To: Marc Zyngier ; Thomas Gleixner
> > > ; Jason Cooper 
> > > Cc: Geert Uytterhoeven ; linux-renesas-
> > > s...@vger.kernel.org; linux-kernel@vger.kernel.org; Phil Edworthy
> > > 
> > > Subject: [PATCH v3 2/2] irqchip: Add support for Renesas RZ/N1 GPIO
> > > interrupt multiplexer
> > >
> > > On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
> > > configured to have 32 interrupt outputs, so we have a total of 96
> > > GPIO interrupts. All of these are passed to the GPIO IRQ Muxer,
> > > which selects
> > > 8 of the GPIO interrupts to pass onto the GIC. The interrupt signals
> > > aren't latched, so there is nothing to do in this driver when an
> > > interrupt is received, other than tell the corresponding GPIO block.
> > >
> > > Signed-off-by: Phil Edworthy 
> > > ---
> > > v3:
> > >  - Use 'interrupt-map' DT property to map the interrupts, this is very
> similar
> > >to PCIe MSI. The only difference is that we need to get hold of the
> interrupt
> > >specifier for the interupts coming into the irqmux.
> > >  - Do not use a chained interrupt controller.
> > > v2:
> > >  - Use interrupt-map to allow the GPIO controller info to be specified
> > >as part of the irq.
> > >  - Renamed struct and funcs from 'girq' to a more comprehenisble
> 'irqmux'.
> > > ---
> > >  drivers/irqchip/Kconfig|   9 ++
> > >  drivers/irqchip/Makefile   |   1 +
> > >  drivers/irqchip/rzn1-irq-mux.c | 205
> > > +
> > >  3 files changed, 215 insertions(+)
> > >  create mode 100644 drivers/irqchip/rzn1-irq-mux.c
> > >
> > > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index
> > > 96451b581452..53c54bba1dd8 100644
> > > --- a/drivers/irqchip/Kconfig
> > > +++ b/drivers/irqchip/Kconfig
> > > @@ -204,6 +204,15 @@ config RENESAS_IRQC
> > >   select GENERIC_IRQ_CHIP
> > >   select IRQ_DOMAIN
> > >
> > > +config RENESAS_RZN1_IRQ_MUX
> > > + bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
> > > + depends on ARCH_RZN1
> > > + select IRQ_DOMAIN
> > > + help
> > > +   Say yes here to add support for the GPIO IRQ multiplexer
> > > embedded
> > > +   in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
> > > +   the interrupts coming from the GPIO controllers are used.
> > > +
> > >  config ST_IRQCHIP
> > >   bool
> > >   select REGMAP
> > > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> > > index b822199445ff..b090f84dd42e 100644
> > > --- a/drivers/irqchip/Makefile
> > > +++ b/drivers/irqchip/Makefile
> > > @@ -45,6 +45,7 @@ obj-$(CONFIG_SIRF_IRQ)  +=
> irq-
> > > sirfsoc.o
> > >  obj-$(CONFIG_JCORE_AIC)  += irq-jcore-aic.o
> > >  obj-$(CONFIG_RENESAS_INTC_IRQPIN)+= irq-renesas-intc-irqpin.o
> > >  obj-$(CONFIG_RENESAS_IRQC)   += irq-renesas-irqc.o
> > > +obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX)   += rzn1-irq-mux.o
> > >  obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
> > >  obj-$(CONFIG_ARCH_NSPIRE)+= irq-zevio.o
> > >  obj-$(CONFIG_ARCH_VT8500)+= irq-vt8500.o
> > > diff --git a/drivers/irqchip/rzn1-irq-mux.c
> > > b/drivers/irqchip/rzn1-irq-mux.c new file mode 100644 index
> > > ..ee7810b9b3f3
> > > --- /dev/null
> > > +++ b/drivers/irqchip/rzn1-irq-mux.c
> > > @@ -0,0 +1,205 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * RZ/N1 GPIO Interrupt Multiplexer
> > > + *
> > > + * Copyright (C) 2018 Renesas Electronics Europe Limited
> > > + *
> > > + * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blo

RE: [PATCH v3 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2019-02-19 Thread Phil Edworthy
Hello,

Any comments on this patch?

Thanks
Phil

> -Original Message-
> From: Phil Edworthy 
> Sent: 13 November 2018 13:09
> To: Marc Zyngier ; Thomas Gleixner
> ; Jason Cooper 
> Cc: Geert Uytterhoeven ; linux-renesas-
> s...@vger.kernel.org; linux-kernel@vger.kernel.org; Phil Edworthy
> 
> Subject: [PATCH v3 2/2] irqchip: Add support for Renesas RZ/N1 GPIO
> interrupt multiplexer
> 
> On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
> configured to have 32 interrupt outputs, so we have a total of 96 GPIO
> interrupts. All of these are passed to the GPIO IRQ Muxer, which selects
> 8 of the GPIO interrupts to pass onto the GIC. The interrupt signals aren't
> latched, so there is nothing to do in this driver when an interrupt is 
> received,
> other than tell the corresponding GPIO block.
> 
> Signed-off-by: Phil Edworthy 
> ---
> v3:
>  - Use 'interrupt-map' DT property to map the interrupts, this is very similar
>to PCIe MSI. The only difference is that we need to get hold of the 
> interrupt
>specifier for the interupts coming into the irqmux.
>  - Do not use a chained interrupt controller.
> v2:
>  - Use interrupt-map to allow the GPIO controller info to be specified
>as part of the irq.
>  - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.
> ---
>  drivers/irqchip/Kconfig|   9 ++
>  drivers/irqchip/Makefile   |   1 +
>  drivers/irqchip/rzn1-irq-mux.c | 205
> +
>  3 files changed, 215 insertions(+)
>  create mode 100644 drivers/irqchip/rzn1-irq-mux.c
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index
> 96451b581452..53c54bba1dd8 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -204,6 +204,15 @@ config RENESAS_IRQC
>   select GENERIC_IRQ_CHIP
>   select IRQ_DOMAIN
> 
> +config RENESAS_RZN1_IRQ_MUX
> + bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
> + depends on ARCH_RZN1
> + select IRQ_DOMAIN
> + help
> +   Say yes here to add support for the GPIO IRQ multiplexer
> embedded
> +   in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
> +   the interrupts coming from the GPIO controllers are used.
> +
>  config ST_IRQCHIP
>   bool
>   select REGMAP
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index
> b822199445ff..b090f84dd42e 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_SIRF_IRQ)  += irq-
> sirfsoc.o
>  obj-$(CONFIG_JCORE_AIC)  += irq-jcore-aic.o
>  obj-$(CONFIG_RENESAS_INTC_IRQPIN)+= irq-renesas-intc-irqpin.o
>  obj-$(CONFIG_RENESAS_IRQC)   += irq-renesas-irqc.o
> +obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX)   += rzn1-irq-mux.o
>  obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
>  obj-$(CONFIG_ARCH_NSPIRE)+= irq-zevio.o
>  obj-$(CONFIG_ARCH_VT8500)+= irq-vt8500.o
> diff --git a/drivers/irqchip/rzn1-irq-mux.c b/drivers/irqchip/rzn1-irq-mux.c
> new file mode 100644 index ..ee7810b9b3f3
> --- /dev/null
> +++ b/drivers/irqchip/rzn1-irq-mux.c
> @@ -0,0 +1,205 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * RZ/N1 GPIO Interrupt Multiplexer
> + *
> + * Copyright (C) 2018 Renesas Electronics Europe Limited
> + *
> + * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
> +configured
> + * to have 32 interrupt outputs, so we have a total of 96 GPIO interrupts.
> + * All of these are passed to the GPIO IRQ Muxer, which selects 8 of
> +the GPIO
> + * interrupts to pass onto the GIC.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define MAX_NR_INPUT_IRQS96
> +#define MAX_NR_OUTPUT_IRQS   8
> +
> +/*
> + * "interrupt-map" consists of 1 interrupt cell, 0 address cells,
> +phandle to
> + * interrupt parent, and parent interrupt specifier (3 cells for GIC),
> +giving
> + * a total of 5 cells.
> + */
> +#define IMAP_LENGTH  5
> +
> +struct irqmux_priv;
> +struct irqmux_one {
> + unsigned int irq;
> + unsigned int src_hwirq;
> + struct irqmux_priv *priv;
> +};
> +
> +struct irqmux_priv {
> + struct device *dev;
> + struct irq_domain *irq_domain;
> + unsigned int nr_irqs;
> + struct irqmux_one mux[MAX_NR_OUTPUT_IRQS]; };
> +
> +static irqreturn_t irqmux_handler(int irq, void *data) {
> + struct irqmux_one *mux = data;
> + struct irqmux_priv *priv = mux->priv;
> + unsigned int virq;
> +

RE: [PATCH v9 1/2] clk: Add comment about __of_clk_get_by_name() error values

2019-01-16 Thread Phil Edworthy
Hi,

Any other comments on this patch and patch 2/2 
(https://lkml.org/lkml/2018/12/3/326)?

Thanks
Phil

> -Original Message-
> From: Phil Edworthy
> Sent: 06 December 2018 12:31
> To: 'Andy Shevchenko' 
> Cc: Michael Turquette ; Stephen Boyd
> ; Russell King ; Geert
> Uytterhoeven ; Uwe Kleine-König  koe...@pengutronix.de>; linux-...@vger.kernel.org; linux-
> ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
> Subject: RE: [PATCH v9 1/2] clk: Add comment about
> __of_clk_get_by_name() error values
> 
> Hi Andy,
> 
> On 03 December 2018 13:31 Andy Shevchenko wrote:
> > On Mon, Dec 03, 2018 at 11:13:08AM +, Phil Edworthy wrote:
> > > It's not immediately obvious from the code that failure to get a
> > > clock provider can return either -ENOENT or -EINVAL. Therefore, add
> > > a comment to highlight this.
> >
> > > +/*
> > > + * Beware the return values when np is valid, but no clock provider
> > > +is
> > found.
> > > + * If name = NULL, the function returns -ENOENT.
> > > + * If name != NULL, the function returns -EINVAL. This is because
> > > +__of_clk_get()
> >
> > I would start new sentence from new line (this will emphasize the
> > possible
> > variants)
> >
> >  * This is ...
> I disagree, the explanation is specifically related to the case where the
> function returns -EINVAL. Though this is a nit, so I'm not really bothered
> either way.
> 
> Thanks for the review!
> Phil
> 
> >  Otherwise looks good to me:
> >
> > Reviewed-by: Andy Shevchenko 
> >
> > > + * is called even if of_property_match_string() returns an error.
> > > + */
> > >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > >   const char *dev_id,
> > >   const char *name)
> > > --
> > > 2.17.1
> > >
> >
> > --
> > With Best Regards,
> > Andy Shevchenko
> >



RE: [PATCH v9 1/2] clk: Add comment about __of_clk_get_by_name() error values

2018-12-06 Thread Phil Edworthy
Hi Andy,

On 03 December 2018 13:31 Andy Shevchenko wrote:
> On Mon, Dec 03, 2018 at 11:13:08AM +0000, Phil Edworthy wrote:
> > It's not immediately obvious from the code that failure to get a clock
> > provider can return either -ENOENT or -EINVAL. Therefore, add a
> > comment to highlight this.
> 
> > +/*
> > + * Beware the return values when np is valid, but no clock provider is
> found.
> > + * If name = NULL, the function returns -ENOENT.
> > + * If name != NULL, the function returns -EINVAL. This is because
> > +__of_clk_get()
> 
> I would start new sentence from new line (this will emphasize the possible
> variants)
> 
>  * This is ...
I disagree, the explanation is specifically related to the case where the 
function
returns -EINVAL. Though this is a nit, so I'm not really bothered either way.

Thanks for the review!
Phil

>  Otherwise looks good to me:
> 
> Reviewed-by: Andy Shevchenko 
> 
> > + * is called even if of_property_match_string() returns an error.
> > + */
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > const char *name)
> > --
> > 2.17.1
> >
> 
> --
> With Best Regards,
> Andy Shevchenko
> 



RE: [PATCH v9 1/2] clk: Add comment about __of_clk_get_by_name() error values

2018-12-06 Thread Phil Edworthy
Hi Andy,

On 03 December 2018 13:31 Andy Shevchenko wrote:
> On Mon, Dec 03, 2018 at 11:13:08AM +0000, Phil Edworthy wrote:
> > It's not immediately obvious from the code that failure to get a clock
> > provider can return either -ENOENT or -EINVAL. Therefore, add a
> > comment to highlight this.
> 
> > +/*
> > + * Beware the return values when np is valid, but no clock provider is
> found.
> > + * If name = NULL, the function returns -ENOENT.
> > + * If name != NULL, the function returns -EINVAL. This is because
> > +__of_clk_get()
> 
> I would start new sentence from new line (this will emphasize the possible
> variants)
> 
>  * This is ...
I disagree, the explanation is specifically related to the case where the 
function
returns -EINVAL. Though this is a nit, so I'm not really bothered either way.

Thanks for the review!
Phil

>  Otherwise looks good to me:
> 
> Reviewed-by: Andy Shevchenko 
> 
> > + * is called even if of_property_match_string() returns an error.
> > + */
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > const char *name)
> > --
> > 2.17.1
> >
> 
> --
> With Best Regards,
> Andy Shevchenko
> 



[PATCH v9 0/2] clk: Add functions to get optional clocks

2018-12-03 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

v9:
 - Add a separate patch to add a comment about __of_clk_get_by_name() error
   values.
 - Add brackets after devm_clk_get so people know it's a function.
 - Add kernel doc for clk_get_optional().


Phil Edworthy (2):
  clk: Add comment about __of_clk_get_by_name() error values
  clk: Add (devm_)clk_get_optional() functions

 drivers/clk/clk-devres.c | 11 +++
 drivers/clk/clkdev.c |  6 ++
 include/linux/clk.h  | 36 
 3 files changed, 53 insertions(+)

-- 
2.17.1



[PATCH v9 1/2] clk: Add comment about __of_clk_get_by_name() error values

2018-12-03 Thread Phil Edworthy
It's not immediately obvious from the code that failure to get a
clock provider can return either -ENOENT or -EINVAL. Therefore, add
a comment to highlight this.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clkdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8b3988..cc5df3970cd3 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -52,6 +52,12 @@ struct clk *of_clk_get(struct device_node *np, int index)
 }
 EXPORT_SYMBOL(of_clk_get);
 
+/*
+ * Beware the return values when np is valid, but no clock provider is found.
+ * If name = NULL, the function returns -ENOENT.
+ * If name != NULL, the function returns -EINVAL. This is because 
__of_clk_get()
+ * is called even if of_property_match_string() returns an error.
+ */
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
const char *name)
-- 
2.17.1



[PATCH v9 0/2] clk: Add functions to get optional clocks

2018-12-03 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

v9:
 - Add a separate patch to add a comment about __of_clk_get_by_name() error
   values.
 - Add brackets after devm_clk_get so people know it's a function.
 - Add kernel doc for clk_get_optional().


Phil Edworthy (2):
  clk: Add comment about __of_clk_get_by_name() error values
  clk: Add (devm_)clk_get_optional() functions

 drivers/clk/clk-devres.c | 11 +++
 drivers/clk/clkdev.c |  6 ++
 include/linux/clk.h  | 36 
 3 files changed, 53 insertions(+)

-- 
2.17.1



[PATCH v9 1/2] clk: Add comment about __of_clk_get_by_name() error values

2018-12-03 Thread Phil Edworthy
It's not immediately obvious from the code that failure to get a
clock provider can return either -ENOENT or -EINVAL. Therefore, add
a comment to highlight this.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clkdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8b3988..cc5df3970cd3 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -52,6 +52,12 @@ struct clk *of_clk_get(struct device_node *np, int index)
 }
 EXPORT_SYMBOL(of_clk_get);
 
+/*
+ * Beware the return values when np is valid, but no clock provider is found.
+ * If name = NULL, the function returns -ENOENT.
+ * If name != NULL, the function returns -EINVAL. This is because 
__of_clk_get()
+ * is called even if of_property_match_string() returns an error.
+ */
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
const char *name)
-- 
2.17.1



[PATCH v9 2/2] clk: Add (devm_)clk_get_optional() functions

2018-12-03 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get() except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
Reviewed-by: Andy Shevchenko 
---
v9:
 - Add brackets after devm_clk_get so people know it's a function.
 - Add kernel doc for clk_get_optional().
v8:
 - Remove else clause
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 36 
 2 files changed, 47 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..8e8893168676 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..d8bc1a856b39 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,25 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+/**
+ * clk_get_optional - lookup and obtain a reference to an optional clock
+ *   producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get() except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



[PATCH v9 2/2] clk: Add (devm_)clk_get_optional() functions

2018-12-03 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get() except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
Reviewed-by: Andy Shevchenko 
---
v9:
 - Add brackets after devm_clk_get so people know it's a function.
 - Add kernel doc for clk_get_optional().
v8:
 - Remove else clause
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 36 
 2 files changed, 47 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..8e8893168676 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..d8bc1a856b39 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,25 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+/**
+ * clk_get_optional - lookup and obtain a reference to an optional clock
+ *   producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get() except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



RE: [PATCH v8] clk: Add (devm_)clk_get_optional() functions

2018-11-30 Thread Phil Edworthy
Hi Stephen,

On 30 November 2018 09:09 Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-11-20 06:14:45)
> > This adds clk_get_optional() and devm_clk_get_optional() functions to
> > get optional clocks.
> > They behave the same as (devm_)clk_get except where there is no clock
> > producer. In this case, instead of returning -ENOENT, the function
> > returns NULL. This makes error checking simpler and allows
> > clk_prepare_enable, etc to be called on the returned reference without
> > additional checks.
> 
> Ok. I guess that works by virtue of how -ENOENT is returned by various
> functions that are called deeper in the clk_get() path? I'm cautiously
> optimistic. So cautious, we should probably add a comment to these optional
> functions that indicate they rely on the functions they call to return -ENOENT
> under the various conditions that make a clk optional.
Yes, it does indeed rely on how clk_get() is implemented.
Specifically, that if __of_clk_get_by_name() returns -EINVAL, the error is
superseded by clk_get_sys() returning -ENOENT.
As you say, a comment may help here.


> >
> > diff --git a/include/linux/clk.h b/include/linux/clk.h index
> > a7773b5c0b9f..3ea3c78f62dd 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct
> device *dev,
> >   */
> >  struct clk *devm_clk_get(struct device *dev, const char *id);
> >
> > +/**
> > + * devm_clk_get_optional - lookup and obtain a managed reference to an
> optional
> > + *clock producer.
> > + * @dev: device for clock "consumer"
> > + * @id: clock consumer ID
> > + *
> > + * Behaves the same as devm_clk_get except where there is no clock
> > +producer. In
> 
> Please add () around devm_clk_get() so we know it's a function.
Will do.


> > + * this case, instead of returning -ENOENT, the function returns NULL.
> > + */
> > +struct clk *devm_clk_get_optional(struct device *dev, const char
> > +*id);
> > +
> >  /**
> >   * devm_get_clk_from_child - lookup and obtain a managed reference to a
> >   *  clock producer from child node.
> > @@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device
> *dev, const char *id)
> > return NULL;
> >  }
> >
> > +static inline struct clk *devm_clk_get_optional(struct device *dev,
> > +   const char *id) {
> > +   return NULL;
> > +}
> > +
> >  static inline int __must_check devm_clk_bulk_get(struct device *dev, int
> num_clks,
> >  struct clk_bulk_data
> > *clks)  { @@ -862,6 +879,16 @@ static inline void
> > clk_bulk_disable_unprepare(int num_clks,
> > clk_bulk_unprepare(num_clks, clks);  }
> >
> > +static inline struct clk *clk_get_optional(struct device *dev, const
> > +char *id)
> 
> Any kernel doc for this function?
I took my cue from the surrounding functions, let me know if I have to add it.

Thanks
Phil

> > +{
> > +   struct clk *clk = clk_get(dev, id);
> > +
> > +   if (clk == ERR_PTR(-ENOENT))
> > +   clk = NULL;
> > +
> > +   return clk;
> > +}
> > +


RE: [PATCH v8] clk: Add (devm_)clk_get_optional() functions

2018-11-30 Thread Phil Edworthy
Hi Stephen,

On 30 November 2018 09:09 Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-11-20 06:14:45)
> > This adds clk_get_optional() and devm_clk_get_optional() functions to
> > get optional clocks.
> > They behave the same as (devm_)clk_get except where there is no clock
> > producer. In this case, instead of returning -ENOENT, the function
> > returns NULL. This makes error checking simpler and allows
> > clk_prepare_enable, etc to be called on the returned reference without
> > additional checks.
> 
> Ok. I guess that works by virtue of how -ENOENT is returned by various
> functions that are called deeper in the clk_get() path? I'm cautiously
> optimistic. So cautious, we should probably add a comment to these optional
> functions that indicate they rely on the functions they call to return -ENOENT
> under the various conditions that make a clk optional.
Yes, it does indeed rely on how clk_get() is implemented.
Specifically, that if __of_clk_get_by_name() returns -EINVAL, the error is
superseded by clk_get_sys() returning -ENOENT.
As you say, a comment may help here.


> >
> > diff --git a/include/linux/clk.h b/include/linux/clk.h index
> > a7773b5c0b9f..3ea3c78f62dd 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct
> device *dev,
> >   */
> >  struct clk *devm_clk_get(struct device *dev, const char *id);
> >
> > +/**
> > + * devm_clk_get_optional - lookup and obtain a managed reference to an
> optional
> > + *clock producer.
> > + * @dev: device for clock "consumer"
> > + * @id: clock consumer ID
> > + *
> > + * Behaves the same as devm_clk_get except where there is no clock
> > +producer. In
> 
> Please add () around devm_clk_get() so we know it's a function.
Will do.


> > + * this case, instead of returning -ENOENT, the function returns NULL.
> > + */
> > +struct clk *devm_clk_get_optional(struct device *dev, const char
> > +*id);
> > +
> >  /**
> >   * devm_get_clk_from_child - lookup and obtain a managed reference to a
> >   *  clock producer from child node.
> > @@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device
> *dev, const char *id)
> > return NULL;
> >  }
> >
> > +static inline struct clk *devm_clk_get_optional(struct device *dev,
> > +   const char *id) {
> > +   return NULL;
> > +}
> > +
> >  static inline int __must_check devm_clk_bulk_get(struct device *dev, int
> num_clks,
> >  struct clk_bulk_data
> > *clks)  { @@ -862,6 +879,16 @@ static inline void
> > clk_bulk_disable_unprepare(int num_clks,
> > clk_bulk_unprepare(num_clks, clks);  }
> >
> > +static inline struct clk *clk_get_optional(struct device *dev, const
> > +char *id)
> 
> Any kernel doc for this function?
I took my cue from the surrounding functions, let me know if I have to add it.

Thanks
Phil

> > +{
> > +   struct clk *clk = clk_get(dev, id);
> > +
> > +   if (clk == ERR_PTR(-ENOENT))
> > +   clk = NULL;
> > +
> > +   return clk;
> > +}
> > +


[PATCH] arm64: dts: alpine: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm64/boot/dts/al/alpine-v2.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/al/alpine-v2.dtsi 
b/arch/arm64/boot/dts/al/alpine-v2.dtsi
index 5b7bef684256..6f35bab10e9d 100644
--- a/arch/arm64/boot/dts/al/alpine-v2.dtsi
+++ b/arch/arm64/boot/dts/al/alpine-v2.dtsi
@@ -113,7 +113,7 @@
 ;
};
 
-   gic: gic@f010 {
+   gic: interrupt-controller@f010 {
compatible = "arm,gic-v3";
reg = <0x0 0xf020 0x0 0x1>, /* GIC Dist */
  <0x0 0xf028 0x0 0x20>,/* GICR */
-- 
2.17.1



[PATCH] arm64: dts: alpine: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm64/boot/dts/al/alpine-v2.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/al/alpine-v2.dtsi 
b/arch/arm64/boot/dts/al/alpine-v2.dtsi
index 5b7bef684256..6f35bab10e9d 100644
--- a/arch/arm64/boot/dts/al/alpine-v2.dtsi
+++ b/arch/arm64/boot/dts/al/alpine-v2.dtsi
@@ -113,7 +113,7 @@
 ;
};
 
-   gic: gic@f010 {
+   gic: interrupt-controller@f010 {
compatible = "arm,gic-v3";
reg = <0x0 0xf020 0x0 0x1>, /* GIC Dist */
  <0x0 0xf028 0x0 0x20>,/* GICR */
-- 
2.17.1



[PATCH] ARM: dts: alpine: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm/boot/dts/alpine.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi
index 731df7a8c4e6..533c876497ff 100644
--- a/arch/arm/boot/dts/alpine.dtsi
+++ b/arch/arm/boot/dts/alpine.dtsi
@@ -85,7 +85,7 @@
};
 
/* Interrupt Controller */
-   gic: gic@fb001000 {
+   gic: interrupt-controller@fb001000 {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
#size-cells = <0>;
-- 
2.17.1



[PATCH] ARM: dts: alpine: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm/boot/dts/alpine.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi
index 731df7a8c4e6..533c876497ff 100644
--- a/arch/arm/boot/dts/alpine.dtsi
+++ b/arch/arm/boot/dts/alpine.dtsi
@@ -85,7 +85,7 @@
};
 
/* Interrupt Controller */
-   gic: gic@fb001000 {
+   gic: interrupt-controller@fb001000 {
compatible = "arm,cortex-a15-gic";
#interrupt-cells = <3>;
#size-cells = <0>;
-- 
2.17.1



[PATCH] ARM: dts: OX820: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm/boot/dts/ox820.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/ox820.dtsi b/arch/arm/boot/dts/ox820.dtsi
index 085bbd33eadc..3a17ab4e7c2f 100644
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -286,7 +286,7 @@
clocks = <>;
};
 
-   gic: gic@1000 {
+   gic: interrupt-controller@1000 {
compatible = "arm,arm11mp-gic";
interrupt-controller;
#interrupt-cells = <3>;
-- 
2.17.1



[PATCH] ARM: dts: OX820: Correct the GIC DT node name

2018-11-27 Thread Phil Edworthy
Harmless mistake, but it's incorrect. The DT spec provides recommendations
for the node names:
"The name of a node should be somewhat generic, reflecting the function
of the device and not its precise programming model. If appropriate, the
name should be one of the following choices:
...
interrupt-controller"

Signed-off-by: Phil Edworthy 
---
 arch/arm/boot/dts/ox820.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/ox820.dtsi b/arch/arm/boot/dts/ox820.dtsi
index 085bbd33eadc..3a17ab4e7c2f 100644
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -286,7 +286,7 @@
clocks = <>;
};
 
-   gic: gic@1000 {
+   gic: interrupt-controller@1000 {
compatible = "arm,arm11mp-gic";
interrupt-controller;
#interrupt-cells = <3>;
-- 
2.17.1



RE: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-23 Thread Phil Edworthy
Hi Geert,

On 23 November 2018 09:41 Geert Uytterhoeven wrote:
> Subject: Re: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus
> On Mon, Nov 19, 2018 at 5:18 PM Phil Edworthy wrote:
> > This fixes the check for unused mdio bus setting and the following
> > static checker warning:
> >  drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
> >  warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max
> >= 0)'
> >
> > It also fixes the return var when calling of_get_child_count()
> 
> I think this should be a separate patch.
Ok, I'll split them.


> > Reported-by: Dan Carpenter 
> > Signed-off-by: Phil Edworthy 
> 
> Reviewed-by: Geert Uytterhoeven 
> 
> BTW, I have a question about rzn1_pinctrl_mdio_select():
> 
> static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl *ipctl, int mdio,
>  u32 func) {
> if (ipctl->mdio_func[mdio] >= 0 && ipctl->mdio_func[mdio] != func)
> dev_warn(ipctl->dev, "conflicting setting for mdio%d!\n", 
> mdio);
> ipctl->mdio_func[mdio] = func;
> 
> dev_dbg(ipctl->dev, "setting mdio%d to %u\n", mdio, func);
> 
> writel(func, >lev2->l2_mdio[mdio]); }
> 
> The check warns the user if it overrides an already initialized MDIO function
> with a different value.
> However, there is no method to uninitialize (reset to -1) mdio_func[], to
> avoid getting the warning.
> 
> For a use case, I was thinking about a DT overlay that would cause the MDIO
> function to be initialized on loading, and needs to uninitialize the MDIO
> function on removing.
> 
> Perhaps that is very unlikely or even impossible, given the function of the
> pins controlled by the MDIO function?
I hadn't considered that DT overlay possibility...
Since this MDIO muxing selects one of several different IP blocks as the
MDIO master, I guess it could happen. However, this is pretty unlikely!

I can't see any way via the pinctrl_ops or pinconf_ops to 'undo' a pin
setting, how would this work?
If a DT overlay causes remove() then probe() to be called again, the driver
resets mdio_func[] in probe(), so it'll work.

Thanks!
Phil


RE: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-23 Thread Phil Edworthy
Hi Geert,

On 23 November 2018 09:41 Geert Uytterhoeven wrote:
> Subject: Re: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus
> On Mon, Nov 19, 2018 at 5:18 PM Phil Edworthy wrote:
> > This fixes the check for unused mdio bus setting and the following
> > static checker warning:
> >  drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
> >  warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max
> >= 0)'
> >
> > It also fixes the return var when calling of_get_child_count()
> 
> I think this should be a separate patch.
Ok, I'll split them.


> > Reported-by: Dan Carpenter 
> > Signed-off-by: Phil Edworthy 
> 
> Reviewed-by: Geert Uytterhoeven 
> 
> BTW, I have a question about rzn1_pinctrl_mdio_select():
> 
> static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl *ipctl, int mdio,
>  u32 func) {
> if (ipctl->mdio_func[mdio] >= 0 && ipctl->mdio_func[mdio] != func)
> dev_warn(ipctl->dev, "conflicting setting for mdio%d!\n", 
> mdio);
> ipctl->mdio_func[mdio] = func;
> 
> dev_dbg(ipctl->dev, "setting mdio%d to %u\n", mdio, func);
> 
> writel(func, >lev2->l2_mdio[mdio]); }
> 
> The check warns the user if it overrides an already initialized MDIO function
> with a different value.
> However, there is no method to uninitialize (reset to -1) mdio_func[], to
> avoid getting the warning.
> 
> For a use case, I was thinking about a DT overlay that would cause the MDIO
> function to be initialized on loading, and needs to uninitialize the MDIO
> function on removing.
> 
> Perhaps that is very unlikely or even impossible, given the function of the
> pins controlled by the MDIO function?
I hadn't considered that DT overlay possibility...
Since this MDIO muxing selects one of several different IP blocks as the
MDIO master, I guess it could happen. However, this is pretty unlikely!

I can't see any way via the pinctrl_ops or pinconf_ops to 'undo' a pin
setting, how would this work?
If a DT overlay causes remove() then probe() to be called again, the driver
resets mdio_func[] in probe(), so it'll work.

Thanks!
Phil


RE: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-22 Thread Phil Edworthy
Hi Simon,

On 22 November 2018 14:09 Simon Horman wrote:
> On Mon, Nov 19, 2018 at 04:18:38PM +0000, Phil Edworthy wrote:
> > This fixes the check for unused mdio bus setting and the following
> > static checker warning:
> >  drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
> >  warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max
> >= 0)'
> >
> > It also fixes the return var when calling of_get_child_count()
> >
> > Reported-by: Dan Carpenter 
> > Signed-off-by: Phil Edworthy 
> > ---
> > v2:
> >  - Don't rely on rely on the implicit typecast from -1 to uint
> > ---
> >  drivers/pinctrl/pinctrl-rzn1.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pinctrl/pinctrl-rzn1.c
> > b/drivers/pinctrl/pinctrl-rzn1.c index 57886dcff53d..cc0e5aa9128a
> > 100644
> > --- a/drivers/pinctrl/pinctrl-rzn1.c
> > +++ b/drivers/pinctrl/pinctrl-rzn1.c
> > @@ -112,7 +112,7 @@ struct rzn1_pinctrl {
> > struct rzn1_pinctrl_regs __iomem *lev2;
> > u32 lev1_protect_phys;
> > u32 lev2_protect_phys;
> > -   u32 mdio_func[2];
> > +   int mdio_func[2];
> 
> Hi Phil,
> 
> rzn1_pinctrl_mdio_select() assigns values of type u32 to elements of
> mdio_func. Perhaps that warrants cleaning up too?
The source of the 'u32 func' arg is ultimately u32 values read from DT.
The code already ensures that these cannot be bigger than 7, so is fine
I think.

Thanks
Phil


> > struct rzn1_pin_group *groups;
> > unsigned int ngroups;
> > @@ -810,8 +810,8 @@ static int rzn1_pinctrl_probe_dt(struct
> platform_device *pdev,
> > struct device_node *np = pdev->dev.of_node;
> > struct device_node *child;
> > unsigned int maxgroups = 0;
> > -   unsigned int nfuncs = 0;
> > unsigned int i = 0;
> > +   int nfuncs = 0;
> > int ret;
> >
> > nfuncs = of_get_child_count(np);
> > --
> > 2.17.1
> >


RE: [PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-22 Thread Phil Edworthy
Hi Simon,

On 22 November 2018 14:09 Simon Horman wrote:
> On Mon, Nov 19, 2018 at 04:18:38PM +0000, Phil Edworthy wrote:
> > This fixes the check for unused mdio bus setting and the following
> > static checker warning:
> >  drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
> >  warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max
> >= 0)'
> >
> > It also fixes the return var when calling of_get_child_count()
> >
> > Reported-by: Dan Carpenter 
> > Signed-off-by: Phil Edworthy 
> > ---
> > v2:
> >  - Don't rely on rely on the implicit typecast from -1 to uint
> > ---
> >  drivers/pinctrl/pinctrl-rzn1.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pinctrl/pinctrl-rzn1.c
> > b/drivers/pinctrl/pinctrl-rzn1.c index 57886dcff53d..cc0e5aa9128a
> > 100644
> > --- a/drivers/pinctrl/pinctrl-rzn1.c
> > +++ b/drivers/pinctrl/pinctrl-rzn1.c
> > @@ -112,7 +112,7 @@ struct rzn1_pinctrl {
> > struct rzn1_pinctrl_regs __iomem *lev2;
> > u32 lev1_protect_phys;
> > u32 lev2_protect_phys;
> > -   u32 mdio_func[2];
> > +   int mdio_func[2];
> 
> Hi Phil,
> 
> rzn1_pinctrl_mdio_select() assigns values of type u32 to elements of
> mdio_func. Perhaps that warrants cleaning up too?
The source of the 'u32 func' arg is ultimately u32 values read from DT.
The code already ensures that these cannot be bigger than 7, so is fine
I think.

Thanks
Phil


> > struct rzn1_pin_group *groups;
> > unsigned int ngroups;
> > @@ -810,8 +810,8 @@ static int rzn1_pinctrl_probe_dt(struct
> platform_device *pdev,
> > struct device_node *np = pdev->dev.of_node;
> > struct device_node *child;
> > unsigned int maxgroups = 0;
> > -   unsigned int nfuncs = 0;
> > unsigned int i = 0;
> > +   int nfuncs = 0;
> > int ret;
> >
> > nfuncs = of_get_child_count(np);
> > --
> > 2.17.1
> >


[PATCH v8] clk: Add (devm_)clk_get_optional() functions

2018-11-20 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
Reviewed-by: Andy Shevchenko 
---
v8:
 - Remove else clause
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 27 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..c6f4a1a92c5f 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   clk = NULL;
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..3ea3c78f62dd 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,16 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   clk = NULL;
+
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



[PATCH v8] clk: Add (devm_)clk_get_optional() functions

2018-11-20 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
Reviewed-by: Andy Shevchenko 
---
v8:
 - Remove else clause
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 27 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..c6f4a1a92c5f 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   clk = NULL;
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..3ea3c78f62dd 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,16 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   clk = NULL;
+
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



[PATCH] gpio: dwapb: Correct the DT node name in the example

2018-11-20 Thread Phil Edworthy
The sub-nodes should not be called gpio-controller, but simply gpio.

Signed-off-by: Phil Edworthy 
---
 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt 
b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
index 7276b50c3506..839dd32ffe11 100644
--- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
@@ -43,7 +43,7 @@ gpio: gpio@2 {
#address-cells = <1>;
#size-cells = <0>;
 
-   porta: gpio-controller@0 {
+   porta: gpio@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
@@ -55,7 +55,7 @@ gpio: gpio@2 {
interrupts = <0>;
};
 
-   portb: gpio-controller@1 {
+   portb: gpio@1 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
-- 
2.17.1



[PATCH] gpio: dwapb: Correct the DT node name in the example

2018-11-20 Thread Phil Edworthy
The sub-nodes should not be called gpio-controller, but simply gpio.

Signed-off-by: Phil Edworthy 
---
 Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt 
b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
index 7276b50c3506..839dd32ffe11 100644
--- a/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
@@ -43,7 +43,7 @@ gpio: gpio@2 {
#address-cells = <1>;
#size-cells = <0>;
 
-   porta: gpio-controller@0 {
+   porta: gpio@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
@@ -55,7 +55,7 @@ gpio: gpio@2 {
interrupts = <0>;
};
 
-   portb: gpio-controller@1 {
+   portb: gpio@1 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
-- 
2.17.1



RE: [PATCH] clk: Add (devm_)clk_get_optional() functions

2018-11-20 Thread Phil Edworthy
Hi Andy,

On 20 November 2018 10:39 Andy Shevchenko wrote:
> On Mon, Nov 19, 2018 at 02:12:59PM +0000, Phil Edworthy wrote:
> > This adds clk_get_optional() and devm_clk_get_optional() functions to
> > get optional clocks.
> > They behave the same as (devm_)clk_get except where there is no clock
> > producer. In this case, instead of returning -ENOENT, the function
> > returns NULL. This makes error checking simpler and allows
> > clk_prepare_enable, etc to be called on the returned reference without
> > additional checks.
> 
> >  - Instead of messing with the core functions, simply wrap them for the
> >_optional() versions. By putting clk_get_optional() inline in the header
> >file, we can get rid of the arch specific patches as well.
> 
> Fine if it would have no surprises with error handling.
There shouldn't be any surprises. My earlier attempts at implementing this
were hampered by the fact that of_clk_get_by_name() can return -EINVAL
in some circumstances. By directly wrapping the (devm_)clk_get() functions
that problem goes away.

> > +   if (ERR_PTR(-ENOENT))
Huh? That wasn't the code I sent...

> > +   return NULL;
> > +   else
> > +   return clk;
> 
> return clk == ERR_PTR(-ENOENT) ? NULL : clk;
> 
> ?
> 
> > +   if (clk == ERR_PTR(-ENOENT))
> > +   return NULL;
> > +   else
> > +   return clk;
> 
> Ditto.
Sure, will fix both.

Thanks
Phil


RE: [PATCH] clk: Add (devm_)clk_get_optional() functions

2018-11-20 Thread Phil Edworthy
Hi Andy,

On 20 November 2018 10:39 Andy Shevchenko wrote:
> On Mon, Nov 19, 2018 at 02:12:59PM +0000, Phil Edworthy wrote:
> > This adds clk_get_optional() and devm_clk_get_optional() functions to
> > get optional clocks.
> > They behave the same as (devm_)clk_get except where there is no clock
> > producer. In this case, instead of returning -ENOENT, the function
> > returns NULL. This makes error checking simpler and allows
> > clk_prepare_enable, etc to be called on the returned reference without
> > additional checks.
> 
> >  - Instead of messing with the core functions, simply wrap them for the
> >_optional() versions. By putting clk_get_optional() inline in the header
> >file, we can get rid of the arch specific patches as well.
> 
> Fine if it would have no surprises with error handling.
There shouldn't be any surprises. My earlier attempts at implementing this
were hampered by the fact that of_clk_get_by_name() can return -EINVAL
in some circumstances. By directly wrapping the (devm_)clk_get() functions
that problem goes away.

> > +   if (ERR_PTR(-ENOENT))
Huh? That wasn't the code I sent...

> > +   return NULL;
> > +   else
> > +   return clk;
> 
> return clk == ERR_PTR(-ENOENT) ? NULL : clk;
> 
> ?
> 
> > +   if (clk == ERR_PTR(-ENOENT))
> > +   return NULL;
> > +   else
> > +   return clk;
> 
> Ditto.
Sure, will fix both.

Thanks
Phil


[PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-19 Thread Phil Edworthy
This fixes the check for unused mdio bus setting and the following static
checker warning:
 drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
 warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max >= 0)'

It also fixes the return var when calling of_get_child_count()

Reported-by: Dan Carpenter 
Signed-off-by: Phil Edworthy 
---
v2:
 - Don't rely on rely on the implicit typecast from -1 to uint
---
 drivers/pinctrl/pinctrl-rzn1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rzn1.c b/drivers/pinctrl/pinctrl-rzn1.c
index 57886dcff53d..cc0e5aa9128a 100644
--- a/drivers/pinctrl/pinctrl-rzn1.c
+++ b/drivers/pinctrl/pinctrl-rzn1.c
@@ -112,7 +112,7 @@ struct rzn1_pinctrl {
struct rzn1_pinctrl_regs __iomem *lev2;
u32 lev1_protect_phys;
u32 lev2_protect_phys;
-   u32 mdio_func[2];
+   int mdio_func[2];
 
struct rzn1_pin_group *groups;
unsigned int ngroups;
@@ -810,8 +810,8 @@ static int rzn1_pinctrl_probe_dt(struct platform_device 
*pdev,
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
unsigned int maxgroups = 0;
-   unsigned int nfuncs = 0;
unsigned int i = 0;
+   int nfuncs = 0;
int ret;
 
nfuncs = of_get_child_count(np);
-- 
2.17.1



[PATCH] pinctrl: rzn1: Fix check for used MDIO bus

2018-11-19 Thread Phil Edworthy
This fixes the check for unused mdio bus setting and the following static
checker warning:
 drivers/pinctrl/pinctrl-rzn1.c:198 rzn1_pinctrl_mdio_select()
 warn: always true condition '(ipctl->mdio_func[mdio] >= 0) => (0-u32max >= 0)'

It also fixes the return var when calling of_get_child_count()

Reported-by: Dan Carpenter 
Signed-off-by: Phil Edworthy 
---
v2:
 - Don't rely on rely on the implicit typecast from -1 to uint
---
 drivers/pinctrl/pinctrl-rzn1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rzn1.c b/drivers/pinctrl/pinctrl-rzn1.c
index 57886dcff53d..cc0e5aa9128a 100644
--- a/drivers/pinctrl/pinctrl-rzn1.c
+++ b/drivers/pinctrl/pinctrl-rzn1.c
@@ -112,7 +112,7 @@ struct rzn1_pinctrl {
struct rzn1_pinctrl_regs __iomem *lev2;
u32 lev1_protect_phys;
u32 lev2_protect_phys;
-   u32 mdio_func[2];
+   int mdio_func[2];
 
struct rzn1_pin_group *groups;
unsigned int ngroups;
@@ -810,8 +810,8 @@ static int rzn1_pinctrl_probe_dt(struct platform_device 
*pdev,
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
unsigned int maxgroups = 0;
-   unsigned int nfuncs = 0;
unsigned int i = 0;
+   int nfuncs = 0;
int ret;
 
nfuncs = of_get_child_count(np);
-- 
2.17.1



[PATCH] clk: Add (devm_)clk_get_optional() functions

2018-11-19 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 27 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..f0033d937c39 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+   else
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..c7bbb0678057 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,16 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+   else
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



[PATCH] clk: Add (devm_)clk_get_optional() functions

2018-11-19 Thread Phil Edworthy
This adds clk_get_optional() and devm_clk_get_optional() functions to get
optional clocks.
They behave the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v7:
 - Instead of messing with the core functions, simply wrap them for the
   _optional() versions. By putting clk_get_optional() inline in the header
   file, we can get rid of the arch specific patches as well.
v6:
 - Add doxygen style comment for devm_clk_get_optional() args
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 11 +++
 include/linux/clk.h  | 27 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 12c87457eca1..f0033d937c39 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = devm_clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+   else
+   return clk;
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index a7773b5c0b9f..c7bbb0678057 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -383,6 +383,17 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
  */
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
 /**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
@@ -718,6 +729,12 @@ static inline struct clk *devm_clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *devm_clk_get_optional(struct device *dev,
+   const char *id)
+{
+   return NULL;
+}
+
 static inline int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk_bulk_data *clks)
 {
@@ -862,6 +879,16 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
clk_bulk_unprepare(num_clks, clks);
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   struct clk *clk = clk_get(dev, id);
+
+   if (clk == ERR_PTR(-ENOENT))
+   return NULL;
+   else
+   return clk;
+}
+
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
2.17.1



RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 19 November 2018 12:58 Uwe Kleine-König wrote:
> On Mon, Nov 19, 2018 at 12:53:46PM +0000, Phil Edworthy wrote:
> > On 19 November 2018 10:46 Uwe Kleine-König wrote:
> > > On Mon, Nov 19, 2018 at 10:41:42AM +0000, Phil Edworthy wrote:
> > > > btw, do we need to add of_clk_get_by_name_optional()? I only added
> it
> > > > as a counterpart to of_clk_get_by_name(), but it may not be needed.
> > >
> > > I don't need it. Given that it is easy to add when someone has a need, I'd
> say,
> > > skip it for now.
> >
> > I'm wondering if we actually need clk_get_optional(). For me at least, I 
> > just
> > want devm_clk_get_optional(). That would get rid of the arch patches.
> 
> Given that clk_get_optional will be that simple, it can live in
> linux/clk.h for all implementors of the clk API, then you don't have to
> care about different archs. (Unless I'm missing something.)
You are absolutely right, I'm such a clutz sometimes!

Thanks
Phil

> I don't think it's a good idea to drop clk_get_optional even if you'd
> have to provide arch-specific stuff.
> 
> Best regards
> Uwe
> 
> --
> Pengutronix e.K.   | Uwe Kleine-König|
> Industrial Linux Solutions | http://www.pengutronix.de/  |


RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 19 November 2018 12:58 Uwe Kleine-König wrote:
> On Mon, Nov 19, 2018 at 12:53:46PM +0000, Phil Edworthy wrote:
> > On 19 November 2018 10:46 Uwe Kleine-König wrote:
> > > On Mon, Nov 19, 2018 at 10:41:42AM +0000, Phil Edworthy wrote:
> > > > btw, do we need to add of_clk_get_by_name_optional()? I only added
> it
> > > > as a counterpart to of_clk_get_by_name(), but it may not be needed.
> > >
> > > I don't need it. Given that it is easy to add when someone has a need, I'd
> say,
> > > skip it for now.
> >
> > I'm wondering if we actually need clk_get_optional(). For me at least, I 
> > just
> > want devm_clk_get_optional(). That would get rid of the arch patches.
> 
> Given that clk_get_optional will be that simple, it can live in
> linux/clk.h for all implementors of the clk API, then you don't have to
> care about different archs. (Unless I'm missing something.)
You are absolutely right, I'm such a clutz sometimes!

Thanks
Phil

> I don't think it's a good idea to drop clk_get_optional even if you'd
> have to provide arch-specific stuff.
> 
> Best regards
> Uwe
> 
> --
> Pengutronix e.K.   | Uwe Kleine-König|
> Industrial Linux Solutions | http://www.pengutronix.de/  |


RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 19 November 2018 10:46 Uwe Kleine-König wrote:
> On Mon, Nov 19, 2018 at 10:41:42AM +0000, Phil Edworthy wrote:
> > On 16 November 2018 16:11 Uwe Kleine-König wrote:
> > > On Fri, Nov 16, 2018 at 05:01:28PM +0100, Uwe Kleine-König wrote:
> > > > Other than that I think the patch is fine
> > >
> > > Thinking again, I wonder why not just do:
> > >
> > > static inline struct clk *clk_get_optional(struct device *dev, const char
> *id) {
> > >   struct clk *c = clk_get(dev, id);
> > >
> > >   if (c == ERR_PTR(-ENOENT))
> > >   return NULL;
> > >   else
> > >   return c;
> > > }
> >
> > Unfortunately, underneath this __of_clk_get_by_name() returns -EINVAL
> > when looking for a named clock, and the "clock-names" OF property
> > can't be found or the name is not in that prop. This is because the
> > index returned by of_property_match_string() will be an error code and
> > is then currently always passed to __of_clk_get().
> >
> > If, as you said, I split the patches into one that fixes the error
> > code, and then adds clk_get_optional() like above, it will make more sense.
> 
> Sounds like a good plan.
Now that I have removed of_clk_get_by_name_optional(), I see that clk_get()
deals with __of_clk_get_by_name() returning -EINVAL and -ENOENT the same
way. In both cases, clk_get_sys() will return -ENOENT... i.e. I no longer need 
to
modify __of_clk_get_by_name().
All I need is a simple wrapper just as you have outlined above.

> > btw, do we need to add of_clk_get_by_name_optional()? I only added it
> > as a counterpart to of_clk_get_by_name(), but it may not be needed.
> 
> I don't need it. Given that it is easy to add when someone has a need, I'd 
> say,
> skip it for now.
I'm wondering if we actually need clk_get_optional(). For me at least, I just
want devm_clk_get_optional(). That would get rid of the arch patches.

Thanks
Phil


RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 19 November 2018 10:46 Uwe Kleine-König wrote:
> On Mon, Nov 19, 2018 at 10:41:42AM +0000, Phil Edworthy wrote:
> > On 16 November 2018 16:11 Uwe Kleine-König wrote:
> > > On Fri, Nov 16, 2018 at 05:01:28PM +0100, Uwe Kleine-König wrote:
> > > > Other than that I think the patch is fine
> > >
> > > Thinking again, I wonder why not just do:
> > >
> > > static inline struct clk *clk_get_optional(struct device *dev, const char
> *id) {
> > >   struct clk *c = clk_get(dev, id);
> > >
> > >   if (c == ERR_PTR(-ENOENT))
> > >   return NULL;
> > >   else
> > >   return c;
> > > }
> >
> > Unfortunately, underneath this __of_clk_get_by_name() returns -EINVAL
> > when looking for a named clock, and the "clock-names" OF property
> > can't be found or the name is not in that prop. This is because the
> > index returned by of_property_match_string() will be an error code and
> > is then currently always passed to __of_clk_get().
> >
> > If, as you said, I split the patches into one that fixes the error
> > code, and then adds clk_get_optional() like above, it will make more sense.
> 
> Sounds like a good plan.
Now that I have removed of_clk_get_by_name_optional(), I see that clk_get()
deals with __of_clk_get_by_name() returning -EINVAL and -ENOENT the same
way. In both cases, clk_get_sys() will return -ENOENT... i.e. I no longer need 
to
modify __of_clk_get_by_name().
All I need is a simple wrapper just as you have outlined above.

> > btw, do we need to add of_clk_get_by_name_optional()? I only added it
> > as a counterpart to of_clk_get_by_name(), but it may not be needed.
> 
> I don't need it. Given that it is easy to add when someone has a need, I'd 
> say,
> skip it for now.
I'm wondering if we actually need clk_get_optional(). For me at least, I just
want devm_clk_get_optional(). That would get rid of the arch patches.

Thanks
Phil


RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 16 November 2018 16:11 Uwe Kleine-König wrote:
> On Fri, Nov 16, 2018 at 05:01:28PM +0100, Uwe Kleine-König wrote:
> > Other than that I think the patch is fine
> 
> Thinking again, I wonder why not just do:
> 
> static inline struct clk *clk_get_optional(struct device *dev, const char 
> *id) {
>   struct clk *c = clk_get(dev, id);
> 
>   if (c == ERR_PTR(-ENOENT))
>   return NULL;
>   else
>   return c;
> }

Unfortunately, underneath this __of_clk_get_by_name() returns -EINVAL
when looking for a named clock, and the "clock-names" OF property can't
be found or the name is not in that prop. This is because the index
returned by of_property_match_string() will be an error code and is then
currently always passed to __of_clk_get().

If, as you said, I split the patches into one that fixes the error code, and 
then
adds clk_get_optional() like above, it will make more sense.

btw, do we need to add of_clk_get_by_name_optional()? I only added it as a
counterpart to of_clk_get_by_name(), but it may not be needed.

Thanks
Phil


RE: [PATCH v6 1/6] clk: Add of_clk_get_by_name_optional() function

2018-11-19 Thread Phil Edworthy
Hi Uwe,

On 16 November 2018 16:11 Uwe Kleine-König wrote:
> On Fri, Nov 16, 2018 at 05:01:28PM +0100, Uwe Kleine-König wrote:
> > Other than that I think the patch is fine
> 
> Thinking again, I wonder why not just do:
> 
> static inline struct clk *clk_get_optional(struct device *dev, const char 
> *id) {
>   struct clk *c = clk_get(dev, id);
> 
>   if (c == ERR_PTR(-ENOENT))
>   return NULL;
>   else
>   return c;
> }

Unfortunately, underneath this __of_clk_get_by_name() returns -EINVAL
when looking for a named clock, and the "clock-names" OF property can't
be found or the name is not in that prop. This is because the index
returned by of_property_match_string() will be an error code and is then
currently always passed to __of_clk_get().

If, as you said, I split the patches into one that fixes the error code, and 
then
adds clk_get_optional() like above, it will make more sense.

btw, do we need to add of_clk_get_by_name_optional()? I only added it as a
counterpart to of_clk_get_by_name(), but it may not be needed.

Thanks
Phil


RE: [PATCH v3 1/2] dt-bindings/interrupt-controller: rzn1: Add RZ/N1 gpio irq mux binding

2018-11-19 Thread Phil Edworthy
Hi Rob,

On 17 November 2018 14:33 Rob Herring wrote:
> On Tue, Nov 13, 2018 at 01:09:09PM +0000, Phil Edworthy wrote:
> > Add device binding documentation for the Renesas RZ/N1 GPIO interrupt
> > multiplexer.
> >
> > Signed-off-by: Phil Edworthy 
> > ---
> > v3:
> >  - Use 'interrupt-map' DT property correctly.
> > v2:
> >  - Use interrupt-map to allow the GPIO controller info to be specified
> >as part of the irq.
> >  - Don't show status in binding examples.
> >  - Don't show the soc/board split in binding doc.
> > ---
> >  .../interrupt-controller/renesas,rzn1-mux.txt | 73
> > +++
> >  1 file changed, 73 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-mu
> > x.txt
> 
> A few nits, otherwise:
> 
> Reviewed-by: Rob Herring 
Thanks for the review!

> >
> > diff --git
> > a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-
> > mux.txt
> > b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-
> > mux.txt
> > new file mode 100644
> > index ..6515880e25cc
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,r
> > +++ zn1-mux.txt
> > @@ -0,0 +1,73 @@
> > +* Renesas RZ/N1 GPIO Interrupt Multiplexer
> > +
> > +On Renesas RZ/N1 devices, there are several GPIO Controllers each
> > +with a number of interrupt outputs. All of the interrupts from the
> > +GPIO Controllers are passed to the GPIO Interrupt Multiplexer, which
> > +selects a sub-set of the interrupts to pass onto the system interrupt
> controller.
> > +
> > +A single node in the device tree is used to describe the GPIO IRQ Muxer.
> > +
> > +Required properties:
> > +- compatible: SoC-specific compatible string "renesas,-
> gpioirqmux"
> > +  followed by "renesas,rzn1-gpioirqmux" as fallback. The SoC-specific
> > +compatible
> > +  strings must be one of:
> > +   "renesas,r9a06g032-gpioirqmux" for RZ/N1D
> > +   "renesas,r9a06g033-gpioirqmux" for RZ/N1S
> > +- reg: Base address and size of GPIO IRQ Muxer registers.
> > +- interrupts: List of output interrupts.
> > +- #interrupt-cells: Numder of cells in the input interrupt specifier, must 
> > be
> 1.
> > +- #address-cells: Must be 0.
> > +- interrupt-map-mask: must be 127.
> > +- interrupt-map: Standard property detailing the maps between input
> > +irqs and the
> > +  corresponding output irq. This consist of a list of:
> > +   
> > +  The input-irq-spec is from 0 to 95, corresponding to the outputs of
> > +the GPIO
> > +  Controllers.
> > +
> > +Example:
> > +
> > +   The following is an example for the RZ/N1D SoC.
> > +
> > +   gpioirqmux: gpioirqmux@51000480 {
> 
> interrupt-controller@...
Sure

> > +   compatible = "renesas,r9a06g032-gpioirqmux",
> > +   "renesas,rzn1-gpioirqmux";
> > +   reg = <0x51000480 0x20>;
> > +   interrupts =
> > +   ,
> > +   ;
> 
> This is a bit redundant as the same information is in interrupt-map, but I
> guess you need it to get the irq resources.
That's right.

> > +
> > +   #interrupt-cells = <1>;
> > +   #address-cells = <0>;
> > +   interrupt-map-mask = <127>;
> 
> Use hex for masks.
Ok.

> > +   interrupt-map =
> > +   /* gpio2a 24, pin 146: ETH Port 1 IRQ */
> > +   <88  GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
> > +   /* gpio2a 26, pin 148: TouchSCRN_IRQ */
> > +   <90  GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
> > +   };
> > +
> > +   gpio2: gpio@5000d000 {
> > +   compatible = "snps,dw-apb-gpio";
> > +   reg = <0x5000d000 0x80>;
> > +   #address-cells = <1>;
> > +   #size-cells = <0>;
> > +   clock-names = "bus";
> > +   clocks = < R9A06G032_HCLK_GPIO2>;
> > +
> > +   gpio2a: gpio-controller@0 {
> 
> gpio@0
Are you sure about this?
The bindings in Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
show an example where the sub-nodes for gpio banks are gpio-controller@.
This is also in Documentation/devicetree/bindings/gpio/gpio.txt.

Thanks
Phil

> > +   compatible = "snps,dw-apb-gpio-port";
> > +   bank-name = "gpio2a";
> > +   gpio-controller;
> > +   #gpio-cells = <2>;
> > +   snps,nr-gpios = <32>;
> > +   reg = <0>;
> > +
> > +   interrupt-controller;
> > +   interrupt-parent = <>;
> > +   interrupts =  < 64 65 66 67 68 69 70 71
> > +   72 73 74 75 76 77 78 79
> > +   80 81 82 83 84 85 86 87
> > +   88 89 90 91 92 93 94 95 >;
> > +   #interrupt-cells = <2>;
> > +   };
> > +   };
> > --
> > 2.17.1
> >


RE: [PATCH v3 1/2] dt-bindings/interrupt-controller: rzn1: Add RZ/N1 gpio irq mux binding

2018-11-19 Thread Phil Edworthy
Hi Rob,

On 17 November 2018 14:33 Rob Herring wrote:
> On Tue, Nov 13, 2018 at 01:09:09PM +0000, Phil Edworthy wrote:
> > Add device binding documentation for the Renesas RZ/N1 GPIO interrupt
> > multiplexer.
> >
> > Signed-off-by: Phil Edworthy 
> > ---
> > v3:
> >  - Use 'interrupt-map' DT property correctly.
> > v2:
> >  - Use interrupt-map to allow the GPIO controller info to be specified
> >as part of the irq.
> >  - Don't show status in binding examples.
> >  - Don't show the soc/board split in binding doc.
> > ---
> >  .../interrupt-controller/renesas,rzn1-mux.txt | 73
> > +++
> >  1 file changed, 73 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-mu
> > x.txt
> 
> A few nits, otherwise:
> 
> Reviewed-by: Rob Herring 
Thanks for the review!

> >
> > diff --git
> > a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-
> > mux.txt
> > b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzn1-
> > mux.txt
> > new file mode 100644
> > index ..6515880e25cc
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,r
> > +++ zn1-mux.txt
> > @@ -0,0 +1,73 @@
> > +* Renesas RZ/N1 GPIO Interrupt Multiplexer
> > +
> > +On Renesas RZ/N1 devices, there are several GPIO Controllers each
> > +with a number of interrupt outputs. All of the interrupts from the
> > +GPIO Controllers are passed to the GPIO Interrupt Multiplexer, which
> > +selects a sub-set of the interrupts to pass onto the system interrupt
> controller.
> > +
> > +A single node in the device tree is used to describe the GPIO IRQ Muxer.
> > +
> > +Required properties:
> > +- compatible: SoC-specific compatible string "renesas,-
> gpioirqmux"
> > +  followed by "renesas,rzn1-gpioirqmux" as fallback. The SoC-specific
> > +compatible
> > +  strings must be one of:
> > +   "renesas,r9a06g032-gpioirqmux" for RZ/N1D
> > +   "renesas,r9a06g033-gpioirqmux" for RZ/N1S
> > +- reg: Base address and size of GPIO IRQ Muxer registers.
> > +- interrupts: List of output interrupts.
> > +- #interrupt-cells: Numder of cells in the input interrupt specifier, must 
> > be
> 1.
> > +- #address-cells: Must be 0.
> > +- interrupt-map-mask: must be 127.
> > +- interrupt-map: Standard property detailing the maps between input
> > +irqs and the
> > +  corresponding output irq. This consist of a list of:
> > +   
> > +  The input-irq-spec is from 0 to 95, corresponding to the outputs of
> > +the GPIO
> > +  Controllers.
> > +
> > +Example:
> > +
> > +   The following is an example for the RZ/N1D SoC.
> > +
> > +   gpioirqmux: gpioirqmux@51000480 {
> 
> interrupt-controller@...
Sure

> > +   compatible = "renesas,r9a06g032-gpioirqmux",
> > +   "renesas,rzn1-gpioirqmux";
> > +   reg = <0x51000480 0x20>;
> > +   interrupts =
> > +   ,
> > +   ;
> 
> This is a bit redundant as the same information is in interrupt-map, but I
> guess you need it to get the irq resources.
That's right.

> > +
> > +   #interrupt-cells = <1>;
> > +   #address-cells = <0>;
> > +   interrupt-map-mask = <127>;
> 
> Use hex for masks.
Ok.

> > +   interrupt-map =
> > +   /* gpio2a 24, pin 146: ETH Port 1 IRQ */
> > +   <88  GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
> > +   /* gpio2a 26, pin 148: TouchSCRN_IRQ */
> > +   <90  GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
> > +   };
> > +
> > +   gpio2: gpio@5000d000 {
> > +   compatible = "snps,dw-apb-gpio";
> > +   reg = <0x5000d000 0x80>;
> > +   #address-cells = <1>;
> > +   #size-cells = <0>;
> > +   clock-names = "bus";
> > +   clocks = < R9A06G032_HCLK_GPIO2>;
> > +
> > +   gpio2a: gpio-controller@0 {
> 
> gpio@0
Are you sure about this?
The bindings in Documentation/devicetree/bindings/gpio/snps-dwapb-gpio.txt
show an example where the sub-nodes for gpio banks are gpio-controller@.
This is also in Documentation/devicetree/bindings/gpio/gpio.txt.

Thanks
Phil

> > +   compatible = "snps,dw-apb-gpio-port";
> > +   bank-name = "gpio2a";
> > +   gpio-controller;
> > +   #gpio-cells = <2>;
> > +   snps,nr-gpios = <32>;
> > +   reg = <0>;
> > +
> > +   interrupt-controller;
> > +   interrupt-parent = <>;
> > +   interrupts =  < 64 65 66 67 68 69 70 71
> > +   72 73 74 75 76 77 78 79
> > +   80 81 82 83 84 85 86 87
> > +   88 89 90 91 92 93 94 95 >;
> > +   #interrupt-cells = <2>;
> > +   };
> > +   };
> > --
> > 2.17.1
> >


[PATCH v2 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2018-10-30 Thread Phil Edworthy
On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
configured to have 32 interrupt outputs, so we have a total of 96 GPIO
interrupts. All of these are passed to the GPIO IRQ Muxer, which selects
8 of the GPIO interrupts to pass onto the GIC. The interrupt signals
aren't latched, so there is nothing to do in this driver when an interrupt
is received, other than tell the corresponding GPIO block.

Signed-off-by: Phil Edworthy 
---
v2:
 - Use interrupt-map to allow the GPIO controller info to be specified
   as part of the irq.
 - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.
---
 drivers/irqchip/Kconfig|  10 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/rzn1-irq-mux.c | 235 +
 3 files changed, 246 insertions(+)
 create mode 100644 drivers/irqchip/rzn1-irq-mux.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 96451b581452..3a60a8af60dd 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -204,6 +204,16 @@ config RENESAS_IRQC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config RENESAS_RZN1_IRQ_MUX
+   bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
+   depends on ARCH_RZN1
+   select IRQ_DOMAIN
+   select IRQ_DOMAIN_HIERARCHY
+   help
+ Say yes here to add support for the GPIO IRQ multiplexer embedded
+ in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
+ the interrupts coming from the GPIO controllers are used.
+
 config ST_IRQCHIP
bool
select REGMAP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b822199445ff..b090f84dd42e 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SIRF_IRQ)+= irq-sirfsoc.o
 obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)  += irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
+obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX) += rzn1-irq-mux.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)   += irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_NSPIRE)  += irq-zevio.o
 obj-$(CONFIG_ARCH_VT8500)  += irq-vt8500.o
diff --git a/drivers/irqchip/rzn1-irq-mux.c b/drivers/irqchip/rzn1-irq-mux.c
new file mode 100644
index ..767ce67e34d2
--- /dev/null
+++ b/drivers/irqchip/rzn1-irq-mux.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/N1 GPIO Interrupt Multiplexer
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each 
configured
+ * to have 32 interrupt outputs, so we have a total of 96 GPIO interrupts.
+ * All of these are passed to the GPIO IRQ Muxer, which selects 8 of the GPIO
+ * interrupts to pass onto the GIC.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GPIO_IRQ_SPEC_SIZE 3
+#define MAX_NR_GPIO_CONTROLLERS3
+#define MAX_NR_GPIO_IRQ32
+#define MAX_NR_INPUT_IRQS  (MAX_NR_GPIO_CONTROLLERS * MAX_NR_GPIO_IRQ)
+#define MAX_NR_OUTPUT_IRQS 8
+
+struct irqmux_priv;
+struct irqmux_one {
+   unsigned int mapped_irq;
+   unsigned int input_irq_nr;
+   struct irqmux_priv *priv;
+};
+
+struct irqmux_priv {
+   struct device *dev;
+   struct irq_chip irq_chip;
+   struct irq_domain *irq_domain;
+   unsigned int nr_irqs;
+   struct irqmux_one irq[MAX_NR_OUTPUT_IRQS];
+};
+
+static void irqmux_handler(struct irq_desc *desc)
+{
+   struct irq_chip *chip = irq_desc_get_chip(desc);
+   struct irqmux_one *girq = irq_desc_get_handler_data(desc);
+   struct irqmux_priv *priv = girq->priv;
+   unsigned int irq;
+
+   chained_irq_enter(chip, desc);
+
+   irq = irq_find_mapping(priv->irq_domain, girq->input_irq_nr);
+   generic_handle_irq(irq);
+
+   chained_irq_exit(chip, desc);
+}
+
+static int irqmux_domain_map(struct irq_domain *h, unsigned int irq,
+irq_hw_number_t hwirq)
+{
+   struct irqmux_priv *priv = h->host_data;
+
+   irq_set_chip_data(irq, h->host_data);
+   irq_set_chip_and_handler(irq, >irq_chip, handle_simple_irq);
+
+   return 0;
+}
+
+static const struct irq_domain_ops irqmux_domain_ops = {
+   .map= irqmux_domain_map,
+};
+
+static int irqmux_probe(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct device_node *np = dev->of_node;
+   struct resource *res;
+   u32 __iomem *regs;
+   struct irqmux_priv *priv;
+   u32 int_specs[MAX_NR_OUTPUT_IRQS][GPIO_IRQ_SPEC_SIZE];
+   DECLARE_BITMAP(irqs_in_used, MAX_NR_INPUT_IRQS);
+   unsigned int irqs_out_used = 0;
+   unsigned int i;
+   int nr_irqs;
+   int ret;
+
+   priv = devm_kzalloc(dev, sizeof(*pri

[PATCH v2 2/2] irqchip: Add support for Renesas RZ/N1 GPIO interrupt multiplexer

2018-10-30 Thread Phil Edworthy
On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each
configured to have 32 interrupt outputs, so we have a total of 96 GPIO
interrupts. All of these are passed to the GPIO IRQ Muxer, which selects
8 of the GPIO interrupts to pass onto the GIC. The interrupt signals
aren't latched, so there is nothing to do in this driver when an interrupt
is received, other than tell the corresponding GPIO block.

Signed-off-by: Phil Edworthy 
---
v2:
 - Use interrupt-map to allow the GPIO controller info to be specified
   as part of the irq.
 - Renamed struct and funcs from 'girq' to a more comprehenisble 'irqmux'.
---
 drivers/irqchip/Kconfig|  10 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/rzn1-irq-mux.c | 235 +
 3 files changed, 246 insertions(+)
 create mode 100644 drivers/irqchip/rzn1-irq-mux.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 96451b581452..3a60a8af60dd 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -204,6 +204,16 @@ config RENESAS_IRQC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config RENESAS_RZN1_IRQ_MUX
+   bool "Renesas RZ/N1 GPIO IRQ multiplexer support"
+   depends on ARCH_RZN1
+   select IRQ_DOMAIN
+   select IRQ_DOMAIN_HIERARCHY
+   help
+ Say yes here to add support for the GPIO IRQ multiplexer embedded
+ in Renesas RZ/N1 SoC devices. The GPIO IRQ Muxer selects which of
+ the interrupts coming from the GPIO controllers are used.
+
 config ST_IRQCHIP
bool
select REGMAP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b822199445ff..b090f84dd42e 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_SIRF_IRQ)+= irq-sirfsoc.o
 obj-$(CONFIG_JCORE_AIC)+= irq-jcore-aic.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)  += irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
+obj-$(CONFIG_RENESAS_RZN1_IRQ_MUX) += rzn1-irq-mux.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)   += irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_NSPIRE)  += irq-zevio.o
 obj-$(CONFIG_ARCH_VT8500)  += irq-vt8500.o
diff --git a/drivers/irqchip/rzn1-irq-mux.c b/drivers/irqchip/rzn1-irq-mux.c
new file mode 100644
index ..767ce67e34d2
--- /dev/null
+++ b/drivers/irqchip/rzn1-irq-mux.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/N1 GPIO Interrupt Multiplexer
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * On RZ/N1 devices, there are 3 Synopsys DesignWare GPIO blocks each 
configured
+ * to have 32 interrupt outputs, so we have a total of 96 GPIO interrupts.
+ * All of these are passed to the GPIO IRQ Muxer, which selects 8 of the GPIO
+ * interrupts to pass onto the GIC.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define GPIO_IRQ_SPEC_SIZE 3
+#define MAX_NR_GPIO_CONTROLLERS3
+#define MAX_NR_GPIO_IRQ32
+#define MAX_NR_INPUT_IRQS  (MAX_NR_GPIO_CONTROLLERS * MAX_NR_GPIO_IRQ)
+#define MAX_NR_OUTPUT_IRQS 8
+
+struct irqmux_priv;
+struct irqmux_one {
+   unsigned int mapped_irq;
+   unsigned int input_irq_nr;
+   struct irqmux_priv *priv;
+};
+
+struct irqmux_priv {
+   struct device *dev;
+   struct irq_chip irq_chip;
+   struct irq_domain *irq_domain;
+   unsigned int nr_irqs;
+   struct irqmux_one irq[MAX_NR_OUTPUT_IRQS];
+};
+
+static void irqmux_handler(struct irq_desc *desc)
+{
+   struct irq_chip *chip = irq_desc_get_chip(desc);
+   struct irqmux_one *girq = irq_desc_get_handler_data(desc);
+   struct irqmux_priv *priv = girq->priv;
+   unsigned int irq;
+
+   chained_irq_enter(chip, desc);
+
+   irq = irq_find_mapping(priv->irq_domain, girq->input_irq_nr);
+   generic_handle_irq(irq);
+
+   chained_irq_exit(chip, desc);
+}
+
+static int irqmux_domain_map(struct irq_domain *h, unsigned int irq,
+irq_hw_number_t hwirq)
+{
+   struct irqmux_priv *priv = h->host_data;
+
+   irq_set_chip_data(irq, h->host_data);
+   irq_set_chip_and_handler(irq, >irq_chip, handle_simple_irq);
+
+   return 0;
+}
+
+static const struct irq_domain_ops irqmux_domain_ops = {
+   .map= irqmux_domain_map,
+};
+
+static int irqmux_probe(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct device_node *np = dev->of_node;
+   struct resource *res;
+   u32 __iomem *regs;
+   struct irqmux_priv *priv;
+   u32 int_specs[MAX_NR_OUTPUT_IRQS][GPIO_IRQ_SPEC_SIZE];
+   DECLARE_BITMAP(irqs_in_used, MAX_NR_INPUT_IRQS);
+   unsigned int irqs_out_used = 0;
+   unsigned int i;
+   int nr_irqs;
+   int ret;
+
+   priv = devm_kzalloc(dev, sizeof(*pri

[PATCH v6 3/3] ARM: dts: r9a06g032: Add pinctrl node

2018-09-27 Thread Phil Edworthy
This provides a pinctrl driver for the Renesas R9A06G032 SoC

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
---
v6:
 - No changes.

v5:
 - No changes.

v4:
 - No changes.

v3:
 - No changes.

v2:
 - Add "renesas,rzn1-pinctrl" compatible fallback string
 - Register size corrected.
---
 arch/arm/boot/dts/r9a06g032.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index eaf94976ed6d..2322268bc862 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -165,6 +165,14 @@
status = "disabled";
};
 
+   pinctrl: pin-controller@40067000 {
+   compatible = "renesas,r9a06g032-pinctrl", 
"renesas,rzn1-pinctrl";
+   reg = <0x40067000 0x1000>, <0x5100 0x480>;
+   clocks = < R9A06G032_HCLK_PINCONFIG>;
+   clock-names = "bus";
+   status = "okay";
+   };
+
gic: gic@44101000 {
compatible = "arm,cortex-a7-gic", "arm,gic-400";
interrupt-controller;
-- 
2.17.1



[PATCH v6 3/3] ARM: dts: r9a06g032: Add pinctrl node

2018-09-27 Thread Phil Edworthy
This provides a pinctrl driver for the Renesas R9A06G032 SoC

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
---
v6:
 - No changes.

v5:
 - No changes.

v4:
 - No changes.

v3:
 - No changes.

v2:
 - Add "renesas,rzn1-pinctrl" compatible fallback string
 - Register size corrected.
---
 arch/arm/boot/dts/r9a06g032.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index eaf94976ed6d..2322268bc862 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -165,6 +165,14 @@
status = "disabled";
};
 
+   pinctrl: pin-controller@40067000 {
+   compatible = "renesas,r9a06g032-pinctrl", 
"renesas,rzn1-pinctrl";
+   reg = <0x40067000 0x1000>, <0x5100 0x480>;
+   clocks = < R9A06G032_HCLK_PINCONFIG>;
+   clock-names = "bus";
+   status = "okay";
+   };
+
gic: gic@44101000 {
compatible = "arm,cortex-a7-gic", "arm,gic-400";
interrupt-controller;
-- 
2.17.1



[PATCH v6 2/3] pinctrl: renesas: Renesas RZ/N1 pinctrl driver

2018-09-27 Thread Phil Edworthy
This provides a pinctrl driver for the Renesas RZ/N1 device family.

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
Reviewed-by: Jacopo Mondi 
---
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.
 - Simplified how the MDIO function is calculated

v5:
 - Address Jacopo's comments
 - Address Geert's comments

v4:
 - Address Jacopo's comments
 - Implement pin_config_group_get()
 - Fix function to get pin configs, i.e. return -EINVAL when disabled.

v3:
 - Use standard DT props instead of proprietary ones.
 - Replace virtual pins used for MDIO muxing with extra funcs.
 - Use pinctrl_utils funcs to handle the maps.
 - Remove the dbg functions to keep things simple.

v2:
 - Change filename to generic rzn1, instead of device specific.
 - Changed Kconfig symbol and file name to generic rzn1 family.
 - Added "renesas,rzn1-pinctrl" compatible fallback string
 - Changes suggested by Jacopo Mondi. Mainly formatting, plus:
   - Removed global ptr
   - Removed unused code accessing parent of node.
   - Removed check for null OF np that can't happen.
   - Replaced overlapping enums with #defines
 - Renamed some variables and symbols to clarify their use
 - Fix error handling during probe
 - Move probe from postcore_initcall to subsys_initcall to ensure
   drivers that require clocks get them instead of having to defer
   probing.
---
 drivers/pinctrl/Kconfig|  10 +
 drivers/pinctrl/Makefile   |   1 +
 drivers/pinctrl/pinctrl-rzn1.c | 941 +
 3 files changed, 952 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-rzn1.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 978b2ed4d014..4d8c00eac742 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -195,6 +195,16 @@ config PINCTRL_RZA1
help
  This selects pinctrl driver for Renesas RZ/A1 platforms.
 
+config PINCTRL_RZN1
+   bool "Renesas RZ/N1 pinctrl driver"
+   depends on OF
+   depends on ARCH_RZN1 || COMPILE_TEST
+   select GENERIC_PINCTRL_GROUPS
+   select GENERIC_PINMUX_FUNCTIONS
+   select GENERIC_PINCONF
+   help
+ This selects pinctrl driver for Renesas RZ/N1 devices.
+
 config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 8e127bd8610f..18a13c1e2c21 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_PIC32)   += pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)+= pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
 obj-$(CONFIG_PINCTRL_RZA1) += pinctrl-rza1.o
+obj-$(CONFIG_PINCTRL_RZN1) += pinctrl-rzn1.o
 obj-$(CONFIG_PINCTRL_SINGLE)   += pinctrl-single.o
 obj-$(CONFIG_PINCTRL_SIRF) += sirf/
 obj-$(CONFIG_PINCTRL_SX150X)   += pinctrl-sx150x.o
diff --git a/drivers/pinctrl/pinctrl-rzn1.c b/drivers/pinctrl/pinctrl-rzn1.c
new file mode 100644
index ..c1c9ee4c502f
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rzn1.c
@@ -0,0 +1,941 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014-2018 Renesas Electronics Europe Limited
+ *
+ * Phil Edworthy 
+ * Based on a driver originally written by Michel Pollet at Renesas.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+#define RZN1_FUNC_L2_MAX   RZN1_FUNC_MAC_MTIP_SWITCH
+#define RZN1_FUNC_MDIO_MAX RZN1_FUNC_MDIO1_E1_SWITCH
+
+/* Field positions and masks in the pinmux registers */
+#define RZN1_L1_PIN_DRIVE_STRENGTH 10
+#define RZN1_L1_PIN_DRIVE_STRENGTH_4MA 0
+#define RZN1_L1_PIN_DRIVE_STRENGTH_6MA 1
+#define RZN1_L1_PIN_DRIVE_STRENGTH_8MA 2
+#define RZN1_L1_PIN_DRIVE_STRENGTH_12MA3
+#define RZN1_L1_PIN_PULL   8
+#define RZN1_L1_PIN_PULL_NONE  0
+#define RZN1_L1_PIN_PULL_UP1
+#define RZN1_L1_PIN_PULL_DOWN  3
+#define RZN1_L1_FUNCTION   0
+#define RZN1_L1_FUNC_MASK  0xf
+#define RZN1_L1_FUNCTION_L20xf
+
+/*
+ * The hardware manual describes two levels of multiplexing, but it's more
+ * logical to think of the hardware as three levels, with level 3 consisting of
+ * the multiplexing for Ethernet MDIO signals.
+ *
+ * Level 1 functions go from 0 to 9, with level 1 function '15' (0xf) 
specifying
+ * that level 2 functions are used instead. Level 2 has a lot more options,
+ * going from 0 to 61. Level 3 allows selection of MDIO functions which can be
+ * floating, or one of seven internal peripherals. Unfortunately, there are two
+ * level 2 functions that can select MDIO, and two MDIO channels so we have 
four
+

[PATCH v6 2/3] pinctrl: renesas: Renesas RZ/N1 pinctrl driver

2018-09-27 Thread Phil Edworthy
This provides a pinctrl driver for the Renesas RZ/N1 device family.

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
Reviewed-by: Jacopo Mondi 
---
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.
 - Simplified how the MDIO function is calculated

v5:
 - Address Jacopo's comments
 - Address Geert's comments

v4:
 - Address Jacopo's comments
 - Implement pin_config_group_get()
 - Fix function to get pin configs, i.e. return -EINVAL when disabled.

v3:
 - Use standard DT props instead of proprietary ones.
 - Replace virtual pins used for MDIO muxing with extra funcs.
 - Use pinctrl_utils funcs to handle the maps.
 - Remove the dbg functions to keep things simple.

v2:
 - Change filename to generic rzn1, instead of device specific.
 - Changed Kconfig symbol and file name to generic rzn1 family.
 - Added "renesas,rzn1-pinctrl" compatible fallback string
 - Changes suggested by Jacopo Mondi. Mainly formatting, plus:
   - Removed global ptr
   - Removed unused code accessing parent of node.
   - Removed check for null OF np that can't happen.
   - Replaced overlapping enums with #defines
 - Renamed some variables and symbols to clarify their use
 - Fix error handling during probe
 - Move probe from postcore_initcall to subsys_initcall to ensure
   drivers that require clocks get them instead of having to defer
   probing.
---
 drivers/pinctrl/Kconfig|  10 +
 drivers/pinctrl/Makefile   |   1 +
 drivers/pinctrl/pinctrl-rzn1.c | 941 +
 3 files changed, 952 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-rzn1.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 978b2ed4d014..4d8c00eac742 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -195,6 +195,16 @@ config PINCTRL_RZA1
help
  This selects pinctrl driver for Renesas RZ/A1 platforms.
 
+config PINCTRL_RZN1
+   bool "Renesas RZ/N1 pinctrl driver"
+   depends on OF
+   depends on ARCH_RZN1 || COMPILE_TEST
+   select GENERIC_PINCTRL_GROUPS
+   select GENERIC_PINMUX_FUNCTIONS
+   select GENERIC_PINCONF
+   help
+ This selects pinctrl driver for Renesas RZ/N1 devices.
+
 config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 8e127bd8610f..18a13c1e2c21 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_PIC32)   += pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)+= pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
 obj-$(CONFIG_PINCTRL_RZA1) += pinctrl-rza1.o
+obj-$(CONFIG_PINCTRL_RZN1) += pinctrl-rzn1.o
 obj-$(CONFIG_PINCTRL_SINGLE)   += pinctrl-single.o
 obj-$(CONFIG_PINCTRL_SIRF) += sirf/
 obj-$(CONFIG_PINCTRL_SX150X)   += pinctrl-sx150x.o
diff --git a/drivers/pinctrl/pinctrl-rzn1.c b/drivers/pinctrl/pinctrl-rzn1.c
new file mode 100644
index ..c1c9ee4c502f
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rzn1.c
@@ -0,0 +1,941 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014-2018 Renesas Electronics Europe Limited
+ *
+ * Phil Edworthy 
+ * Based on a driver originally written by Michel Pollet at Renesas.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+#define RZN1_FUNC_L2_MAX   RZN1_FUNC_MAC_MTIP_SWITCH
+#define RZN1_FUNC_MDIO_MAX RZN1_FUNC_MDIO1_E1_SWITCH
+
+/* Field positions and masks in the pinmux registers */
+#define RZN1_L1_PIN_DRIVE_STRENGTH 10
+#define RZN1_L1_PIN_DRIVE_STRENGTH_4MA 0
+#define RZN1_L1_PIN_DRIVE_STRENGTH_6MA 1
+#define RZN1_L1_PIN_DRIVE_STRENGTH_8MA 2
+#define RZN1_L1_PIN_DRIVE_STRENGTH_12MA3
+#define RZN1_L1_PIN_PULL   8
+#define RZN1_L1_PIN_PULL_NONE  0
+#define RZN1_L1_PIN_PULL_UP1
+#define RZN1_L1_PIN_PULL_DOWN  3
+#define RZN1_L1_FUNCTION   0
+#define RZN1_L1_FUNC_MASK  0xf
+#define RZN1_L1_FUNCTION_L20xf
+
+/*
+ * The hardware manual describes two levels of multiplexing, but it's more
+ * logical to think of the hardware as three levels, with level 3 consisting of
+ * the multiplexing for Ethernet MDIO signals.
+ *
+ * Level 1 functions go from 0 to 9, with level 1 function '15' (0xf) 
specifying
+ * that level 2 functions are used instead. Level 2 has a lot more options,
+ * going from 0 to 61. Level 3 allows selection of MDIO functions which can be
+ * floating, or one of seven internal peripherals. Unfortunately, there are two
+ * level 2 functions that can select MDIO, and two MDIO channels so we have 
four
+

[PATCH v6 1/3] dt-bindings: pinctrl: renesas,rzn1-pinctrl: documentation

2018-09-27 Thread Phil Edworthy
The Renesas RZ/N1 device family PINCTRL node description.

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
Reviewed-by: Jacopo Mondi 
---
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.

v5:
 - 'Optional generic properties' => 'Optional generic pinconf properties'

v4:
 - Add alternative way to use the pinmux prop.
 - Remove mention of gpios.

v3:
 - Use standard bindings
 - Change the way the functions are defined so it is easy to check
   against the hardware numbering.
 - Add functions for the MDIO source peripheral instead of using
   virtual pins.

v2:
 - Change filename to generic rzn1, instead of device specific.
 - Add "renesas,rzn1-pinctrl" compatible fallback string.
 - Example register size corrected.
 - Typos fixed.
 - Changes suggested by Jacopo Mondi.
 - rzn1-pinctrl.h squashed into this as requested by Rob Herring.
---
 .../bindings/pinctrl/renesas,rzn1-pinctrl.txt | 155 ++
 include/dt-bindings/pinctrl/rzn1-pinctrl.h| 135 +++
 2 files changed, 290 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
 create mode 100644 include/dt-bindings/pinctrl/rzn1-pinctrl.h

diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
new file mode 100644
index ..ca747b3b7455
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
@@ -0,0 +1,155 @@
+Renesas RZ/N1 SoC Pinctrl node description.
+
+Pin controller node
+---
+Required properties:
+- compatible: SoC-specific compatible string "renesas,-pinctrl"
+  followed by "renesas,rzn1-pinctrl" as fallback. The SoC-specific compatible
+  strings must be one of:
+   "renesas,r9a06g032-pinctrl" for RZ/N1D
+   "renesas,r9a06g033-pinctrl" for RZ/N1S
+- reg: Address base and length of the memory area where the pin controller
+  hardware is mapped to.
+- clocks: phandle for the clock, see the description of clock-names below.
+- clock-names: Contains the name of the clock:
+"bus", the bus clock, sometimes described as pclk, for register accesses.
+
+Example:
+   pinctrl: pin-controller@40067000 {
+   compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl";
+   reg = <0x40067000 0x1000>, <0x5100 0x480>;
+   clocks = < R9A06G032_HCLK_PINCONFIG>;
+   clock-names = "bus";
+   };
+
+Sub-nodes
+-
+
+The child nodes of the pin controller node describe a pin multiplexing
+function.
+
+- Pin multiplexing sub-nodes:
+  A pin multiplexing sub-node describes how to configure a set of
+  (or a single) pin in some desired alternate function mode.
+  A single sub-node may define several pin configurations.
+  Please refer to pinctrl-bindings.txt to get to know more on generic
+  pin properties usage.
+
+  The allowed generic formats for a pin multiplexing sub-node are the
+  following ones:
+
+  node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  node-2 {
+  sub-node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  sub-node-2 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  ...
+
+  sub-node-n {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+  };
+
+  node-3 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+
+  sub-node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  ...
+
+  sub-node-n {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+  };
+
+  Use the latter two formats when pins part of the same logical group need to
+  have different generic pin configuration flags applied. Note that the generic
+  pinconfig in node-3 does not apply to the sub-nodes.
+
+  Client sub-nodes shall refer to pin multiplexing sub-nodes using the phandle
+  of the most external one.
+
+  Eg.
+
+  client-1 {
+  ...
+  pinctrl-0 = <>;
+  ...
+  };
+
+  client-2 {
+  ...
+  pinctrl-0 = <>;
+  ...
+  };
+
+  Required properties:
+- pinmux:
+  8-bit integer array consisting of PIN_NR pin number and MUX_FUNC pairs.
+  When a pin has to be configured in alternate function mode, use this
+  property to identify the pin by its global index, and provide its
+  alternate function configuration number.
+  When multiple pins are required to be configured as part of the same
+  alternate function they shall be specified as members of the same
+  argument list of a single "pinmux" property.
+  PIN_NR directly corresponds to the pl_gpio pin number and MUX_FUNC is
+  o

[PATCH v6 1/3] dt-bindings: pinctrl: renesas,rzn1-pinctrl: documentation

2018-09-27 Thread Phil Edworthy
The Renesas RZ/N1 device family PINCTRL node description.

Based on a patch originally written by Michel Pollet at Renesas.

Signed-off-by: Phil Edworthy 
Reviewed-by: Jacopo Mondi 
---
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.

v5:
 - 'Optional generic properties' => 'Optional generic pinconf properties'

v4:
 - Add alternative way to use the pinmux prop.
 - Remove mention of gpios.

v3:
 - Use standard bindings
 - Change the way the functions are defined so it is easy to check
   against the hardware numbering.
 - Add functions for the MDIO source peripheral instead of using
   virtual pins.

v2:
 - Change filename to generic rzn1, instead of device specific.
 - Add "renesas,rzn1-pinctrl" compatible fallback string.
 - Example register size corrected.
 - Typos fixed.
 - Changes suggested by Jacopo Mondi.
 - rzn1-pinctrl.h squashed into this as requested by Rob Herring.
---
 .../bindings/pinctrl/renesas,rzn1-pinctrl.txt | 155 ++
 include/dt-bindings/pinctrl/rzn1-pinctrl.h| 135 +++
 2 files changed, 290 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
 create mode 100644 include/dt-bindings/pinctrl/rzn1-pinctrl.h

diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
new file mode 100644
index ..ca747b3b7455
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
@@ -0,0 +1,155 @@
+Renesas RZ/N1 SoC Pinctrl node description.
+
+Pin controller node
+---
+Required properties:
+- compatible: SoC-specific compatible string "renesas,-pinctrl"
+  followed by "renesas,rzn1-pinctrl" as fallback. The SoC-specific compatible
+  strings must be one of:
+   "renesas,r9a06g032-pinctrl" for RZ/N1D
+   "renesas,r9a06g033-pinctrl" for RZ/N1S
+- reg: Address base and length of the memory area where the pin controller
+  hardware is mapped to.
+- clocks: phandle for the clock, see the description of clock-names below.
+- clock-names: Contains the name of the clock:
+"bus", the bus clock, sometimes described as pclk, for register accesses.
+
+Example:
+   pinctrl: pin-controller@40067000 {
+   compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl";
+   reg = <0x40067000 0x1000>, <0x5100 0x480>;
+   clocks = < R9A06G032_HCLK_PINCONFIG>;
+   clock-names = "bus";
+   };
+
+Sub-nodes
+-
+
+The child nodes of the pin controller node describe a pin multiplexing
+function.
+
+- Pin multiplexing sub-nodes:
+  A pin multiplexing sub-node describes how to configure a set of
+  (or a single) pin in some desired alternate function mode.
+  A single sub-node may define several pin configurations.
+  Please refer to pinctrl-bindings.txt to get to know more on generic
+  pin properties usage.
+
+  The allowed generic formats for a pin multiplexing sub-node are the
+  following ones:
+
+  node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  node-2 {
+  sub-node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  sub-node-2 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  ...
+
+  sub-node-n {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+  };
+
+  node-3 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+
+  sub-node-1 {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+
+  ...
+
+  sub-node-n {
+  pinmux = /bits/ 8 , , ... ;
+  GENERIC_PINCONFIG;
+  };
+  };
+
+  Use the latter two formats when pins part of the same logical group need to
+  have different generic pin configuration flags applied. Note that the generic
+  pinconfig in node-3 does not apply to the sub-nodes.
+
+  Client sub-nodes shall refer to pin multiplexing sub-nodes using the phandle
+  of the most external one.
+
+  Eg.
+
+  client-1 {
+  ...
+  pinctrl-0 = <>;
+  ...
+  };
+
+  client-2 {
+  ...
+  pinctrl-0 = <>;
+  ...
+  };
+
+  Required properties:
+- pinmux:
+  8-bit integer array consisting of PIN_NR pin number and MUX_FUNC pairs.
+  When a pin has to be configured in alternate function mode, use this
+  property to identify the pin by its global index, and provide its
+  alternate function configuration number.
+  When multiple pins are required to be configured as part of the same
+  alternate function they shall be specified as members of the same
+  argument list of a single "pinmux" property.
+  PIN_NR directly corresponds to the pl_gpio pin number and MUX_FUNC is
+  o

[PATCH v6 0/3] Renesas R9A06G032 PINCTRL Driver

2018-09-27 Thread Phil Edworthy
This implements the pinctrl driver for the RZ/N1 family of devices, including
the R9A06G032 (RZ/N1D) device.

This series was originally written by Michel Pollet whilst at Renesas, and I
have taken over this work.

Main changes:
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.
 - Simplified how the MDIO function is calculated

v5:
 - Address Jacopo's further comments
 - Address Geert's comments

v4:
 - Address Jacopo's comments
 - Add alternative way to use the pinmux prop.
 - Remove mention of gpios.
 - Implement pin_config_group_get()
 - Fix function to get pin configs, i.e. return -EINVAL when disabled.

v3:
 - Use standard DT props instead of proprietary ones.
 - Replace virtual pins used for MDIO muxing with extra funcs.
 - Use pinctrl_utils funcs to handle the maps.
 - Remove the dbg functions to keep things simple.
 - Change the way the functions are defined so it is easy to check
   against the hardware numbering.

v2:
 - Change to generic rzn1 family driver, instead of device specific.
 - Review comments fixed.
 - Fix error handling during probe

Phil Edworthy (3):
  dt-bindings: pinctrl: renesas,rzn1-pinctrl: documentation
  pinctrl: renesas: Renesas RZ/N1 pinctrl driver
  ARM: dts: r9a06g032: Add pinctrl node

 .../bindings/pinctrl/renesas,rzn1-pinctrl.txt | 155 +++
 arch/arm/boot/dts/r9a06g032.dtsi  |   8 +
 drivers/pinctrl/Kconfig   |  10 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/pinctrl-rzn1.c| 941 ++
 include/dt-bindings/pinctrl/rzn1-pinctrl.h| 135 +++
 6 files changed, 1250 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
 create mode 100644 drivers/pinctrl/pinctrl-rzn1.c
 create mode 100644 include/dt-bindings/pinctrl/rzn1-pinctrl.h

-- 
2.17.1



[PATCH v6 0/3] Renesas R9A06G032 PINCTRL Driver

2018-09-27 Thread Phil Edworthy
This implements the pinctrl driver for the RZ/N1 family of devices, including
the R9A06G032 (RZ/N1D) device.

This series was originally written by Michel Pollet whilst at Renesas, and I
have taken over this work.

Main changes:
v6:
 - Instead of combining the pin nr and func into a single element, use
   a pair of 8-bit elements.
 - Simplified how the MDIO function is calculated

v5:
 - Address Jacopo's further comments
 - Address Geert's comments

v4:
 - Address Jacopo's comments
 - Add alternative way to use the pinmux prop.
 - Remove mention of gpios.
 - Implement pin_config_group_get()
 - Fix function to get pin configs, i.e. return -EINVAL when disabled.

v3:
 - Use standard DT props instead of proprietary ones.
 - Replace virtual pins used for MDIO muxing with extra funcs.
 - Use pinctrl_utils funcs to handle the maps.
 - Remove the dbg functions to keep things simple.
 - Change the way the functions are defined so it is easy to check
   against the hardware numbering.

v2:
 - Change to generic rzn1 family driver, instead of device specific.
 - Review comments fixed.
 - Fix error handling during probe

Phil Edworthy (3):
  dt-bindings: pinctrl: renesas,rzn1-pinctrl: documentation
  pinctrl: renesas: Renesas RZ/N1 pinctrl driver
  ARM: dts: r9a06g032: Add pinctrl node

 .../bindings/pinctrl/renesas,rzn1-pinctrl.txt | 155 +++
 arch/arm/boot/dts/r9a06g032.dtsi  |   8 +
 drivers/pinctrl/Kconfig   |  10 +
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/pinctrl-rzn1.c| 941 ++
 include/dt-bindings/pinctrl/rzn1-pinctrl.h| 135 +++
 6 files changed, 1250 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/renesas,rzn1-pinctrl.txt
 create mode 100644 drivers/pinctrl/pinctrl-rzn1.c
 create mode 100644 include/dt-bindings/pinctrl/rzn1-pinctrl.h

-- 
2.17.1



RE: [PATCH v4 2/3] pinctrl: renesas: Renesas RZ/N1 pinctrl driver

2018-09-24 Thread Phil Edworthy
Hi Geert,

On 24 September 2018 12:59 Geert Uytterhoeven wrote:
> On Wed, Sep 19, 2018 at 4:24 PM Phil Edworthy wrote:
> > This provides a pinctrl driver for the Renesas RZ/N1 device family.
> >
> > Based on a patch originally written by Michel Pollet at Renesas.
> >
> > Signed-off-by: Phil Edworthy 
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-rzn1.c
> 
> > +/*
> > + * Structure detailing the HW registers on the RZ/N1 devices.
> > + * Both the Level 1 mux registers and Level 2 mux registers have the
> > +same
> > + * structure. The only difference is that Level 2 has additional MDIO
> > +registers
> > + * at the end.
> > + */
> > +struct rzn1_pinctrl_regs {
> > +   union {
> > +   u32 conf[170];
> > +   u8  pad0[0x400];
> 
> This looks a bit confusing, and isn't really padding, as you use a union.
> What about getting rid of the union, and making it real padding?
> 
> u32 conf[170];
> u32 pad0[86];
> 
> > +   };
> > +   u32 status_protect; /* 0x400 */
> > +   /* MDIO mux registers, level2 only */
> > +   u32 l2_mdio[2];
> > +};
> 
> BTW, while using a struct instead of register offset definitions has its 
> merits,
> it also has its drawbacks, like the need for the "0x400" comment.
> You don't have to change it, though.
> 
> > +static const struct rzn1_pin_group *rzn1_pinctrl_find_group_by_name(
> > +   const struct rzn1_pinctrl *ipctl, const char *name) {
> > +   const struct rzn1_pin_group *grp = NULL;
> > +   int i;
> 
> unsigned int i;
> (rzn1_pinctrl.ngroups is unsigned int)
> 
> > +
> > +   for (i = 0; i < ipctl->ngroups; i++) {
> > +   if (!strcmp(ipctl->groups[i].name, name)) {
> > +   grp = >groups[i];
> > +   break;
> > +   }
> > +   }
> > +
> > +   return grp;
> > +}
> 
> > +static int rzn1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
> > +   unsigned long *configs, unsigned int
> > +num_configs) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   enum pin_config_param param;
> > +   int i;
> 
> unsigned int i;
> 
> > +   u32 arg;
> > +   u32 l1, l1_cache;
> > +   u32 drv;
> > +
> > +   if (pin >= ARRAY_SIZE(ipctl->lev1->conf))
> > +   return -EINVAL;
> > +
> > +   l1 = readl(>lev1->conf[pin]);
> > +   l1_cache = l1;
> > +
> > +   for (i = 0; i < num_configs; i++) {
> 
> > +static int rzn1_pinconf_group_get(struct pinctrl_dev *pctldev,
> > + unsigned int selector,
> > + unsigned long *config) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   struct rzn1_pin_group *grp = >groups[selector];
> > +   unsigned long old = 0;
> > +   int i;
> 
> unsigned int i;
> 
> > +
> > +   dev_dbg(ipctl->dev, "group get %s selector:%d\n", grp->name,
> > + selector);
> 
> %u to format unsigned int.
> 
> > +
> > +   for (i = 0; i < grp->npins; i++) {
> 
> > +static int rzn1_pinconf_group_set(struct pinctrl_dev *pctldev,
> > + unsigned int selector,
> > + unsigned long *configs,
> > + unsigned int num_configs) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   struct rzn1_pin_group *grp = >groups[selector];
> > +   int ret, i;
> 
> unsigned int i;
> 
> > +
> > +   dev_dbg(ipctl->dev, "group set %s selector:%d
> > + configs:%p/%d\n",
> 
> %u
> 
> > +   grp->name, selector, configs, num_configs);
> > +
> > +   for (i = 0; i < grp->npins; i++) {
> > +   unsigned int pin = grp->pins[i];
> > +
> > +   ret = rzn1_pinconf_set(pctldev, pin, configs, num_configs);
> > +   if (ret)
> > +   return ret;
> > +   }
> > +
> > +   return 0;
> > +}
> 
> 
> > +static int rzn1_pinctrl_parse_functions(struct device_node *np,
> > +   struct rzn1_pinctrl *ipctl,
> > +u32 index)
> 
> Why u3

RE: [PATCH v4 2/3] pinctrl: renesas: Renesas RZ/N1 pinctrl driver

2018-09-24 Thread Phil Edworthy
Hi Geert,

On 24 September 2018 12:59 Geert Uytterhoeven wrote:
> On Wed, Sep 19, 2018 at 4:24 PM Phil Edworthy wrote:
> > This provides a pinctrl driver for the Renesas RZ/N1 device family.
> >
> > Based on a patch originally written by Michel Pollet at Renesas.
> >
> > Signed-off-by: Phil Edworthy 
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/drivers/pinctrl/pinctrl-rzn1.c
> 
> > +/*
> > + * Structure detailing the HW registers on the RZ/N1 devices.
> > + * Both the Level 1 mux registers and Level 2 mux registers have the
> > +same
> > + * structure. The only difference is that Level 2 has additional MDIO
> > +registers
> > + * at the end.
> > + */
> > +struct rzn1_pinctrl_regs {
> > +   union {
> > +   u32 conf[170];
> > +   u8  pad0[0x400];
> 
> This looks a bit confusing, and isn't really padding, as you use a union.
> What about getting rid of the union, and making it real padding?
> 
> u32 conf[170];
> u32 pad0[86];
> 
> > +   };
> > +   u32 status_protect; /* 0x400 */
> > +   /* MDIO mux registers, level2 only */
> > +   u32 l2_mdio[2];
> > +};
> 
> BTW, while using a struct instead of register offset definitions has its 
> merits,
> it also has its drawbacks, like the need for the "0x400" comment.
> You don't have to change it, though.
> 
> > +static const struct rzn1_pin_group *rzn1_pinctrl_find_group_by_name(
> > +   const struct rzn1_pinctrl *ipctl, const char *name) {
> > +   const struct rzn1_pin_group *grp = NULL;
> > +   int i;
> 
> unsigned int i;
> (rzn1_pinctrl.ngroups is unsigned int)
> 
> > +
> > +   for (i = 0; i < ipctl->ngroups; i++) {
> > +   if (!strcmp(ipctl->groups[i].name, name)) {
> > +   grp = >groups[i];
> > +   break;
> > +   }
> > +   }
> > +
> > +   return grp;
> > +}
> 
> > +static int rzn1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
> > +   unsigned long *configs, unsigned int
> > +num_configs) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   enum pin_config_param param;
> > +   int i;
> 
> unsigned int i;
> 
> > +   u32 arg;
> > +   u32 l1, l1_cache;
> > +   u32 drv;
> > +
> > +   if (pin >= ARRAY_SIZE(ipctl->lev1->conf))
> > +   return -EINVAL;
> > +
> > +   l1 = readl(>lev1->conf[pin]);
> > +   l1_cache = l1;
> > +
> > +   for (i = 0; i < num_configs; i++) {
> 
> > +static int rzn1_pinconf_group_get(struct pinctrl_dev *pctldev,
> > + unsigned int selector,
> > + unsigned long *config) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   struct rzn1_pin_group *grp = >groups[selector];
> > +   unsigned long old = 0;
> > +   int i;
> 
> unsigned int i;
> 
> > +
> > +   dev_dbg(ipctl->dev, "group get %s selector:%d\n", grp->name,
> > + selector);
> 
> %u to format unsigned int.
> 
> > +
> > +   for (i = 0; i < grp->npins; i++) {
> 
> > +static int rzn1_pinconf_group_set(struct pinctrl_dev *pctldev,
> > + unsigned int selector,
> > + unsigned long *configs,
> > + unsigned int num_configs) {
> > +   struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
> > +   struct rzn1_pin_group *grp = >groups[selector];
> > +   int ret, i;
> 
> unsigned int i;
> 
> > +
> > +   dev_dbg(ipctl->dev, "group set %s selector:%d
> > + configs:%p/%d\n",
> 
> %u
> 
> > +   grp->name, selector, configs, num_configs);
> > +
> > +   for (i = 0; i < grp->npins; i++) {
> > +   unsigned int pin = grp->pins[i];
> > +
> > +   ret = rzn1_pinconf_set(pctldev, pin, configs, num_configs);
> > +   if (ret)
> > +   return ret;
> > +   }
> > +
> > +   return 0;
> > +}
> 
> 
> > +static int rzn1_pinctrl_parse_functions(struct device_node *np,
> > +   struct rzn1_pinctrl *ipctl,
> > +u32 index)
> 
> Why u3

RE: [PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-09-03 Thread Phil Edworthy
Hi Stephen,

On 03 September 2018 10:33 Phil Edworthy wrote:
> On 01 September 2018 03:46, Stephen Boyd wrote:
> > Quoting Phil Edworthy (2018-08-31 07:07:22)
> > > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index
> > > 9ab3db8..4adb99e 100644
> > > --- a/drivers/clk/clkdev.c
> > > +++ b/drivers/clk/clkdev.c
> > > @@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
> > >
> > >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > > const char *dev_id,
> > > -   const char *name)
> > > +   const char *name,
> > > +   bool optional)
> > >  {
> > > struct clk *clk = ERR_PTR(-ENOENT);
> > > +   struct device_node *child = np;
> > > +   int index = 0;
> > >
> > > /* Walk up the tree of devices looking for a clock that matches */
> > > while (np) {
> > > -   int index = 0;
> > >
> > > /*
> > >  * For named clocks, first look up the name in the
> > >  * "clock-names" property.  If it cannot be found, then
> > > -* index will be an error code, and of_clk_get() will 
> > > fail.
> > > +* index will be an error code.
> > >  */
> > > if (name)
> > > index = of_property_match_string(np, 
> > > "clock-names",
> name);
> > > -   clk = __of_clk_get(np, index, dev_id, name);
> > > -   if (!IS_ERR(clk)) {
> > > -   break;
> > > -   } else if (name && index >= 0) {
> > > -   if (PTR_ERR(clk) != -EPROBE_DEFER)
> > > -   pr_err("ERROR: could not get clock 
> > > %pOF:%s(%i)\n",
> > > -   np, name ? name : "", index);
> > > +   if (index >= 0)
> > > +   clk = __of_clk_get(np, index, dev_id, name);
> > > +   if (!IS_ERR(clk))
> >
> > Was this change necessary? It looks like we can leave it all alone and keep
> > passing a negative number to __of_clk_get() and have that return an error
> > pointer which we then return immediately as an error. But, if the clock is
> > optional and we've passed a name here, shouldn't we treat an error from
> > of_property_match_string() as success too? This is all looking pretty 
> > fragile
> so
> > maybe it can be better commented and also more explicit instead of relying
> > on the reader to jump through all the function calls to figure out what the
> > return value is in some cases.
> If we call __of_clk_get, with index < 0, we will not be able to differentiate
> between clock provider not present and other errors with the passed data,
> as it will just return -EINVAL.
> 
> of_property_match_string() will return -EINVAL if the "clock-names"
> property
> is missing, or -ENODATA if the specified clock name in the "clock-names"
> property is missing. That is why I have changed the code to conditionally
> call __of_clk_get, so the code will correctly treat optional clocks that are 
> not
> present.
When getting named optional clocks, if the node has a "clock-names" property,
but no clock matching the name we want, I think the function should stop there
and *not* walk up the tree of devices looking for a matching clock. In this 
case,
the code determines that the optional clock is not present.

If there isn’t a "clock-names" property in the current node, the function should
walk up the tree of devices looking for a matching optional clock. If there are 
no
parent nodes left and we haven't found a matching optional clock, we determine
that the clock isn’t there.

Is that how this should work?

Thanks
Phil


> > > return clk;
> > > -   }
> > > +   if (name && index >= 0)
> > > +   break;
> >
> > And this causes us to duplicate logic down below because we have to check
> it
> > again if it's not optional or some other error condition?
> Yes, the error handling is messy, though I have tried to make this simple.
> I'll have a think about some other way to make this cleaner.
> 
> 
> > >
> > > /*
> > >  * No 

RE: [PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-09-03 Thread Phil Edworthy
Hi Stephen,

On 03 September 2018 10:33 Phil Edworthy wrote:
> On 01 September 2018 03:46, Stephen Boyd wrote:
> > Quoting Phil Edworthy (2018-08-31 07:07:22)
> > > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index
> > > 9ab3db8..4adb99e 100644
> > > --- a/drivers/clk/clkdev.c
> > > +++ b/drivers/clk/clkdev.c
> > > @@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
> > >
> > >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > > const char *dev_id,
> > > -   const char *name)
> > > +   const char *name,
> > > +   bool optional)
> > >  {
> > > struct clk *clk = ERR_PTR(-ENOENT);
> > > +   struct device_node *child = np;
> > > +   int index = 0;
> > >
> > > /* Walk up the tree of devices looking for a clock that matches */
> > > while (np) {
> > > -   int index = 0;
> > >
> > > /*
> > >  * For named clocks, first look up the name in the
> > >  * "clock-names" property.  If it cannot be found, then
> > > -* index will be an error code, and of_clk_get() will 
> > > fail.
> > > +* index will be an error code.
> > >  */
> > > if (name)
> > > index = of_property_match_string(np, 
> > > "clock-names",
> name);
> > > -   clk = __of_clk_get(np, index, dev_id, name);
> > > -   if (!IS_ERR(clk)) {
> > > -   break;
> > > -   } else if (name && index >= 0) {
> > > -   if (PTR_ERR(clk) != -EPROBE_DEFER)
> > > -   pr_err("ERROR: could not get clock 
> > > %pOF:%s(%i)\n",
> > > -   np, name ? name : "", index);
> > > +   if (index >= 0)
> > > +   clk = __of_clk_get(np, index, dev_id, name);
> > > +   if (!IS_ERR(clk))
> >
> > Was this change necessary? It looks like we can leave it all alone and keep
> > passing a negative number to __of_clk_get() and have that return an error
> > pointer which we then return immediately as an error. But, if the clock is
> > optional and we've passed a name here, shouldn't we treat an error from
> > of_property_match_string() as success too? This is all looking pretty 
> > fragile
> so
> > maybe it can be better commented and also more explicit instead of relying
> > on the reader to jump through all the function calls to figure out what the
> > return value is in some cases.
> If we call __of_clk_get, with index < 0, we will not be able to differentiate
> between clock provider not present and other errors with the passed data,
> as it will just return -EINVAL.
> 
> of_property_match_string() will return -EINVAL if the "clock-names"
> property
> is missing, or -ENODATA if the specified clock name in the "clock-names"
> property is missing. That is why I have changed the code to conditionally
> call __of_clk_get, so the code will correctly treat optional clocks that are 
> not
> present.
When getting named optional clocks, if the node has a "clock-names" property,
but no clock matching the name we want, I think the function should stop there
and *not* walk up the tree of devices looking for a matching clock. In this 
case,
the code determines that the optional clock is not present.

If there isn’t a "clock-names" property in the current node, the function should
walk up the tree of devices looking for a matching optional clock. If there are 
no
parent nodes left and we haven't found a matching optional clock, we determine
that the clock isn’t there.

Is that how this should work?

Thanks
Phil


> > > return clk;
> > > -   }
> > > +   if (name && index >= 0)
> > > +   break;
> >
> > And this causes us to duplicate logic down below because we have to check
> it
> > again if it's not optional or some other error condition?
> Yes, the error handling is messy, though I have tried to make this simple.
> I'll have a think about some other way to make this cleaner.
> 
> 
> > >
> > > /*
> > >  * No 

RE: [PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-09-03 Thread Phil Edworthy
Hi Stephen,

On 01 September 2018 03:46, Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-08-31 07:07:22)
> > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index
> > 9ab3db8..4adb99e 100644
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> > @@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > struct clk *clk = ERR_PTR(-ENOENT);
> > +   struct device_node *child = np;
> > +   int index = 0;
> >
> > /* Walk up the tree of devices looking for a clock that matches */
> > while (np) {
> > -   int index = 0;
> >
> > /*
> >  * For named clocks, first look up the name in the
> >  * "clock-names" property.  If it cannot be found, then
> > -* index will be an error code, and of_clk_get() will fail.
> > +* index will be an error code.
> >  */
> > if (name)
> > index = of_property_match_string(np, "clock-names", 
> > name);
> > -   clk = __of_clk_get(np, index, dev_id, name);
> > -   if (!IS_ERR(clk)) {
> > -   break;
> > -   } else if (name && index >= 0) {
> > -   if (PTR_ERR(clk) != -EPROBE_DEFER)
> > -   pr_err("ERROR: could not get clock 
> > %pOF:%s(%i)\n",
> > -   np, name ? name : "", index);
> > +   if (index >= 0)
> > +   clk = __of_clk_get(np, index, dev_id, name);
> > +   if (!IS_ERR(clk))
> 
> Was this change necessary? It looks like we can leave it all alone and keep
> passing a negative number to __of_clk_get() and have that return an error
> pointer which we then return immediately as an error. But, if the clock is
> optional and we've passed a name here, shouldn't we treat an error from
> of_property_match_string() as success too? This is all looking pretty fragile 
> so
> maybe it can be better commented and also more explicit instead of relying
> on the reader to jump through all the function calls to figure out what the
> return value is in some cases.
If we call __of_clk_get, with index < 0, we will not be able to differentiate
between clock provider not present and other errors with the passed data,
as it will just return -EINVAL.

of_property_match_string() will return -EINVAL if the "clock-names" property
is missing, or -ENODATA if the specified clock name in the "clock-names"
property is missing. That is why I have changed the code to conditionally
call __of_clk_get, so the code will correctly treat optional clocks that are not
present.


> > return clk;
> > -   }
> > +   if (name && index >= 0)
> > +   break;
> 
> And this causes us to duplicate logic down below because we have to check it
> again if it's not optional or some other error condition?
Yes, the error handling is messy, though I have tried to make this simple.
I'll have a think about some other way to make this cleaner.


> >
> > /*
> >  * No matching clock found on this node.  If the
> > parent node @@ -89,6 +88,16 @@ static struct clk
> *__of_clk_get_by_name(struct device_node *np,
> > break;
> > }
> >
> > +   /* The clock is not valid, but it could be optional or deferred */
> > +   if (optional && PTR_ERR(clk) == -ENOENT) {
> > +   clk = NULL;
> > +   pr_info("no optional clock %pOF:%s\n", child,
> > +   name ? name : "");
> 
> Is this intentionally pr_info?
Yes, it's not an error if an optional clock isn’t there.
Would pr_debug be more appropriate?


> > +   } else if (name && index >= 0 && PTR_ERR(clk) != -EPROBE_DEFER) {
> > +   pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
> > +   child, name, index);
> > +   }
> > +
> > return clk;
> >  }
> >

Thanks
Phil


RE: [PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-09-03 Thread Phil Edworthy
Hi Stephen,

On 01 September 2018 03:46, Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-08-31 07:07:22)
> > diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index
> > 9ab3db8..4adb99e 100644
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> > @@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > struct clk *clk = ERR_PTR(-ENOENT);
> > +   struct device_node *child = np;
> > +   int index = 0;
> >
> > /* Walk up the tree of devices looking for a clock that matches */
> > while (np) {
> > -   int index = 0;
> >
> > /*
> >  * For named clocks, first look up the name in the
> >  * "clock-names" property.  If it cannot be found, then
> > -* index will be an error code, and of_clk_get() will fail.
> > +* index will be an error code.
> >  */
> > if (name)
> > index = of_property_match_string(np, "clock-names", 
> > name);
> > -   clk = __of_clk_get(np, index, dev_id, name);
> > -   if (!IS_ERR(clk)) {
> > -   break;
> > -   } else if (name && index >= 0) {
> > -   if (PTR_ERR(clk) != -EPROBE_DEFER)
> > -   pr_err("ERROR: could not get clock 
> > %pOF:%s(%i)\n",
> > -   np, name ? name : "", index);
> > +   if (index >= 0)
> > +   clk = __of_clk_get(np, index, dev_id, name);
> > +   if (!IS_ERR(clk))
> 
> Was this change necessary? It looks like we can leave it all alone and keep
> passing a negative number to __of_clk_get() and have that return an error
> pointer which we then return immediately as an error. But, if the clock is
> optional and we've passed a name here, shouldn't we treat an error from
> of_property_match_string() as success too? This is all looking pretty fragile 
> so
> maybe it can be better commented and also more explicit instead of relying
> on the reader to jump through all the function calls to figure out what the
> return value is in some cases.
If we call __of_clk_get, with index < 0, we will not be able to differentiate
between clock provider not present and other errors with the passed data,
as it will just return -EINVAL.

of_property_match_string() will return -EINVAL if the "clock-names" property
is missing, or -ENODATA if the specified clock name in the "clock-names"
property is missing. That is why I have changed the code to conditionally
call __of_clk_get, so the code will correctly treat optional clocks that are not
present.


> > return clk;
> > -   }
> > +   if (name && index >= 0)
> > +   break;
> 
> And this causes us to duplicate logic down below because we have to check it
> again if it's not optional or some other error condition?
Yes, the error handling is messy, though I have tried to make this simple.
I'll have a think about some other way to make this cleaner.


> >
> > /*
> >  * No matching clock found on this node.  If the
> > parent node @@ -89,6 +88,16 @@ static struct clk
> *__of_clk_get_by_name(struct device_node *np,
> > break;
> > }
> >
> > +   /* The clock is not valid, but it could be optional or deferred */
> > +   if (optional && PTR_ERR(clk) == -ENOENT) {
> > +   clk = NULL;
> > +   pr_info("no optional clock %pOF:%s\n", child,
> > +   name ? name : "");
> 
> Is this intentionally pr_info?
Yes, it's not an error if an optional clock isn’t there.
Would pr_debug be more appropriate?


> > +   } else if (name && index >= 0 && PTR_ERR(clk) != -EPROBE_DEFER) {
> > +   pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
> > +   child, name, index);
> > +   }
> > +
> > return clk;
> >  }
> >

Thanks
Phil


[PATCH v5 2/2] clk: Add functions to get optional clocks

2018-08-31 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 4adb99e..6355573 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -222,21 +222,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_

[PATCH v5 2/2] clk: Add functions to get optional clocks

2018-08-31 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v5:
 - No changes.
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 4adb99e..6355573 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -222,21 +222,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_

[PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-08-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT.

Signed-off-by: Phil Edworthy 
---
v5:
 - Simplified the code by handling all the error conditions on exit
v4:
 - For optional named clocks of_property_match_string() will return
   -EINVAL if the "clock-names" property is missing, or -ENODATA if
   the specified clock name in the "clock-names" property is missing.
   If we then call __of_clk_get() with these errors as the index, we
   get clk = -EINVAL. This is then filtered later on so users don't
   see it. However, if the clock is not named, __of_clk_get() will
   return -ENOENT is the clock provide is not there.
   So for optional named clocks, use index to determine if the clock
   provider is there or not, and for unnamed clocks, simply check if
   __of_clk_get() returns -ENOENT.

v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 59 +++-
 include/linux/clk.h  |  6 ++
 2 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..4adb99e 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
+   struct device_node *child = np;
+   int index = 0;
 
/* Walk up the tree of devices looking for a clock that matches */
while (np) {
-   int index = 0;
 
/*
 * For named clocks, first look up the name in the
 * "clock-names" property.  If it cannot be found, then
-* index will be an error code, and of_clk_get() will fail.
+* index will be an error code.
 */
if (name)
index = of_property_match_string(np, "clock-names", 
name);
-   clk = __of_clk_get(np, index, dev_id, name);
-   if (!IS_ERR(clk)) {
-   break;
-   } else if (name && index >= 0) {
-   if (PTR_ERR(clk) != -EPROBE_DEFER)
-   pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
-   np, name ? name : "", index);
+   if (index >= 0)
+   clk = __of_clk_get(np, index, dev_id, name);
+   if (!IS_ERR(clk))
return clk;
-   }
+   if (name && index >= 0)
+   break;
 
/*
 * No matching clock found on this node.  If the parent node
@@ -89,6 +88,16 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
break;
}
 
+   /* The clock is not valid, but it could be optional or deferred */
+   if (optional && PTR_ERR(clk) == -ENOENT) {
+   clk = NULL;
+   pr_info("no optional clock %pOF:%s\n", child,
+   name ? name : "");
+   } else if (name && index >= 0 && PTR_ERR(clk) != -EPROBE_DEFER) {
+   pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
+   child, name, index);
+   }
+
return clk;
 }
 
@@ -106,15 +115,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional

[PATCH v5 1/2] clk: Add of_clk_get_by_name_optional() function

2018-08-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT.

Signed-off-by: Phil Edworthy 
---
v5:
 - Simplified the code by handling all the error conditions on exit
v4:
 - For optional named clocks of_property_match_string() will return
   -EINVAL if the "clock-names" property is missing, or -ENODATA if
   the specified clock name in the "clock-names" property is missing.
   If we then call __of_clk_get() with these errors as the index, we
   get clk = -EINVAL. This is then filtered later on so users don't
   see it. However, if the clock is not named, __of_clk_get() will
   return -ENOENT is the clock provide is not there.
   So for optional named clocks, use index to determine if the clock
   provider is there or not, and for unnamed clocks, simply check if
   __of_clk_get() returns -ENOENT.

v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 59 +++-
 include/linux/clk.h  |  6 ++
 2 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..4adb99e 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,30 +54,29 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
+   struct device_node *child = np;
+   int index = 0;
 
/* Walk up the tree of devices looking for a clock that matches */
while (np) {
-   int index = 0;
 
/*
 * For named clocks, first look up the name in the
 * "clock-names" property.  If it cannot be found, then
-* index will be an error code, and of_clk_get() will fail.
+* index will be an error code.
 */
if (name)
index = of_property_match_string(np, "clock-names", 
name);
-   clk = __of_clk_get(np, index, dev_id, name);
-   if (!IS_ERR(clk)) {
-   break;
-   } else if (name && index >= 0) {
-   if (PTR_ERR(clk) != -EPROBE_DEFER)
-   pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
-   np, name ? name : "", index);
+   if (index >= 0)
+   clk = __of_clk_get(np, index, dev_id, name);
+   if (!IS_ERR(clk))
return clk;
-   }
+   if (name && index >= 0)
+   break;
 
/*
 * No matching clock found on this node.  If the parent node
@@ -89,6 +88,16 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
break;
}
 
+   /* The clock is not valid, but it could be optional or deferred */
+   if (optional && PTR_ERR(clk) == -ENOENT) {
+   clk = NULL;
+   pr_info("no optional clock %pOF:%s\n", child,
+   name ? name : "");
+   } else if (name && index >= 0 && PTR_ERR(clk) != -EPROBE_DEFER) {
+   pr_err("ERROR: could not get clock %pOF:%s(%i)\n",
+   child, name, index);
+   }
+
return clk;
 }
 
@@ -106,15 +115,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional

[PATCH v5 0/2] clk: Add functions to get optional clocks

2018-08-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 ++--
 drivers/clk/clkdev.c | 74 ++--
 include/linux/clk.h  | 35 +++
 3 files changed, 110 insertions(+), 17 deletions(-)

-- 
2.7.4



[PATCH v5 0/2] clk: Add functions to get optional clocks

2018-08-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 ++--
 drivers/clk/clkdev.c | 74 ++--
 include/linux/clk.h  | 35 +++
 3 files changed, 110 insertions(+), 17 deletions(-)

-- 
2.7.4



RE: [PATCH v4 1/2] clk: Add of_clk_get_by_name_optional() function

2018-08-30 Thread Phil Edworthy
Hi Andy,

On 29 August 2018 18:11 Andy Shevchenko wrote:
> On Tue, Jul 31, 2018 at 01:10:59PM +0100, Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required
> > to access peripheral's registers that is always enabled on some
> > devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that
> > it will return NULL instead of -ENOENT.
> 
> > +   if (optional && (index == -EINVAL || index == -ENODATA ||
> > +   PTR_ERR(clk) == -ENOENT)) {
> 
> A nit: I would rather rearrange this to be
> 
> if (optional &&
> (... || ... || ...)) {
> 
> (disregard 80 characters limit for second line)

Thanks for the review. I'm not particularly happy with the patch as is, it's
pretty messy. I was in rush trying to get things done before holidays - always
a mistake.
Would you mind if I sent a v5 that I feel is somewhat clearer?

Thanks
Phil


RE: [PATCH v4 1/2] clk: Add of_clk_get_by_name_optional() function

2018-08-30 Thread Phil Edworthy
Hi Andy,

On 29 August 2018 18:11 Andy Shevchenko wrote:
> On Tue, Jul 31, 2018 at 01:10:59PM +0100, Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required
> > to access peripheral's registers that is always enabled on some
> > devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that
> > it will return NULL instead of -ENOENT.
> 
> > +   if (optional && (index == -EINVAL || index == -ENODATA ||
> > +   PTR_ERR(clk) == -ENOENT)) {
> 
> A nit: I would rather rearrange this to be
> 
> if (optional &&
> (... || ... || ...)) {
> 
> (disregard 80 characters limit for second line)

Thanks for the review. I'm not particularly happy with the patch as is, it's
pretty messy. I was in rush trying to get things done before holidays - always
a mistake.
Would you mind if I sent a v5 that I feel is somewhat clearer?

Thanks
Phil


[PATCH v4 2/2] clk: Add functions to get optional clocks

2018-07-31 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index f8f6ba9..0ad6c31 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -226,21 +226,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct devi

[PATCH v4 2/2] clk: Add functions to get optional clocks

2018-07-31 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v4:
 - No changes.
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index f8f6ba9..0ad6c31 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -226,21 +226,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct devi

[PATCH v4 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT.

Signed-off-by: Phil Edworthy 
---
v4:
 - For optional named clocks of_property_match_string() will return
   -EINVAL if the "clock-names" property is missing, or -ENODATA if
   the specified clock name in the "clock-names" property is missing.
   If we then call __of_clk_get() with these errors as the index, we
   get clk = -EINVAL. This is then filtered later on so users don't
   see it. However, if the clock is not named, __of_clk_get() will
   return -ENOENT is the clock provide is not there.
   So for optional named clocks, use index to determine if the clock
   provider is there or not, and for unnamed clocks, simply check if
   __of_clk_get() returns -ENOENT.

v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 43 +++
 include/linux/clk.h  |  6 ++
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..f8f6ba9 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -70,6 +71,12 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (name)
index = of_property_match_string(np, "clock-names", 
name);
clk = __of_clk_get(np, index, dev_id, name);
+   if (optional && (index == -EINVAL || index == -ENODATA ||
+   PTR_ERR(clk) == -ENOENT)) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
@@ -89,6 +96,12 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
break;
}
 
+   if (optional && PTR_ERR(clk) == -ENOENT) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
+
return clk;
 }
 
@@ -106,15 +119,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return NULL;
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +232,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
   

[PATCH v4 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT.

Signed-off-by: Phil Edworthy 
---
v4:
 - For optional named clocks of_property_match_string() will return
   -EINVAL if the "clock-names" property is missing, or -ENODATA if
   the specified clock name in the "clock-names" property is missing.
   If we then call __of_clk_get() with these errors as the index, we
   get clk = -EINVAL. This is then filtered later on so users don't
   see it. However, if the clock is not named, __of_clk_get() will
   return -ENOENT is the clock provide is not there.
   So for optional named clocks, use index to determine if the clock
   provider is there or not, and for unnamed clocks, simply check if
   __of_clk_get() returns -ENOENT.

v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 43 +++
 include/linux/clk.h  |  6 ++
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..f8f6ba9 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -70,6 +71,12 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (name)
index = of_property_match_string(np, "clock-names", 
name);
clk = __of_clk_get(np, index, dev_id, name);
+   if (optional && (index == -EINVAL || index == -ENODATA ||
+   PTR_ERR(clk) == -ENOENT)) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
@@ -89,6 +96,12 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
break;
}
 
+   if (optional && PTR_ERR(clk) == -ENOENT) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
+
return clk;
 }
 
@@ -106,15 +119,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return NULL;
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +232,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
   

[PATCH v4 0/2] clk: Add functions to get optional clocks

2018-07-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 +--
 drivers/clk/clkdev.c | 58 +++-
 include/linux/clk.h  | 35 +
 3 files changed, 104 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v4 0/2] clk: Add functions to get optional clocks

2018-07-31 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 +--
 drivers/clk/clkdev.c | 58 +++-
 include/linux/clk.h  | 35 +
 3 files changed, 104 insertions(+), 7 deletions(-)

-- 
2.7.4



RE: [PATCH v3 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Hi Andy,

On 30 July 2018 17:04, Andy Shevchenko wrote:
> On Mon, 2018-07-30 at 14:31 +0100, Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required to
> > access peripheral's registers that is always enabled on some devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that it
> > will return NULL instead of -EINVAL.
> 
> I'm puzzled a bit.
> 
> __of_clk_get() may return few error codes, and to me ENOENT sounds
> correct when clock is not found. Other error codes should be passed to the
> caller even for optional clocks.
> 
> If above is not true, we need to understand what circumstances for each
> possible returned code are, and fix / act accordingly.
>
> P.S. Possible way like regulator framework does is to return -ENODEV.
> 
> So, basically what I'm asking here is to be sure that single error code (for 
> now
> supposed -EINVAL) in this case is _the_ error code for absent / can't be
> found clock.
of_property_match_string() can return different return values for when:
 the "clock-names" property is missing (-EINVAL),
 the specified clock name in the "clock-names" property is missing  (-ENODATA),
 or internal errors, (e.g. -EILSEQ).
However, if you then call __of_clk_get() with the failed index, you just get
the -EINVAL error.

Looking at it further, __of_clk_get() should return -ENOENT if passed a valid
index (e.g. 0 when name=NULL) and the clock is not there. However, I think
it will take a while to check all possible return values as it's not immediately
clear what they are (to me).

I think the best thing is to test the return value of of_property_match_string()
for -ENODATA, and deal with it then. Then deal with the case of name=NULL
separately.

Thanks
Phil

 >  - Fix check for clock not present. __of_clk_get() returns -EINVAL
> >if it's not there. Cover case of when there is no clock name.
> 
> --
> Andy Shevchenko 
> Intel Finland Oy


RE: [PATCH v3 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Hi Andy,

On 30 July 2018 17:04, Andy Shevchenko wrote:
> On Mon, 2018-07-30 at 14:31 +0100, Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required to
> > access peripheral's registers that is always enabled on some devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that it
> > will return NULL instead of -EINVAL.
> 
> I'm puzzled a bit.
> 
> __of_clk_get() may return few error codes, and to me ENOENT sounds
> correct when clock is not found. Other error codes should be passed to the
> caller even for optional clocks.
> 
> If above is not true, we need to understand what circumstances for each
> possible returned code are, and fix / act accordingly.
>
> P.S. Possible way like regulator framework does is to return -ENODEV.
> 
> So, basically what I'm asking here is to be sure that single error code (for 
> now
> supposed -EINVAL) in this case is _the_ error code for absent / can't be
> found clock.
of_property_match_string() can return different return values for when:
 the "clock-names" property is missing (-EINVAL),
 the specified clock name in the "clock-names" property is missing  (-ENODATA),
 or internal errors, (e.g. -EILSEQ).
However, if you then call __of_clk_get() with the failed index, you just get
the -EINVAL error.

Looking at it further, __of_clk_get() should return -ENOENT if passed a valid
index (e.g. 0 when name=NULL) and the clock is not there. However, I think
it will take a while to check all possible return values as it's not immediately
clear what they are (to me).

I think the best thing is to test the return value of of_property_match_string()
for -ENODATA, and deal with it then. Then deal with the case of name=NULL
separately.

Thanks
Phil

 >  - Fix check for clock not present. __of_clk_get() returns -EINVAL
> >if it's not there. Cover case of when there is no clock name.
> 
> --
> Andy Shevchenko 
> Intel Finland Oy


[PATCH v3 2/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index a710333..2245ba6 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -219,21 +219,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const

[PATCH v3 2/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
v3:
 - No changes.
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index a710333..2245ba6 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -219,21 +219,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index de0e5e0..58ec7bc 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const

[PATCH v3 0/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 +++--
 drivers/clk/clkdev.c | 51 +++-
 include/linux/clk.h  | 35 +
 3 files changed, 97 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v3 0/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a bus clock required to 
access peripheral's registers that is always enabled on some devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 +++--
 drivers/clk/clkdev.c | 51 +++-
 include/linux/clk.h  | 35 +
 3 files changed, 97 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v3 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -EINVAL.

Signed-off-by: Phil Edworthy 
---
v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 36 
 include/linux/clk.h  |  6 ++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..a710333 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -70,6 +71,11 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (name)
index = of_property_match_string(np, "clock-names", 
name);
clk = __of_clk_get(np, index, dev_id, name);
+   if (optional && PTR_ERR(clk) == -EINVAL) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
@@ -106,15 +112,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return NULL;
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +225,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4f750c4..de0e5e0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -777,6 +777,7 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
+struct clk *of_clk_get_by_name_optional(struct device_node *np, const char 
*name);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
@@ -788,6 +789,11 @@ static inline struct clk *of_clk_get_by_name(struct 
device_node *np,
 {
return ERR_PTR(-ENOENT);
 }
+static inline struct clk *of_clk_get_by_name_optional(struct device_node *np,
+ const char *name)
+{
+   return NULL;
+}
 static inline struct clk *of_clk_get_from_provider(struct of_phandle_args 
*clkspec)
 {
return ERR_PTR(-ENOENT);
-- 
2.7.4



[PATCH v3 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -EINVAL.

Signed-off-by: Phil Edworthy 
---
v3:
 - Fix check for clock not present. __of_clk_get() returns -EINVAL
   if it's not there. Cover case of when there is no clock name.
 - of_clk_get_by_name_optional() should return NULL if !np.
 - Add dummy version of of_clk_get_by_name_optional() for the
   !OF || !COMMON_CLK case.
---
 drivers/clk/clkdev.c | 36 
 include/linux/clk.h  |  6 ++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..a710333 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -70,6 +71,11 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (name)
index = of_property_match_string(np, "clock-names", 
name);
clk = __of_clk_get(np, index, dev_id, name);
+   if (optional && PTR_ERR(clk) == -EINVAL) {
+   clk = NULL;
+   pr_info("optional clock is not present %pOF:%s\n", np,
+   name ? name : "");
+   }
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
@@ -106,15 +112,37 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties, and uses them to
+ * look up the struct clk from the registered list of clock providers.
+ * It behaves the same as of_clk_get_by_name(), except when np is NULL or no
+ * clock provider is found, when it then returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return NULL;
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +225,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4f750c4..de0e5e0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -777,6 +777,7 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
+struct clk *of_clk_get_by_name_optional(struct device_node *np, const char 
*name);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
@@ -788,6 +789,11 @@ static inline struct clk *of_clk_get_by_name(struct 
device_node *np,
 {
return ERR_PTR(-ENOENT);
 }
+static inline struct clk *of_clk_get_by_name_optional(struct device_node *np,
+ const char *name)
+{
+   return NULL;
+}
 static inline struct clk *of_clk_get_from_provider(struct of_phandle_args 
*clkspec)
 {
return ERR_PTR(-ENOENT);
-- 
2.7.4



RE: [PATCH v2 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Hi Geert,

On 30 July 2018 09:56, Geert Uytterhoeven wrote:
> On Mon, Jul 30, 2018 at 10:36 AM Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required to
> > access peripheral's registers that is always enabled on some devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that it
> > will return NULL instead of -ENOENT. This makes error checking for
> > users easier and allows clk_prepare_enable, etc to be called on the
> > returned reference without additional checks.
> >
> > Signed-off-by: Phil Edworthy 
> 
> Thanks for your patch!
> 
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> > @@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > struct clk *clk = ERR_PTR(-ENOENT);
> >
> > @@ -73,6 +74,8 @@ static struct clk *__of_clk_get_by_name(struct
> device_node *np,
> > if (!IS_ERR(clk)) {
> > break;
> > } else if (name && index >= 0) {
> > +   if (optional && PTR_ERR(clk) == -ENOENT)
> > +   clk = NULL;
> 
> This only handles the "name && index >= 0" case.
> If that condition is never true, the loop will end, eventually, and the last 
> value
> of clk will be returned. Hence there should be a similar check at the end of
> the function.
Oops, I was only considering named optional clocks, I'll fix this.

> > if (PTR_ERR(clk) != -EPROBE_DEFER)
> > pr_err("ERROR: could not get clock 
> > %pOF:%s(%i)\n",
> > np, name ? name : "", index);
> 
> Hence if not found, this will always print an error, even if the clock is
> optional?
Right.

> > @@ -106,15 +109,38 @@ struct clk *of_clk_get_by_name(struct
> device_node *np, const char *name)
> > if (!np)
> > return ERR_PTR(-ENOENT);
> >
> > -   return __of_clk_get_by_name(np, np->full_name, name);
> > +   return __of_clk_get_by_name(np, np->full_name, name, false);
> >  }
> >  EXPORT_SYMBOL(of_clk_get_by_name);
> >
> > +/**
> > + * of_clk_get_by_name_optional() - Parse and lookup an optional clock
> > +referenced
> > + * by a device node
> > + * @np: pointer to clock consumer node
> > + * @name: name of consumer's clock input, or NULL for the first clock
> > +reference
> > + *
> > + * This function parses the clocks and clock-names properties,
> > + * and uses them to look up the struct clk from the registered list
> > +of clock
> > + * providers.
> > + * It behaves the same as of_clk_get_by_name(), except when no clock is
> found.
> > + * In this case, instead of returning -ENOENT, it returns NULL.
> > + */
> > +struct clk *of_clk_get_by_name_optional(struct device_node *np,
> > +   const char *name) {
> > +   if (!np)
> > +   return ERR_PTR(-ENOENT);
> 
> Shouldn't this return NULL?
I wasn’t sure on this, I thought the node should be valid, but I guess the node
is also optional. I'll fix.

> Or let __of_clk_get_by_name() handle that (cfr. above)?

> Hmm, of_clk_get_by_name() has a similar check, while the current
> __of_clk_get_by_name() already handle np == NULL, too.
Yes I see, I'll clean that up.

 
> > +
> > +   return __of_clk_get_by_name(np, np->full_name, name, true); }
> > +EXPORT_SYMBOL(of_clk_get_by_name_optional);
> > +
> >  #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > return ERR_PTR(-ENOENT);
> >  }
> > @@ -197,7 +223,7 @@ struct clk *clk_get(struct device *dev, const char
> *con_id)
> > struct clk *clk;
> >
> > if (dev && dev->of_node) {
> > -   clk = __of_clk_get_by

RE: [PATCH v2 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Hi Geert,

On 30 July 2018 09:56, Geert Uytterhoeven wrote:
> On Mon, Jul 30, 2018 at 10:36 AM Phil Edworthy wrote:
> > Quite a few drivers get an optional clock, e.g. a clock required to
> > access peripheral's registers that is always enabled on some devices.
> >
> > This function behaves the same as of_clk_get_by_name() except that it
> > will return NULL instead of -ENOENT. This makes error checking for
> > users easier and allows clk_prepare_enable, etc to be called on the
> > returned reference without additional checks.
> >
> > Signed-off-by: Phil Edworthy 
> 
> Thanks for your patch!
> 
> > --- a/drivers/clk/clkdev.c
> > +++ b/drivers/clk/clkdev.c
> > @@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > struct clk *clk = ERR_PTR(-ENOENT);
> >
> > @@ -73,6 +74,8 @@ static struct clk *__of_clk_get_by_name(struct
> device_node *np,
> > if (!IS_ERR(clk)) {
> > break;
> > } else if (name && index >= 0) {
> > +   if (optional && PTR_ERR(clk) == -ENOENT)
> > +   clk = NULL;
> 
> This only handles the "name && index >= 0" case.
> If that condition is never true, the loop will end, eventually, and the last 
> value
> of clk will be returned. Hence there should be a similar check at the end of
> the function.
Oops, I was only considering named optional clocks, I'll fix this.

> > if (PTR_ERR(clk) != -EPROBE_DEFER)
> > pr_err("ERROR: could not get clock 
> > %pOF:%s(%i)\n",
> > np, name ? name : "", index);
> 
> Hence if not found, this will always print an error, even if the clock is
> optional?
Right.

> > @@ -106,15 +109,38 @@ struct clk *of_clk_get_by_name(struct
> device_node *np, const char *name)
> > if (!np)
> > return ERR_PTR(-ENOENT);
> >
> > -   return __of_clk_get_by_name(np, np->full_name, name);
> > +   return __of_clk_get_by_name(np, np->full_name, name, false);
> >  }
> >  EXPORT_SYMBOL(of_clk_get_by_name);
> >
> > +/**
> > + * of_clk_get_by_name_optional() - Parse and lookup an optional clock
> > +referenced
> > + * by a device node
> > + * @np: pointer to clock consumer node
> > + * @name: name of consumer's clock input, or NULL for the first clock
> > +reference
> > + *
> > + * This function parses the clocks and clock-names properties,
> > + * and uses them to look up the struct clk from the registered list
> > +of clock
> > + * providers.
> > + * It behaves the same as of_clk_get_by_name(), except when no clock is
> found.
> > + * In this case, instead of returning -ENOENT, it returns NULL.
> > + */
> > +struct clk *of_clk_get_by_name_optional(struct device_node *np,
> > +   const char *name) {
> > +   if (!np)
> > +   return ERR_PTR(-ENOENT);
> 
> Shouldn't this return NULL?
I wasn’t sure on this, I thought the node should be valid, but I guess the node
is also optional. I'll fix.

> Or let __of_clk_get_by_name() handle that (cfr. above)?

> Hmm, of_clk_get_by_name() has a similar check, while the current
> __of_clk_get_by_name() already handle np == NULL, too.
Yes I see, I'll clean that up.

 
> > +
> > +   return __of_clk_get_by_name(np, np->full_name, name, true); }
> > +EXPORT_SYMBOL(of_clk_get_by_name_optional);
> > +
> >  #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
> >
> >  static struct clk *__of_clk_get_by_name(struct device_node *np,
> > const char *dev_id,
> > -   const char *name)
> > +   const char *name,
> > +   bool optional)
> >  {
> > return ERR_PTR(-ENOENT);
> >  }
> > @@ -197,7 +223,7 @@ struct clk *clk_get(struct device *dev, const char
> *con_id)
> > struct clk *clk;
> >
> > if (dev && dev->of_node) {
> > -   clk = __of_clk_get_by

[PATCH v2 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT. This makes error checking
for users easier and allows clk_prepare_enable, etc to be called
on the returned reference without additional checks.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clkdev.c | 34 ++
 include/linux/clk.h  |  1 +
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..c1b7262 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -73,6 +74,8 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
+   if (optional && PTR_ERR(clk) == -ENOENT)
+   clk = NULL;
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
np, name ? name : "", index);
@@ -106,15 +109,38 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ * It behaves the same as of_clk_get_by_name(), except when no clock is found.
+ * In this case, instead of returning -ENOENT, it returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return ERR_PTR(-ENOENT);
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +223,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4f750c4..8cb5455 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -777,6 +777,7 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
+struct clk *of_clk_get_by_name_optional(struct device_node *np, const char 
*name);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
-- 
2.7.4



[PATCH v2 1/2] clk: Add of_clk_get_by_name_optional() function

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

This function behaves the same as of_clk_get_by_name() except that
it will return NULL instead of -ENOENT. This makes error checking
for users easier and allows clk_prepare_enable, etc to be called
on the returned reference without additional checks.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clkdev.c | 34 ++
 include/linux/clk.h  |  1 +
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 9ab3db8..c1b7262 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -73,6 +74,8 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (!IS_ERR(clk)) {
break;
} else if (name && index >= 0) {
+   if (optional && PTR_ERR(clk) == -ENOENT)
+   clk = NULL;
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
np, name ? name : "", index);
@@ -106,15 +109,38 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ * It behaves the same as of_clk_get_by_name(), except when no clock is found.
+ * In this case, instead of returning -ENOENT, it returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return ERR_PTR(-ENOENT);
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -197,7 +223,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 4f750c4..8cb5455 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -777,6 +777,7 @@ static inline void clk_bulk_disable_unprepare(int num_clks,
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
+struct clk *of_clk_get_by_name_optional(struct device_node *np, const char 
*name);
 struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
 #else
 static inline struct clk *of_clk_get(struct device_node *np, int index)
-- 
2.7.4



[PATCH v2 0/2] Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 49 +++-
 include/linux/clk.h  | 30 +
 3 files changed, 90 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v2 2/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index c1b7262..484a444 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -217,21 +217,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 8cb5455..22040ea 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   re

[PATCH v2 0/2] Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Quite a few drivers get an optional clock, e.g. a clock required
to access peripheral's registers that is always enabled on some
devices.

Phil Edworthy (2):
  clk: Add of_clk_get_by_name_optional() function
  clk: Add functions to get optional clocks

 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 49 +++-
 include/linux/clk.h  | 30 +
 3 files changed, 90 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v2 2/2] clk: Add functions to get optional clocks

2018-07-30 Thread Phil Edworthy
Behaves the same as (devm_)clk_get except where there is no clock
producer. In this case, instead of returning -ENOENT, the function
returns NULL. This makes error checking simpler and allows
clk_prepare_enable, etc to be called on the returned reference
without additional checks.

Signed-off-by: Phil Edworthy 
---
 drivers/clk/clk-devres.c | 18 --
 drivers/clk/clkdev.c | 17 +++--
 include/linux/clk.h  | 29 +
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index d854e26..a2bb01a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -14,7 +14,7 @@ static void devm_clk_release(struct device *dev, void *res)
clk_put(*(struct clk **)res);
 }
 
-struct clk *devm_clk_get(struct device *dev, const char *id)
+static struct clk *__devm_clk_get(struct device *dev, const char *id, bool 
optional)
 {
struct clk **ptr, *clk;
 
@@ -22,7 +22,10 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
if (!ptr)
return ERR_PTR(-ENOMEM);
 
-   clk = clk_get(dev, id);
+   if (!optional)
+   clk = clk_get(dev, id);
+   else
+   clk = clk_get_optional(dev, id);
if (!IS_ERR(clk)) {
*ptr = clk;
devres_add(dev, ptr);
@@ -32,8 +35,19 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 
return clk;
 }
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, false);
+}
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk *devm_clk_get_optional(struct device *dev, const char *id)
+{
+   return __devm_clk_get(dev, id, true);
+}
+EXPORT_SYMBOL(devm_clk_get_optional);
+
 struct clk_bulk_devres {
struct clk_bulk_data *clks;
int num_clks;
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index c1b7262..484a444 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -217,21 +217,34 @@ struct clk *clk_get_sys(const char *dev_id, const char 
*con_id)
 }
 EXPORT_SYMBOL(clk_get_sys);
 
-struct clk *clk_get(struct device *dev, const char *con_id)
+static struct clk *internal_clk_get(struct device *dev, const char *con_id,
+   bool optional)
 {
const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
 
if (dev && dev->of_node) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id, false);
+   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id,
+  optional);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
 
return clk_get_sys(dev_id, con_id);
 }
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, false);
+}
 EXPORT_SYMBOL(clk_get);
 
+struct clk *clk_get_optional(struct device *dev, const char *con_id)
+{
+   return internal_clk_get(dev, con_id, true);
+}
+EXPORT_SYMBOL(clk_get_optional);
+
 void clk_put(struct clk *clk)
 {
__clk_put(clk);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 8cb5455..22040ea 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -291,6 +291,16 @@ static inline void clk_bulk_unprepare(int num_clks, struct 
clk_bulk_data *clks)
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_get_optional - lookup and obtain a reference to optional clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as clk_get except where there is no clock producer. In this
+ * case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *clk_get_optional(struct device *dev, const char *id);
+
+/**
  * clk_bulk_get - lookup and obtain a number of references to clock producer.
  * @dev: device for clock "consumer"
  * @num_clks: the number of clk_bulk_data
@@ -349,6 +359,14 @@ int __must_check devm_clk_bulk_get(struct device *dev, int 
num_clks,
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *clock producer.
+ * Behaves the same as devm_clk_get except where there is no clock producer. In
+ * this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct device *dev, const char *id);
+
+/**
  * devm_get_clk_from_child - lookup and obtain a managed reference to a
  *  clock producer from child node.
  * @dev: device for clock "consumer"
@@ -636,6 +654,11 @@ static inline struct clk *clk_get(struct device *dev, 
const char *id)
return NULL;
 }
 
+static inline struct clk *clk_get_optional(struct device *dev, const char *id)
+{
+   re

RE: [PATCH] clk: Add functions to get optional clocks

2018-07-27 Thread Phil Edworthy
Hi Stephen,

On 25 July 2018 23:37, Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-07-18 06:56:26)
> > On 18 July 2018 14:19, Geert Uytterhoeven wrote:
> > > On Wed, Jul 18, 2018 at 3:02 PM Russell King - ARM Linux  wrote:
> > > > On Wed, Jul 18, 2018 at 01:57:38PM +0100, Phil Edworthy wrote:
> > > > > Behaves the same as (devm_)clk_get except where there is no
> > > > > clock producer. In this case, instead of returning -ENOENT, the
> > > > > function returns NULL. This makes error checking simpler and
> > > > > allows clk_prepare_enable, etc to be called on the returned
> > > > > reference without additional checks.
> > > >
> > > > How does this work with non-DT systems, where looking a clock up
> > > > which isn't yet registered with clkdev returns -ENOENT ?
> > > >
> > > > (clkdev doesn't know when all clocks are registered with it.)
> > >
> > > Good question.
> > >
> > > I guess all drivers trying to handle optional clocks this way are
> > > already broken on non-DT systems where clocks may be registered late...
> >
> > So how do non-DT systems that look a clock up which isn't yet
> > registered with clkdev, determine that an optional clock is there or
> > not?
> >
> 
> Short answer is they don't. I'd still prefer we have this API though.
> 
> Can you rework this patch to be a little more invasive into the
> clk_get() path, perhaps by reworking __of_clk_get_by_name() a little to
> take an 'optional' argument, so that it only returns NULL when the clk is
> looked up from DT? The fallback path in clkdev where we have a DT based
> system looking up a clk through clkdev lookups doesn't seem to be a real
> scenario that we should worry about here. I think sometimes people use
> clkdev lookups when they're migrating to DT systems and things aren't wired
> up properly in DT, but that isn't the norm.
Do you mean something like this:

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 7f2cd1e..42a7d4e 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -57,7 +57,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -79,6 +80,8 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
np, name ? name : "", index);
+   if (optional && PTR_ERR(clk) == -ENOENT)
+   clk = NULL;
return clk;
}
 
@@ -109,15 +112,38 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ * It behaves the same as of_clk_get_by_name(), except when no clock is found.
+ * In this case, instead of returning -ENOENT, it returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return ERR_PTR(-ENOENT);
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -200,7 +226,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(

RE: [PATCH] clk: Add functions to get optional clocks

2018-07-27 Thread Phil Edworthy
Hi Stephen,

On 25 July 2018 23:37, Stephen Boyd wrote:
> Quoting Phil Edworthy (2018-07-18 06:56:26)
> > On 18 July 2018 14:19, Geert Uytterhoeven wrote:
> > > On Wed, Jul 18, 2018 at 3:02 PM Russell King - ARM Linux  wrote:
> > > > On Wed, Jul 18, 2018 at 01:57:38PM +0100, Phil Edworthy wrote:
> > > > > Behaves the same as (devm_)clk_get except where there is no
> > > > > clock producer. In this case, instead of returning -ENOENT, the
> > > > > function returns NULL. This makes error checking simpler and
> > > > > allows clk_prepare_enable, etc to be called on the returned
> > > > > reference without additional checks.
> > > >
> > > > How does this work with non-DT systems, where looking a clock up
> > > > which isn't yet registered with clkdev returns -ENOENT ?
> > > >
> > > > (clkdev doesn't know when all clocks are registered with it.)
> > >
> > > Good question.
> > >
> > > I guess all drivers trying to handle optional clocks this way are
> > > already broken on non-DT systems where clocks may be registered late...
> >
> > So how do non-DT systems that look a clock up which isn't yet
> > registered with clkdev, determine that an optional clock is there or
> > not?
> >
> 
> Short answer is they don't. I'd still prefer we have this API though.
> 
> Can you rework this patch to be a little more invasive into the
> clk_get() path, perhaps by reworking __of_clk_get_by_name() a little to
> take an 'optional' argument, so that it only returns NULL when the clk is
> looked up from DT? The fallback path in clkdev where we have a DT based
> system looking up a clk through clkdev lookups doesn't seem to be a real
> scenario that we should worry about here. I think sometimes people use
> clkdev lookups when they're migrating to DT systems and things aren't wired
> up properly in DT, but that isn't the norm.
Do you mean something like this:

diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 7f2cd1e..42a7d4e 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -57,7 +57,8 @@ EXPORT_SYMBOL(of_clk_get);
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
struct clk *clk = ERR_PTR(-ENOENT);
 
@@ -79,6 +80,8 @@ static struct clk *__of_clk_get_by_name(struct device_node 
*np,
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock 
%pOF:%s(%i)\n",
np, name ? name : "", index);
+   if (optional && PTR_ERR(clk) == -ENOENT)
+   clk = NULL;
return clk;
}
 
@@ -109,15 +112,38 @@ struct clk *of_clk_get_by_name(struct device_node *np, 
const char *name)
if (!np)
return ERR_PTR(-ENOENT);
 
-   return __of_clk_get_by_name(np, np->full_name, name);
+   return __of_clk_get_by_name(np, np->full_name, name, false);
 }
 EXPORT_SYMBOL(of_clk_get_by_name);
 
+/**
+ * of_clk_get_by_name_optional() - Parse and lookup an optional clock 
referenced
+ * by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ * It behaves the same as of_clk_get_by_name(), except when no clock is found.
+ * In this case, instead of returning -ENOENT, it returns NULL.
+ */
+struct clk *of_clk_get_by_name_optional(struct device_node *np,
+   const char *name)
+{
+   if (!np)
+   return ERR_PTR(-ENOENT);
+
+   return __of_clk_get_by_name(np, np->full_name, name, true);
+}
+EXPORT_SYMBOL(of_clk_get_by_name_optional);
+
 #else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 
 static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
-   const char *name)
+   const char *name,
+   bool optional)
 {
return ERR_PTR(-ENOENT);
 }
@@ -200,7 +226,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
 
if (dev) {
-   clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+   clk = __of_clk_get_by_name(

RE: [PATCH] clk: renesas: r9a06g032: Avoid needless probe deferring

2018-07-20 Thread Phil Edworthy
Hi Geert,

On 20 July 2018 13:12, Geert Uytterhoeven wrote:
> On Fri, Jul 20, 2018 at 2:06 PM Phil Edworthy  wrote:
> > On 20 July 2018 12:21, Geert Uytterhoeven wrote:
> > > On Wed, Jul 18, 2018 at 4:34 PM Phil Edworthy wrote:
> > > > To avoid all SoC peripheral drivers deferring their probes, both
> > > > clock and pinctrl drivers should already be probed. Since the
> > > > pinctrl driver requires a clock to access the registers, the clock
> > > > driver should be probed before the pinctrl driver.
> > > >
> > > > Therefore, move the clock driver from subsys_initcall to core_initcall.
> > > >
> > > > Signed-off-by: Phil Edworthy 
> > >
> > > Thanks for your patch!
> > Thanks for your review!
> >
> > > The (not yet upstreamed) pinctrl driver uses postcore_initcall(), right?
> > No, the pinctrl driver uses subsys_initcall, but postcore_initcall or
> > arch_initcall may be better to make it clear about the dependencies.
> 
> if the pinctrl driver uses subsys_initcall(), ...
> 
> > > > --- a/drivers/clk/renesas/r9a06g032-clocks.c
> > > > +++ b/drivers/clk/renesas/r9a06g032-clocks.c
> > > > @@ -877,17 +877,18 @@ static const struct of_device_id
> > > r9a06g032_match[] = {
> > > > { }
> > > >  };
> > > >
> > > > -static struct platform_driver r9a06g032_clock_driver = {
> > > > +static struct platform_driver r9a06g032_clock_driver __refdata =
> > > > +{
> > > > .driver = {
> > > > .name   = "renesas,r9a06g032-sysctrl",
> > > > .of_match_table = r9a06g032_match,
> > > > },
> > > > +   .probe = r9a06g032_clocks_probe,
> > > >  };
> > > >
> > > >  static int __init r9a06g032_clocks_init(void)  {
> > > > -   return platform_driver_probe(_clock_driver,
> > > > -   r9a06g032_clocks_probe);
> > > > +   platform_driver_register(_clock_driver);
> > > > +   return 0;
> > That should be:
> > +   return platform_driver_register(_clock_driver);
> >
> > > >  }
> > >
> > > Why are all of the above changes needed?
> > > Shouldn't the platform_driver_probe() keep on working?
> > > If it does not, it means the clock driver has some other dependency,
> > > and cannot be bound immediately.  This is potentially a dangerous
> > > situation, as
> > > r9a06g032_clocks_probe() is __init, but can still be called at any time 
> > > later.
> > > Hence using platform_driver_probe() is the safe thing to do,
> > > possibly with a different reshuffling of the clock and pinctrl initcall
> priorities.
> > No, you cannot call platform_driver_probe() from core_initcall.
> > All drivers that are in core_initcall call platform_driver_register().
> 
> Hence they cannot have their probe function __init.
> 
> >
> > Thanks
> > Phil
> >
> > > > -subsys_initcall(r9a06g032_clocks_init);
> > > > +core_initcall(r9a06g032_clocks_init);
> 
> ... using postcore_initcall() or arch_initcall() here, should work with
> platform_driver_probe()?
Nope, you have to use platform_driver_register() for DT based drivers.
subsys_initcall is the earliest you can use platform_driver_probe().

Thanks
Phil

> Gr{oetje,eeting}s,
> 
> Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
> -- Linus Torvalds


RE: [PATCH] clk: renesas: r9a06g032: Avoid needless probe deferring

2018-07-20 Thread Phil Edworthy
Hi Geert,

On 20 July 2018 13:12, Geert Uytterhoeven wrote:
> On Fri, Jul 20, 2018 at 2:06 PM Phil Edworthy  wrote:
> > On 20 July 2018 12:21, Geert Uytterhoeven wrote:
> > > On Wed, Jul 18, 2018 at 4:34 PM Phil Edworthy wrote:
> > > > To avoid all SoC peripheral drivers deferring their probes, both
> > > > clock and pinctrl drivers should already be probed. Since the
> > > > pinctrl driver requires a clock to access the registers, the clock
> > > > driver should be probed before the pinctrl driver.
> > > >
> > > > Therefore, move the clock driver from subsys_initcall to core_initcall.
> > > >
> > > > Signed-off-by: Phil Edworthy 
> > >
> > > Thanks for your patch!
> > Thanks for your review!
> >
> > > The (not yet upstreamed) pinctrl driver uses postcore_initcall(), right?
> > No, the pinctrl driver uses subsys_initcall, but postcore_initcall or
> > arch_initcall may be better to make it clear about the dependencies.
> 
> if the pinctrl driver uses subsys_initcall(), ...
> 
> > > > --- a/drivers/clk/renesas/r9a06g032-clocks.c
> > > > +++ b/drivers/clk/renesas/r9a06g032-clocks.c
> > > > @@ -877,17 +877,18 @@ static const struct of_device_id
> > > r9a06g032_match[] = {
> > > > { }
> > > >  };
> > > >
> > > > -static struct platform_driver r9a06g032_clock_driver = {
> > > > +static struct platform_driver r9a06g032_clock_driver __refdata =
> > > > +{
> > > > .driver = {
> > > > .name   = "renesas,r9a06g032-sysctrl",
> > > > .of_match_table = r9a06g032_match,
> > > > },
> > > > +   .probe = r9a06g032_clocks_probe,
> > > >  };
> > > >
> > > >  static int __init r9a06g032_clocks_init(void)  {
> > > > -   return platform_driver_probe(_clock_driver,
> > > > -   r9a06g032_clocks_probe);
> > > > +   platform_driver_register(_clock_driver);
> > > > +   return 0;
> > That should be:
> > +   return platform_driver_register(_clock_driver);
> >
> > > >  }
> > >
> > > Why are all of the above changes needed?
> > > Shouldn't the platform_driver_probe() keep on working?
> > > If it does not, it means the clock driver has some other dependency,
> > > and cannot be bound immediately.  This is potentially a dangerous
> > > situation, as
> > > r9a06g032_clocks_probe() is __init, but can still be called at any time 
> > > later.
> > > Hence using platform_driver_probe() is the safe thing to do,
> > > possibly with a different reshuffling of the clock and pinctrl initcall
> priorities.
> > No, you cannot call platform_driver_probe() from core_initcall.
> > All drivers that are in core_initcall call platform_driver_register().
> 
> Hence they cannot have their probe function __init.
> 
> >
> > Thanks
> > Phil
> >
> > > > -subsys_initcall(r9a06g032_clocks_init);
> > > > +core_initcall(r9a06g032_clocks_init);
> 
> ... using postcore_initcall() or arch_initcall() here, should work with
> platform_driver_probe()?
Nope, you have to use platform_driver_register() for DT based drivers.
subsys_initcall is the earliest you can use platform_driver_probe().

Thanks
Phil

> Gr{oetje,eeting}s,
> 
> Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
> -- Linus Torvalds


  1   2   3   4   >