* [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support
From: Laurent Pinchart @ 2016-10-07 9:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f39e907c-424f-7572-f88e-5dd0b6009631@codeaurora.org>
Hi Archit,
On Friday 07 Oct 2016 10:27:31 Archit Taneja wrote:
> On 10/07/2016 02:34 AM, Laurent Pinchart wrote:
> > On Thursday 06 Oct 2016 15:53:28 Sean Paul wrote:
> >> On Thu, Oct 6, 2016 at 1:27 PM, Laurent Pinchart wrote:
> >>> On Thursday 06 Oct 2016 17:09:57 Archit Taneja wrote:
> >>>> On 10/06/2016 12:51 PM, Maxime Ripard wrote:
> >>>>> On Mon, Oct 03, 2016 at 04:40:57PM +0530, Archit Taneja wrote:
> >>>>>> On 09/30/2016 08:07 PM, Maxime Ripard wrote:
> >>>>>>> Some boards have an entirely passive RGB to VGA bridge, based on
> >>>>>>> either DACs or resistor ladders.
> >>>>>>>
> >>>>>>> Those might or might not have an i2c bus routed to the VGA connector
> >>>>>>> in order to access the screen EDIDs.
> >>>>>>>
> >>>>>>> Add a bridge that doesn't do anything but expose the modes available
> >>>>>>> on the screen, either based on the EDIDs if available, or based on
> >>>>>>> the XGA standards.
> >>>>>>>
> >>>>>>> Acked-by: Rob Herring <robh@kernel.org>
> >>>>>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> >>>>>>> ---
> >>>>>>> .../bindings/display/bridge/rgb-to-vga-bridge.txt | 48 +++++
> >>>>>>> drivers/gpu/drm/bridge/Kconfig | 7 +
> >>>>>>> drivers/gpu/drm/bridge/Makefile | 1 +
> >>>>>>> drivers/gpu/drm/bridge/rgb-to-vga.c | 229 +++++++++++
> >>>>>>> 4 files changed, 285 insertions(+)
> >>>>>>> create mode 100644
> >>>>>>> Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.t
> >>>>>>> xt
> >>>>>>> create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c
> >>>>>>>
> >>>>>>> diff --git
> >>>>>>> a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge
> >>>>>>> .
> >>>>>>> txt
> >>>>>>> b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge
> >>>>>>> .
> >>>>>>> txt
> >>>>>>> new file mode 100644
> >>>>>>> index 000000000000..a8375bc1f9cb
> >>>>>>> --- /dev/null
> >>>>>>> +++
> >>>>>>> b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge
> >>>>>>> .
> >>>>>>> tx
> >>>>>>> t @@ -0,0 +1,48 @@
> >>>>>>> +Dumb RGB to VGA bridge
> >>>>>>> +----------------------
> >>>>>>> +
> >>>>>>> +This binding is aimed for dumb RGB to VGA bridges that do not
> >>>>>>> require
> >>>>>>> +any configuration.
> >>>>>>> +
> >>>>>>> +Required properties:
> >>>>>>> +
> >>>>>>> +- compatible: Must be "rgb-to-vga-bridge"
> >>>>>>
> >>>>>> I'd talked to Laurent on IRC if he's okay with this. And I guess you
> >>>>>> to had discussed it during XDC too. He's suggested that it'd be
> >>>>>> better
> >>>>>> to have the compatible string as "simple-vga-dac".
> >>>>>
> >>>>> I just wished this bikeshedding had taken place publicly and be
> >>>>> actually part of that discussion, but yeah, ok.
> >>>>
> >>>> Sorry about that. I'd pinged him for an Ack, the discussion went
> >>>> more than that :)
> >>>>
> >>>>>> Some of the reasons behind having this:
> >>>>>>
> >>>>>> - We don't need to specify "rgb" in the compatible string since most
> >>>>>> simple VGA DACs can only work with an RGB input.
> >>>>>
> >>>>> Ok.
> >>>>>
> >>>>>> - Also, with "dac" specified in the string, we don't need to
> >>>>>> specifically mention "bridge" in the string. Also, bridge is a drm
> >>>>>> specific term.
> >>>>>>
> >>>>>> - "simple" is considered because it's an unconfigurable bridge, and
> >>>>>> it might be misleading for other VGA DACs to not use "vga-dac".
> >>>>>
> >>>>> All those "simple" bindings are just the biggest lie we ever
> >>>>> told. It's simple when you introduce it, and then grows into something
> >>>>> much more complicated than a non-simple implementation.
> >>>>
> >>>> "simple" here is supposed to mean that it's an unconfigurable RGB to
> >>>> VGA DAC. This isn't supposed to follow the simple-panel model, where
> >>>> you add the "simple-panel" string in the compatible node, along with
> >>>> you chip specific compatible string.
> >>>
> >>> I agree with Maxime, I don't like the word "simple". My preference would
> >>> be "vga-dac" for a lack of a better qualifier than "simple" to describe
> >>> the fact that the device requires no configuration. My only concern with
> >>> "vga-dac" is that we would restrict usage of that compatible string for
> >>> a subset of VGA DACs, with more complex devices not being compatible
> >>> with "vga-dac" even though they are VGA DACs. That's a problem I can
> >>> live with though.
> >>
> >> While we're bikeshedding (feel free to ignore my input on this), I
> >> think Maxime's initial "dumb" qualifier was better than "simple".
> >
> > I think I agree.
> >
> >> I think "passive" also gets the point across better than "simple", which
> >> we've already established as something else in drm.
> >
> > To my electrical engineer's ear, passive refers to a component or
> > combination of components that is not capable of power gain. The
> > resistors ladder VGA DAC that Maxime is trying to support is a passive
> > system, but the ADV7123 VGA DAC that equally requires no configuration is
> > an active component.
>
> If no one has any more objections within the next day, I'll pull in
> Maxime's v5 RGB to VGA bridge driver,
I'm testing the patch with rcar-du-drm and will provide results today.
> and change the compatible to "dumb-vga-dac".
Feel free to ignore the bikeshedding, but "transparent" could be a candidate
to replace "dumb" (either as "vga-dac-transparent" or "transparent-vga-dac").
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH v3] arm64: mm: move zero page from .bss to right before swapper_pg_dir
From: Ard Biesheuvel @ 2016-10-07 9:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473696925-26156-1-git-send-email-ard.biesheuvel@linaro.org>
On 12 September 2016 at 17:15, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> Move the statically allocated zero page from the .bss section to right
> before swapper_pg_dir. This allows us to refer to its physical address
> by simply reading TTBR1_EL1 (which always points to swapper_pg_dir and
> always has its ASID field cleared), and subtracting PAGE_SIZE.
>
> To protect the zero page from inadvertent modification, carve out a
> segment that covers it as well as idmap_pg_dir[], and mark it read-only
> in both the primary and the linear mappings of the kernel.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
[...]
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 05615a3fdc6f..d2be62ff1ad3 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
[...]
> @@ -424,13 +430,19 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
> */
> static void __init map_kernel(pgd_t *pgd)
> {
> - static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;
> + static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init,
> + vmlinux_data, vmlinux_robss, vmlinux_swapper;
>
> map_kernel_segment(pgd, _text, _etext, PAGE_KERNEL_EXEC, &vmlinux_text);
> map_kernel_segment(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata);
> map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
> &vmlinux_init);
> - map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);
> + map_kernel_segment(pgd, _data, __robss_start, PAGE_KERNEL,
> + &vmlinux_data);
> + map_kernel_segment(pgd, __robss_start, __robss_end, PAGE_KERNEL_RO,
> + &vmlinux_robss);
I realised it is actually unnecessary to map the idmap and the zero
page into the kernel mapping, so we could drop this line.
^ permalink raw reply
* [PATCH v3 04/11] ARM: dts: r8a7743: initial SoC device tree
From: Sergei Shtylyov @ 2016-10-07 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007030932.GH13721@verge.net.au>
On 10/7/2016 6:09 AM, Simon Horman wrote:
>> The initial R8A7743 SoC device tree including CPU cores, GIC, timer, SYSC,
>> CPG, and the required clock descriptions.
>>
>> Based on the original (and large) patch by Dmitry Shifrin
>> <dmitry.shifrin@cogentembedded.com>.
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> I notice that this patch enables two CPUs. Have you tested SMP and:
> - CPU hotplug
> - Suspend to RAM
No, not really. I'll remove CPU1. :-<
MBR, Sergei
^ permalink raw reply
* [PATCH v2 2/2] ARM: dts: rockchip: Add rk3066 MK808 board
From: Heiko Stuebner @ 2016-10-07 10:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a166a444-8819-ffe7-8ee1-1f632f6a66ab@rock-chips.com>
Am Freitag, 7. Oktober 2016, 10:29:48 CEST schrieb Shawn Lin:
> Hi Pawe? ,
>
> On 2016/10/7 1:38, Pawe? Jarosz wrote:
> > MK808 is a tv stick which has rockchip rk3066 CPU inside, two usb ports
> > - host and otg, micro sd card slot and onboard wifi RK901.
> >
> > Signed-off-by: Pawe? Jarosz <paweljarosz3691@gmail.com>
> > ---
> >
> > Changes in v2:
> > - included Heiko sugestion.
> >
> > Documentation/devicetree/bindings/arm/rockchip.txt | 4 +
> > arch/arm/boot/dts/Makefile | 1 +
> > arch/arm/boot/dts/rk3066a-mk808.dts | 184
> > +++++++++++++++++++++ 3 files changed, 189 insertions(+)
> > create mode 100644 arch/arm/boot/dts/rk3066a-mk808.dts
> >
> > diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt
> > b/Documentation/devicetree/bindings/arm/rockchip.txt index
> > 55f388f..c09595b 100644
> > --- a/Documentation/devicetree/bindings/arm/rockchip.txt
> > +++ b/Documentation/devicetree/bindings/arm/rockchip.txt
> > @@ -17,6 +17,10 @@ Rockchip platforms device tree bindings
> >
> > Required root node properties:
> > - compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
> >
> > +- Rikomagic MK808 v1 board:
> > + Required root node properties:
> > + - compatible = "rikomagic,mk808", "rockchip,rk3066a";
> > +
> >
> > - Radxa Rock board:
> > Required root node properties:
> > - compatible = "radxa,rock", "rockchip,rk3188";
> >
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index befcd26..f19cc1d 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -639,6 +639,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> >
> > rk3036-kylin.dtb \
> > rk3066a-bqcurie2.dtb \
> > rk3066a-marsboard.dtb \
> >
> > + rk3066a-mk808.dtb \
> >
> > rk3066a-rayeager.dtb \
> > rk3188-radxarock.dtb \
> > rk3228-evb.dtb \
> >
> > diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts
> > b/arch/arm/boot/dts/rk3066a-mk808.dts new file mode 100644
> > index 0000000..2878562
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/rk3066a-mk808.dts
> > @@ -0,0 +1,184 @@
> > +/*
> > + * Copyright (c) 2016 Pawe? Jarosz <paweljarosz3691@gmail.com>
> > + *
> > + * This file is dual-licensed: you can use it either under the terms
> > + * of the GPL or the X11 license, at your option. Note that this dual
> > + * licensing only applies to this file, and not this project as a
> > + * whole.
> > + *
> > + * a) This file is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation; either version 2 of the
> > + * License, or (at your option) any later version.
> > + *
> > + * This file is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * Or, alternatively,
> > + *
> > + * b) Permission is hereby granted, free of charge, to any person
> > + * obtaining a copy of this software and associated documentation
> > + * files (the "Software"), to deal in the Software without
> > + * restriction, including without limitation the rights to use,
> > + * copy, modify, merge, publish, distribute, sublicense, and/or
> > + * sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following
> > + * conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be
> > + * included in all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> > + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> > + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> > + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> > + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > + * OTHER DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +/dts-v1/;
> > +#include "rk3066a.dtsi"
> > +
> > +/ {
> > + model = "Rikomagic MK808";
> > + compatible = "rikomagic,mk808", "rockchip,rk3066a";
> > +
> > + chosen {
> > + stdout-path = "serial2:115200n8";
> > + };
> > +
> > + memory at 60000000 {
> > + device_type = "memory";
> > + reg = <0x60000000 0x40000000>;
> > + };
> > +
> > + gpio-leds {
> > + compatible = "gpio-leds";
> > +
> > + blue {
> > + label = "mk808:blue:power";
> > + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
> > + default-state = "off";
> > + linux,default-trigger = "default-on";
> > + };
> > + };
> > +
> > + mmc_pwrseq: mmc-pwrseq {
> > + compatible = "mmc-pwrseq-simple";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&sdmmc_pwr>;
>
> sd slot does not contain a reset pin. So the power pin should be
> enough. just add sdmmc_pwr to mmc0's pinctrl-0 and let mmc driver
> control it should be enough. Typically pwrseq is for emmc and sdio.
> We don't need a pwerseq to control power for sd slot..
>
> But it seems sdmmc_pwr is a GPIO, but not functional port.
> So I am interesting that why MK808 board doesn't use the mmc
> controller's default power pin but chosing another gpio, so finally
> we have to add thses code for your DT.
Actually, we always model the sd-mmc pwr-pin as gpio-based regulator (see
sdmmc-regulator for example in the rk3066a-rayeager.dts), and specifiy this
regulator as vmmc. That way the mmc core really can control the power.
Heiko
^ permalink raw reply
* [PATCH v3 03/11] ARM: shmobile: r8a7743: basic SoC support
From: Sergei Shtylyov @ 2016-10-07 10:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2345971.ESZSzve5jF@avalon>
Hello.
On 10/7/2016 11:33 AM, Laurent Pinchart wrote:
>>> Add minimal support for the RZ/G1M (R8A7743) SoC.
>>>
>>> Based on the original (and large) patch by Dmitry Shifrin
>>> <dmitry.shifrin@cogentembedded.com>.
>>>
>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>
>> Thanks, I have queued this up.
>
> I'd like to see this patch rebased on top of "[PATCH] ARM: shmobile:
> Consolidate R8A779[234] machine definitions".
R87743 is analogous to R8A7791, not R8A779[234], not sure how it is
connected to your patch.
MBR, Sergei
^ permalink raw reply
* [PATCH v2 1/5] clk: add support for runtime pm
From: Ulf Hansson @ 2016-10-07 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474282525-30441-2-git-send-email-m.szyprowski@samsung.com>
On 19 September 2016 at 12:55, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Registers for some clocks might be located in the SOC area, which are under the
> power domain. To enable access to those registers respective domain has to be
> turned on. Additionally, registers for such clocks will usually loose its
> contents when power domain is turned off, so additional saving and restoring of
> them might be needed in the clock controller driver.
>
> This patch adds basic infrastructure in the clocks core to allow implementing
> driver for such clocks under power domains. Clock provider can supply a
> struct device pointer, which is the used by clock core for tracking and managing
> clock's controller runtime pm state. Each clk_prepare() operation
> will first call pm_runtime_get_sync() on the supplied device, while
> clk_unprepare() will do pm_runtime_put() at the end.
>
> Additional calls to pm_runtime_get/put functions are required to ensure that any
> register access (like calculating/changing clock rates and unpreparing/disabling
> unused clocks on boot) will be done with clock controller in runtime resumend
> state.
>
> When one wants to register clock controller, which make use of this feature, he
> has to:
> 1. Provide a struct device to the core when registering the provider and set
> CLK_RUNTIME_PM flags for its clocks.
> 2. It needs to enable runtime PM for that device.
> 3. It needs to make sure the runtime PM status of the controller device reflects
> the HW state.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/clk/clk.c | 107 +++++++++++++++++++++++++++++++++++++++----
> include/linux/clk-provider.h | 1 +
> 2 files changed, 98 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 820a939fb6bb..096a199b8e46 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -21,6 +21,7 @@
> #include <linux/of.h>
> #include <linux/device.h>
> #include <linux/init.h>
> +#include <linux/pm_runtime.h>
> #include <linux/sched.h>
> #include <linux/clkdev.h>
>
> @@ -46,6 +47,7 @@ struct clk_core {
> const struct clk_ops *ops;
> struct clk_hw *hw;
> struct module *owner;
> + struct device *dev;
> struct clk_core *parent;
> const char **parent_names;
> struct clk_core **parents;
> @@ -87,6 +89,26 @@ struct clk {
> struct hlist_node clks_node;
> };
>
> +/*** runtime pm ***/
> +static int clk_pm_runtime_get(struct clk_core *core)
> +{
> + int ret = 0;
> +
> + if (!core->dev)
> + return 0;
> +
> + ret = pm_runtime_get_sync(core->dev);
> + return ret < 0 ? ret : 0;
> +}
> +
> +static void clk_pm_runtime_put(struct clk_core *core)
> +{
> + if (!core->dev)
> + return;
> +
> + pm_runtime_put(core->dev);
> +}
> +
> /*** locking ***/
> static void clk_prepare_lock(void)
> {
> @@ -150,6 +172,8 @@ static void clk_enable_unlock(unsigned long flags)
>
> static bool clk_core_is_prepared(struct clk_core *core)
> {
> + bool status;
> +
> /*
> * .is_prepared is optional for clocks that can prepare
> * fall back to software usage counter if it is missing
> @@ -157,11 +181,17 @@ static bool clk_core_is_prepared(struct clk_core *core)
> if (!core->ops->is_prepared)
> return core->prepare_count;
>
> - return core->ops->is_prepared(core->hw);
> + clk_pm_runtime_get(core);
I guess you should assign status to the return code, and check it.
> + status = core->ops->is_prepared(core->hw);
> + clk_pm_runtime_put(core);
> +
> + return status;
> }
>
> static bool clk_core_is_enabled(struct clk_core *core)
> {
> + bool status;
> +
> /*
> * .is_enabled is only mandatory for clocks that gate
> * fall back to software usage counter if .is_enabled is missing
> @@ -169,7 +199,29 @@ static bool clk_core_is_enabled(struct clk_core *core)
> if (!core->ops->is_enabled)
> return core->enable_count;
>
> - return core->ops->is_enabled(core->hw);
> + /*
> + * Check if runtime pm is enabled before calling .is_enabled callback,
> + * if not assume that clock is disabled, because we might be called
> + * from atomic context, from which pm_runtime_get() is not allowed.
> + * This function is called mainly from clk_disable_unused_subtree,
> + * which ensures proper runtime pm activation of controller before
> + * taking enable spinlock, but the below check is needed if one tries
> + * to call it from other place.
> + */
> + if (core->dev) {
> + pm_runtime_get_noresume(core->dev);
> + if (pm_runtime_suspended(core->dev)) {
I think it's wrong to use pm_runtime_suspended().
What you should be checking, is whether the device is RPM_ACTIVE or if
runtime PM isn't enabled for device.
In other words, you should use pm_runtime_active() to find out whether
it's okay to invoke the ->is_enabled() ops or not.
Accordingly, I think the upper comment you added then needs to be a
rephrased a bit to reflect this.
> + status = false;
> + goto done;
> + }
> + }
> +
> + status = core->ops->is_enabled(core->hw);
> +done:
> + if (core->dev)
> + pm_runtime_put(core->dev);
> +
> + return status;
> }
>
> /*** helper functions ***/
> @@ -489,6 +541,8 @@ static void clk_core_unprepare(struct clk_core *core)
> if (core->ops->unprepare)
> core->ops->unprepare(core->hw);
>
> + clk_pm_runtime_put(core);
> +
> trace_clk_unprepare_complete(core);
> clk_core_unprepare(core->parent);
> }
> @@ -530,10 +584,14 @@ static int clk_core_prepare(struct clk_core *core)
> return 0;
>
> if (core->prepare_count == 0) {
> - ret = clk_core_prepare(core->parent);
> + ret = clk_pm_runtime_get(core);
> if (ret)
> return ret;
>
> + ret = clk_core_prepare(core->parent);
> + if (ret)
> + goto runtime_put;
> +
> trace_clk_prepare(core);
>
> if (core->ops->prepare)
> @@ -541,15 +599,18 @@ static int clk_core_prepare(struct clk_core *core)
>
> trace_clk_prepare_complete(core);
>
> - if (ret) {
> - clk_core_unprepare(core->parent);
> - return ret;
> - }
> + if (ret)
> + goto unprepare;
> }
>
> core->prepare_count++;
>
> return 0;
> +unprepare:
> + clk_core_unprepare(core->parent);
> +runtime_put:
> + clk_pm_runtime_put(core);
> + return ret;
> }
>
> static int clk_core_prepare_lock(struct clk_core *core)
> @@ -745,6 +806,9 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
> if (core->flags & CLK_IGNORE_UNUSED)
> return;
>
> + if (clk_pm_runtime_get(core) != 0)
You may simplify this:
if (clk_pm_runtime_get(core))
> + return;
> +
> if (clk_core_is_prepared(core)) {
> trace_clk_unprepare(core);
> if (core->ops->unprepare_unused)
> @@ -753,6 +817,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *core)
> core->ops->unprepare(core->hw);
> trace_clk_unprepare_complete(core);
> }
> +
> + clk_pm_runtime_put(core);
> }
>
> static void clk_disable_unused_subtree(struct clk_core *core)
> @@ -768,6 +834,9 @@ static void clk_disable_unused_subtree(struct clk_core *core)
> if (core->flags & CLK_OPS_PARENT_ENABLE)
> clk_core_prepare_enable(core->parent);
>
> + if (clk_pm_runtime_get(core) != 0)
Is there any reason to why you haven't moved this further down in this
function, like just before calling clk_core_is_enabled()?
You may also simplify this:
if (clk_pm_runtime_get(core))
> + return;
> +
You need to restore the call made to clk_core_prepare_enable()
earlier, so please update the error handling to cope with this.
> flags = clk_enable_lock();
>
> if (core->enable_count)
> @@ -794,6 +863,8 @@ unlock_out:
> clk_enable_unlock(flags);
> if (core->flags & CLK_OPS_PARENT_ENABLE)
> clk_core_disable_unprepare(core->parent);
> +
> + clk_pm_runtime_put(core);
> }
>
> static bool clk_ignore_unused;
> @@ -1563,6 +1634,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
> {
> struct clk_core *top, *fail_clk;
> unsigned long rate = req_rate;
> + int ret = 0;
>
> if (!core)
> return 0;
> @@ -1579,21 +1651,28 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
> if (!top)
> return -EINVAL;
>
> + ret = clk_pm_runtime_get(core);
> + if (ret)
> + return ret;
> +
> /* notify that we are about to change rates */
> fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
> if (fail_clk) {
> pr_debug("%s: failed to set %s rate\n", __func__,
> fail_clk->name);
> clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
> - return -EBUSY;
> + ret = -EBUSY;
> + goto err;
> }
>
> /* change the rates */
> clk_change_rate(top);
>
> core->req_rate = req_rate;
> +err:
> + clk_pm_runtime_put(core);
>
> - return 0;
> + return ret;
> }
>
> /**
> @@ -1824,12 +1903,16 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
> p_rate = parent->rate;
> }
>
> + ret = clk_pm_runtime_get(core);
> + if (ret)
> + goto out;
> +
> /* propagate PRE_RATE_CHANGE notifications */
> ret = __clk_speculate_rates(core, p_rate);
>
> /* abort if a driver objects */
> if (ret & NOTIFY_STOP_MASK)
> - goto out;
> + goto runtime_put;
>
> /* do the re-parent */
> ret = __clk_set_parent(core, parent, p_index);
> @@ -1842,6 +1925,8 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent)
> __clk_recalc_accuracies(core);
> }
>
> +runtime_put:
> + clk_pm_runtime_put(core);
> out:
> clk_prepare_unlock();
>
> @@ -2546,6 +2631,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
> goto fail_name;
> }
> core->ops = hw->init->ops;
> + if (dev && (hw->init->flags & CLK_RUNTIME_PM))
> + core->dev = dev;
I guess you need this to play safe, although I am really wondering if
we should try without.
Not that many clocks are currently being registered with a valid
struct device pointer. For the other cases why not try to use runtime
PM as per default?
Moreover we anyway rely on the clock provider to enable runtime PM for
the clock device, and when that isn't the case the runtime PM
deployment in the core should still be safe, right!?
> if (dev && dev->driver)
> core->owner = dev->driver->owner;
> core->hw = hw;
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index a39c0c530778..8a131eb71fdf 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -35,6 +35,7 @@
> #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
> /* parents need enable during gate/ungate, set rate and re-parent */
> #define CLK_OPS_PARENT_ENABLE BIT(12)
> +#define CLK_RUNTIME_PM BIT(13)
>
> struct clk;
> struct clk_hw;
> --
> 1.9.1
>
Kind regards
Uffe
^ permalink raw reply
* [PATCH v3 03/11] ARM: shmobile: r8a7743: basic SoC support
From: Geert Uytterhoeven @ 2016-10-07 10:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <836d9018-e8f4-27ef-bfff-06932184d59f@cogentembedded.com>
Hi Sergei,
On Fri, Oct 7, 2016 at 12:02 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 10/7/2016 11:33 AM, Laurent Pinchart wrote:
>>>> Add minimal support for the RZ/G1M (R8A7743) SoC.
>>>> Based on the original (and large) patch by Dmitry Shifrin
>>>> <dmitry.shifrin@cogentembedded.com>.
>>>>
>>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>>> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>>
>>>
>>> Thanks, I have queued this up.
>>
>>
>> I'd like to see this patch rebased on top of "[PATCH] ARM: shmobile:
>> Consolidate R8A779[234] machine definitions".
>
>
> R87743 is analogous to R8A7791, not R8A779[234], not sure how it is
> connected to your patch.
The comment
+ /*
+ * R8A7790 and R8A7791 can't be handled here as long as they need SMP
+ * initialization fallback.
+ */
is not about r8a7790/r8a7791 in se, but about backward compatibility support
for DTBs without APMU nodes and CPU enable-methods.
For new SoCs, we mandate the presence of these in the DTB.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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
^ permalink raw reply
* [PATCH 0/2] fix issue: vblank interrupts are never disabled
From: Daniel Kurtz @ 2016-10-07 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475119789-64619-1-git-send-email-bibby.hsieh@mediatek.com>
On Thu, Sep 29, 2016 at 11:29 AM, Bibby Hsieh <bibby.hsieh@mediatek.com> wrote:
>
> Clean the interrupt status before enable interrupt
> and set the vblank_disable_allowed to fix the issue.
For the series:
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
>
> Bibby Hsieh (2):
> drm/mediatek: set vblank_disable_allowed to true
> drm/mediatek: clear IRQ status before enable OVL interrupt
>
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 1 +
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 +
> 2 files changed, 2 insertions(+)
>
> --
> 1.7.9.5
>
^ permalink raw reply
* [PATCH v2 0/5] Add runtime PM support for clocks (on Exynos SoC example)
From: Tobias Jakobi @ 2016-10-07 11:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c1cf1a1f-2d1f-7f35-3e3b-f2de90959a24@samsung.com>
Hey Marek,
Marek Szyprowski wrote:
> Hi Tobias,
>
>
> On 2016-10-06 20:05, Tobias Jakobi wrote:
>> Hello Marek,
>>
>> I'm using the patches from the v4.8-clocks-pm-v2 branch plus the ones
>> from the v4.8-clocks-pm-v2 branch on top of 4.8.0.
>>
>> I see some warnings on boot coming from driver core. It appears that the
>> warnings are actually meaningful, since IOMMUs stop working completly.
>> E.g. if I modprobe s5p-mfc later, firmware loading fails because
>> apparantly the IOMMU domain isn't online.
>>
>>> WARNING: CPU: 0 PID: 1 at drivers/base/core.c:356
>>> device_links_driver_bound+0x124/0x12c
>> I added some debug printk() to device_links_driver_bound(), to show the
>> link status. Apparantly it is always DEVICE_LINK_AVAILABLE.
>
> Please note that some additional patches are needed to get IOMMU working
> properly with both runtime-pm patches and deferred probe, which feature
> in turn is needed to get it working after adding clocks-pm changes. I
> will send such patch soon (as a new version of IOMMU deferred probe
> support patches were posted a few days ago).
I see. I thought that this was supposed to work with the patches in
v4.8-clocks-pm-v2.
I picked the patches in this range (endpoints included).
- arm: dma-mapping: Don't override dma_ops in arch_setup_dma_ops()
- clocks: exynos5433: add runtime pm support
And this range in v4.8-iommu-pm-v4>
- driver core: Add a wrapper around __device_release_driver()
- iommu/exynos: Add proper runtime pm support
Anyway, looking forward to test the new patchset.
- Tobias
>
>> (...)
>
> Best regards
^ permalink raw reply
* [PATCH v4] Adding missing features of Coresight PTM components
From: Muhammad Abdul WAHAB @ 2016-10-07 12:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <60a1f04c-1e73-0ff1-dfee-775b875d2c4a@centralesupelec.fr>
In the current driver for Coresight components, two features of PTM
components are missing:
1. Branch Broadcasting (present also in ETM but called Branch Output)
2. Return Stack (only present in PTM v1.0 and PTMv1.1)
These features can be added simply to the code using `mode` field of
`etm_config` struct.
1. **Branch Broadcast** : The branch broadcast feature is present in ETM
components as well and is called Branch output. It allows to retrieve
addresses for direct branch addresses alongside the indirect branch
addresses. For example, it could be useful in cases when tracing without
source code.
2. **Return Stack** : The return stack option allows to retrieve the
return addresses of function calls. It can be useful to avoid CRA
(Code Reuse Attacks) by keeping a shadowstack.
Signed-off-by: Muhammad Abdul Wahab <muhammadabdul.wahab@centralesupelec.fr>
---
change(s) in v4 :
- syntax error correction (sorry did not compile after 1st version but
did compile it before sending it this time)
drivers/hwtracing/coresight/coresight-etm.h | 5 +++++
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 10 ++++++++++
2 files changed, 15 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm.h
b/drivers/hwtracing/coresight/coresight-etm.h
index 4a18ee4..ad063d7 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -89,11 +89,13 @@
/* ETMCR - 0x00 */
#define ETMCR_PWD_DWN BIT(0)
#define ETMCR_STALL_MODE BIT(7)
+#define ETMCR_BRANCH_BROADCAST BIT(8)
#define ETMCR_ETM_PRG BIT(10)
#define ETMCR_ETM_EN BIT(11)
#define ETMCR_CYC_ACC BIT(12)
#define ETMCR_CTXID_SIZE (BIT(14)|BIT(15))
#define ETMCR_TIMESTAMP_EN BIT(28)
+#define ETMCR_RETURN_STACK BIT(29)
/* ETMCCR - 0x04 */
#define ETMCCR_FIFOFULL BIT(23)
/* ETMPDCR - 0x310 */
@@ -110,8 +112,11 @@
#define ETM_MODE_STALL BIT(2)
#define ETM_MODE_TIMESTAMP BIT(3)
#define ETM_MODE_CTXID BIT(4)
+#define ETM_MODE_BBROAD BIT(5)
+#define ETM_MODE_RET_STACK BIT(6)
#define ETM_MODE_ALL (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC | \
ETM_MODE_STALL | ETM_MODE_TIMESTAMP | \
+ ETM_MODE_BBROAD | ETM_MODE_RET_STACK | \
ETM_MODE_CTXID | ETM_MODE_EXCL_KERN | \
ETM_MODE_EXCL_USER)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index e9b0719..7308304 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -164,6 +164,16 @@ static ssize_t mode_store(struct device *dev,
else
config->ctrl &= ~ETMCR_CTXID_SIZE;
+ if (config->mode & ETM_MODE_BBROAD)
+ config->ctrl |= ETMCR_BRANCH_BROADCAST;
+ else
+ config->ctrl &= ~ETMCR_BRANCH_BROADCAST;
+
+ if (config->mode & ETM_MODE_RET_STACK)
+ config->ctrl |= ETMCR_RETURN_STACK;
+ else
+ config->ctrl &= ~ETMCR_RETURN_STACK;
+
if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
etm_config_trace_mode(config);
--
1.9.1
^ permalink raw reply related
* [RESEND PATCH v2 -next 0/3] ARM64: amlogic: Add support for GXL SoC Family
From: Kevin Hilman @ 2016-10-07 13:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475595430-30075-1-git-send-email-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> This is a resend rebased on linux-next-20161004 tag.
>
> The new Amlogic GXL SoCs (S905X and S905D) are part of the Meson GX family and
> share some common features that can be described in a common GX dtsi file used
> by the Meson GXBB and Meson GXL Family dtsi.
>
> This patchset introduces the common GX dtsi and switches the GXBB to use
> the common GX dtsi.
> Then it introduces the GXL S905X SoC with the GXL common dtsi, then the S905D
> dtsi and the p212 board dts.
> Finally the GXL S905D SoC is introduced with a S905D dtsi using the GXL common
> and the p23x Board dtsi for the p231 and p230 development boards.
>
> Changes since v1 at http://lkml.kernel.org/r/20160903082227.30559-1-narmstrong at baylibre.com :
> - Add missing copyrigh in gx dtsi
> - Rename gxl SoCs compatibles to amlogic,s905x and amlogic,s905d
>
> Changes since RFC v1:
> - Merge GX common and GXBB changes in a single patch
> - Integrate GXL S905X patch
> - Add support for S905D and the p23x boards
>
> Note: This patchset integrates the patch "ARM64: dts: amlogic: Add basic support for Amlogic S905X" [1]
> from Carlo Caione.
I'm applying this series as the first DT change for v4.10, so all future
DT patches should be applied on top of this.
It's available in the v4.10/dt64 branch of my tree[1].
Kevin
[1] https://git.kernel.org/cgit/linux/kernel/git/khilman/linux-amlogic.git
^ permalink raw reply
* [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support
From: Laurent Pinchart @ 2016-10-07 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160930143709.1388-3-maxime.ripard@free-electrons.com>
Hi Maxime,
Thank you for the patch.
On Friday 30 Sep 2016 16:37:06 Maxime Ripard wrote:
> Some boards have an entirely passive RGB to VGA bridge, based on either
> DACs or resistor ladders.
A resistor ladder is a DAC :-)
> Those might or might not have an i2c bus routed to the VGA connector in
> order to access the screen EDIDs.
>
> Add a bridge that doesn't do anything but expose the modes available on the
> screen, either based on the EDIDs if available, or based on the XGA
> standards.
>
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Please see below for a few comments.
> ---
> .../bindings/display/bridge/rgb-to-vga-bridge.txt | 48 +++++
> drivers/gpu/drm/bridge/Kconfig | 7 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/rgb-to-vga.c | 229 ++++++++++++++++++
> 4 files changed, 285 insertions(+)
> create mode 100644
> Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
> create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c
>
> diff --git
> a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
> b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
> new file mode 100644
> index 000000000000..a8375bc1f9cb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt
> @@ -0,0 +1,48 @@
> +Dumb RGB to VGA bridge
> +----------------------
> +
> +This binding is aimed for dumb RGB to VGA bridges that do not require
> +any configuration.
> +
> +Required properties:
> +
> +- compatible: Must be "rgb-to-vga-bridge"
> +
> +Required nodes:
> +
> +This device has two video ports. Their connections are modeled using the OF
> +graph bindings specified in Documentation/devicetree/bindings/graph.txt. +
> +- Video port 0 for RGB input
> +- Video port 1 for VGA output
> +
> +
> +Example
> +-------
> +
> +bridge {
> + compatible = "rgb-to-vga-bridge";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port at 0 {
> + reg = <0>;
> +
> + vga_bridge_in: endpoint {
> + remote-endpoint = <&tcon0_out_vga>;
> + };
> + };
> +
> + port at 1 {
> + reg = <1>;
> +
> + vga_bridge_out: endpoint {
> + remote-endpoint = <&vga_con_in>;
> + };
> + };
> + };
> +};
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index b590e678052d..d690398c541c 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -17,6 +17,13 @@ config DRM_ANALOGIX_ANX78XX
> the HDMI output of an application processor to MyDP
> or DisplayPort.
>
> +config DRM_RGB_TO_VGA
> + tristate "Dumb RGB to VGA Bridge support"
> + depends on OF
> + select DRM_KMS_HELPER
> + help
> + Support for passive RGB to VGA bridges
> +
> config DRM_DW_HDMI
> tristate
> select DRM_KMS_HELPER
> diff --git a/drivers/gpu/drm/bridge/Makefile
> b/drivers/gpu/drm/bridge/Makefile index efdb07e878f5..3bb8cbe09fe9 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -1,6 +1,7 @@
> ccflags-y := -Iinclude/drm
>
> obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
> +obj-$(CONFIG_DRM_RGB_TO_VGA) += rgb-to-vga.o
> obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
> diff --git a/drivers/gpu/drm/bridge/rgb-to-vga.c
> b/drivers/gpu/drm/bridge/rgb-to-vga.c new file mode 100644
> index 000000000000..5ff4d4f3598f
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/rgb-to-vga.c
> @@ -0,0 +1,229 @@
> +/*
> + * Copyright (C) 2015-2016 Free Electrons
> + * Copyright (C) 2015-2016 NextThing Co
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_graph.h>
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc.h>
> +#include <drm/drm_crtc_helper.h>
> +
> +struct dumb_vga {
> + struct drm_bridge bridge;
> + struct drm_connector connector;
> +
> + struct i2c_adapter *ddc;
> +};
> +
> +static inline struct dumb_vga *
> +drm_bridge_to_dumb_vga(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct dumb_vga, bridge);
> +}
> +
> +static inline struct dumb_vga *
> +drm_connector_to_dumb_vga(struct drm_connector *connector)
> +{
> + return container_of(connector, struct dumb_vga, connector);
> +}
> +
> +static int dumb_vga_get_modes(struct drm_connector *connector)
> +{
> + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
> + struct edid *edid;
> + int ret;
> +
> + if (IS_ERR(vga->ddc))
> + goto fallback;
> +
> + edid = drm_get_edid(connector, vga->ddc);
> + if (!edid) {
> + DRM_INFO("EDID readout failed, falling back to standard
modes\n");
> + goto fallback;
> + }
> +
> + drm_mode_connector_update_edid_property(connector, edid);
> + return drm_add_edid_modes(connector, edid);
> +
> +fallback:
> + /*
> + * In case we cannot retrieve the EDIDs (broken or missing i2c
> + * bus), fallback on the XGA standards
> + */
> + ret = drm_add_modes_noedid(connector, 1920, 1200);
> +
> + /* And prefer a mode pretty much anyone can handle */
> + drm_set_preferred_mode(connector, 1024, 768);
> +
> + return ret;
> +}
> +
> +static const struct drm_connector_helper_funcs dumb_vga_con_helper_funcs =
> { + .get_modes = dumb_vga_get_modes,
> +};
> +
> +static enum drm_connector_status
> +dumb_vga_connector_detect(struct drm_connector *connector, bool force)
> +{
> + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
> +
> + /*
> + * Even if we have an I2C bus, we can't assume that the cable
> + * is disconnected if drm_probe_ddc fails. Some cables don't
> + * wire the DDC pins, or the I2C bus might not be working at
> + * all.
> + */
> + if (!IS_ERR(vga->ddc) && drm_probe_ddc(vga->ddc))
> + return connector_status_connected;
> +
> + return connector_status_unknown;
> +}
> +
> +static void
> +dumb_vga_connector_destroy(struct drm_connector *connector)
> +{
> + drm_connector_cleanup(connector);
> +}
> +
> +static const struct drm_connector_funcs dumb_vga_con_funcs = {
> + .dpms = drm_atomic_helper_connector_dpms,
> + .detect = dumb_vga_connector_detect,
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .destroy = dumb_vga_connector_destroy,
You can use drm_connector_cleanup directly here.
> + .reset = drm_atomic_helper_connector_reset,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static int dumb_vga_attach(struct drm_bridge *bridge)
> +{
> + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
> + int ret;
> +
> + if (!bridge->encoder) {
> + DRM_ERROR("Missing encoder\n");
> + return -ENODEV;
> + }
> +
> + drm_connector_helper_add(&vga->connector,
> + &dumb_vga_con_helper_funcs);
> + ret = drm_connector_init(bridge->dev, &vga->connector,
> + &dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA);
> + if (ret) {
> + DRM_ERROR("Failed to initialize connector\n");
> + return ret;
> + }
> +
> + drm_mode_connector_attach_encoder(&vga->connector,
> + bridge->encoder);
> +
> + return 0;
> +}
> +
> +static const struct drm_bridge_funcs dumb_vga_bridge_funcs = {
> + .attach = dumb_vga_attach,
> +};
> +
> +static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
> +{
> + struct device_node *end_node, *phandle, *remote;
> + struct i2c_adapter *ddc;
> +
> + end_node = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
> + if (!end_node) {
> + dev_err(dev, "Missing connector endpoint\n");
> + return ERR_PTR(-ENODEV);
> + }
> +
> + remote = of_graph_get_remote_port_parent(end_node);
> + of_node_put(end_node);
> + if (!remote) {
> + dev_err(dev, "Enable to parse remote node\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
> + of_node_put(remote);
> + if (!phandle)
> + return ERR_PTR(-ENODEV);
> +
> + ddc = of_get_i2c_adapter_by_node(phandle);
> + of_node_put(phandle);
> + if (!ddc)
> + return ERR_PTR(-EPROBE_DEFER);
> +
> + return ddc;
> +}
> +
> +static int dumb_vga_probe(struct platform_device *pdev)
> +{
> + struct dumb_vga *vga;
> + int ret;
> +
> + vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
> + if (!vga)
> + return -ENOMEM;
> + platform_set_drvdata(pdev, vga);
> +
> + vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
> + if (IS_ERR(vga->ddc)) {
> + if (PTR_ERR(vga->ddc) == -ENODEV) {
> + dev_info(&pdev->dev,
> + "No i2c bus specified... Disabling EDID
readout\n");
Nitpicking, there's no need for an ellipsis ("..."). I'd write the message as
"DDC not available, disabling EDID readout".
You could also turn it into a dev_dbg() message as I'm not sure it's really
crucial information, that's up to you.
> + } else {
> + dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n");
> + return PTR_ERR(vga->ddc);
> + }
> + }
> +
> + vga->bridge.funcs = &dumb_vga_bridge_funcs;
> + vga->bridge.of_node = pdev->dev.of_node;
> +
> + ret = drm_bridge_add(&vga->bridge);
> + if (ret && !IS_ERR(vga->ddc))
> + i2c_put_adapter(vga->ddc);
> +
> + return ret;
> +}
> +
> +static int dumb_vga_remove(struct platform_device *pdev)
> +{
> + struct dumb_vga *vga = platform_get_drvdata(pdev);
> +
> + drm_bridge_remove(&vga->bridge);
> +
> + if (!IS_ERR(vga->ddc))
> + i2c_put_adapter(vga->ddc);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id dumb_vga_match[] = {
> + { .compatible = "rgb-to-vga-bridge" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, dumb_vga_match);
> +
> +struct platform_driver dumb_vga_driver = {
> + .probe = dumb_vga_probe,
> + .remove = dumb_vga_remove,
> + .driver = {
> + .name = "rgb-to-vga-bridge",
If we changing the compatible string to "dumb-vga-dac" as proposed by Archit,
let's not forget to rename the driver (dumb-vga-dac.ko seems a good match) as
well as the description string below ("Dumb VGA DAC bridge driver" ?). Both
The DT binding and Kconfig texts need to be updated as well.
I would also rename struct dumb_vga to dumb_vga_dac, that's up to you.
> + .of_match_table = dumb_vga_match,
> + },
> +};
> +module_platform_driver(dumb_vga_driver);
> +
> +MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
> +MODULE_DESCRIPTION("Dumb RGB to VGA bridge driver");
> +MODULE_LICENSE("GPL");
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH v2 0/2] ARM64: meson-gxbb: Add support for the Nexbox A95X Board
From: Kevin Hilman @ 2016-10-07 13:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475654980-16414-1-git-send-email-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> Add support for the Amlogic S905 (GXBB) version of the Nexbox A95X, an IPTV
> set-top-box with Ethernet, SDCard, eMMC, USB, HDMI, IR, Led, Reset button and Audio Jack.
>
> Changes since v1 at: http://lkml.kernel.org/r/1471951370-29269-1-git-send-email-narmstrong at baylibre.com
> - Rebase on linux-next-20161004 with patchset [1]
> - Add nexbox vendor prefix
>
> [1] http://lkml.kernel.org/r/1475595430-30075-1-git-send-email-narmstrong at baylibre.com
>
> Neil Armstrong (2):
> devicetree: Add vendor prefix for Nexbox
> ARM: dts: meson-gxbb: Add support for the Nexbox A95X Board
Applied to v4.10/dt64 branch,
Kevin
^ permalink raw reply
* [PATCH 2/2] ARM: imx: improve precision of AV PLL to 1 Hz
From: Emil Lundmark @ 2016-10-07 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007094828.3f967c93@ipc1.ka-ro>
On Fri, Oct 07, 2016 at 09:48:28AM +0200, Lothar Wa?mann wrote:
> Hi,
>
> On Thu, 6 Oct 2016 13:12:11 +0200 Emil Lundmark wrote:
> > The audio and video PLLs are designed to have a precision of 1 Hz if some
> > conditions are met. The current implementation only allows a precision that
> > depends on the rate of the parent clock. E.g., if the parent clock is 24
> > MHz, the precision will be 24 Hz; or more generally the precision will be
> >
> > p / 10^6 Hz
> >
> > where p is the parent clock rate. This comes down to how the register
> > values for the PLL's fractional loop divider is chosen.
> >
> > The clock rate calculation for the PLL is
> >
> > PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM)
> >
> > or with a shorter notation
> >
> > r = p * (d + a / b)
> >
> > In addition to all variables being integers, we also have the following
> > conditions:
> >
> > 27 <= d <= 54
> >
> > 0 <= a <= 2^30-1
> >
> Wrong. 'a' is a _signed_ number (see below)!
> So this should be:
Correct, good catch! It is confusing that the denominator is defined as
'u32 mfn', I think it should be changed to 's32 mfn' instead.
> -2^29 <= a < 2^29
>
> > 0 < b <= 2^30-1
> > a < b
> >
> > Here, d, a and b are register values for the fractional loop divider. We
> > want to chose d, a and b such that f(p, r) = p, i.e. f is our round_rate
> > function. Currently, d and b are chosen as
> >
> > d = r / p
> > b = 10^6
> >
> > hence we get the poor precision. And a is defined in terms of r, d, p and
> > b:
> >
> > a = (r - d * p) * b / p
> >
> > I propose that if p <= 2^30-1 (i.e., the max value for b), we chose b as
> >
> > b = p
> >
> According to the Reference Manual the "Absolute value should be less
> than denominator"
> |18.7.9 Numerator of Audio PLL Fractional Loop Divider Register
> | (CCM_ANALOG_PLL_AUDIO_NUM)
> |This register contains the numerator (A) of Audio PLL fractional loop divider.(Signed
> |number), absolute value should be less than denominator
> |Absolute value should be less than denominator
>
Yes, this changes everything. Lets revise my argument. We have the
following:
|a| < b
d = r / p
a = (r - d * p) * b / p
If b = p, the expressions above still holds. Proof:
|a| < b
|(r - d * p) * b / p| < b
|r - d * p| < p
Which have two solutions, one of them is when p < 0, so we can skip that
one. The other is when p > 0 and
p * (d - 1) < r < p * (d + 1)
Substitute d = r / p
(r - p) < r < (r + p) <=> p > 0
So, as long as p > 0, we can chose b = p.
However, we still have the constraint that b <= 2^30-1, so p <= 2^30-1.
Which means that my proposed patch actually works, only my initial
reasoning was wrong.
For even more nitpicking, would it not be better to chose d = round(a / b)?
Now, we essentially have d = floor(a / b) because of the integer division.
So, with the current choice for d, would we not loose precision if
p > 2^29-1?
The question is, should we always chose b = p and ignore the precision loss
if p > 2^30-1 (or p > 2^29-1)?
--
Emil Lundmark
^ permalink raw reply
* [PATCH 1/2] ARM: imx: fix integer overflow in AV PLL round rate
From: Emil Lundmark @ 2016-10-07 14:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475752331-19525-1-git-send-email-emil@limesaudio.com>
I realize that the two patches in this series does not actually depend on
each other. This is my first contribution to Linux so I wonder if I should
resubmit these as two separate patches instead?
For example, what if the second patch in the series is not needed? Do you
only accept the first patch then? Or what if I need to revise the second
patch? It seems unnecessary to include the first patch in that case.
I also got the threading wrong, but thats another story.
--
Emil Lundmark
^ permalink raw reply
* [PATCH v6 0/6] ARM: dts: imx6q: Add Engicam i.CoreM6 dts
From: Jagan Teki @ 2016-10-07 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1474917787-29030-1-git-send-email-jteki@openedev.com>
On Tue, Sep 27, 2016 at 12:53 AM, Jagan Teki <jteki@openedev.com> wrote:
> This is series add dts support for Engicam I.Core M6 qdl modules on
> top of */shawnguo/linux.git for-next.
>
> Jagan Teki (6):
> of: Add vendor prefix for Engicam s.r.l company
> ARM: dts: imx6q: Add Engicam i.CoreM6 Quad/Dual initial support
> ARM: dts: imx6q: Add Engicam i.CoreM6 DualLite/Solo initial support
> ARM: dts: imx6qdl-icore: Add usbhost support
> ARM: dts: imx6qdl-icore: Add usbotg support
> ARM: dts: imx6qdl-icore: Add FEC support
Shawn, please pick this series.
thanks!
--
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.
^ permalink raw reply
* [PATCH] ARM64: dts: meson-gx: Add missing L2 cache node
From: Kevin Hilman @ 2016-10-07 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475675630-31514-1-git-send-email-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> In order to remove the boot warning :
> [ 2.290933] Unable to detect cache hierarchy from DT for CPU 0
> And add missing L2 cache hierarchy information, add a simple l2 cache node
> and reference it from the A53 cpu nodes.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Applied to v4.10/dt64.
Kevin
^ permalink raw reply
* [PATCH 1/4] staging/vchi: Convert to current get_user_pages() arguments.
From: Greg Kroah-Hartman @ 2016-10-07 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003185209.27733-2-eric@anholt.net>
On Mon, Oct 03, 2016 at 11:52:06AM -0700, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric@anholt.net>
In the future, it's good to put at least some changelog text in here. I
normally do not accept patches without it. But I'll take these two.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v2] ARM64: dts: meson-gxbb: Add rmii pinctrl node and rename rgmii node
From: Neil Armstrong @ 2016-10-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
For boards only supporting 10/100 ethernet over a RMII PHY link, add
a separate pinctrl node. By the way, rename the existing node to rgmii
specific naming in all boards dts.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 3 ++-
arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 +-
arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 2 +-
arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 2 +-
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 17 ++++++++++++++++-
5 files changed, 21 insertions(+), 5 deletions(-)
Changes since v1 at http://lkml.kernel.org/r/1475678673-15277-1-git-send-email-narmstrong at baylibre.com :
- Change Nexbox A95X to rmii interface
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 80d7b35..399d85f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -97,8 +97,9 @@
ðmac {
status = "okay";
- pinctrl-0 = <ð_pins>;
+ pinctrl-0 = <ð_rmii_pins>;
pinctrl-names = "default";
+ phy-mode = "rmii";
};
&ir {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index e6e3491..325b9c5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -83,7 +83,7 @@
ðmac {
status = "okay";
- pinctrl-0 = <ð_pins>;
+ pinctrl-0 = <ð_rgmii_pins>;
pinctrl-names = "default";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 06a34dc..031d69b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -81,7 +81,7 @@
ðmac {
status = "okay";
- pinctrl-0 = <ð_pins>;
+ pinctrl-0 = <ð_rgmii_pins>;
pinctrl-names = "default";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 73f1593..e93221a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -82,7 +82,7 @@
ðmac {
status = "okay";
- pinctrl-0 = <ð_pins>;
+ pinctrl-0 = <ð_rgmii_pins>;
pinctrl-names = "default";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 443811b..aad639a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -443,7 +443,7 @@
};
};
- eth_pins: eth_c {
+ eth_rgmii_pins: eth-rgmii {
mux {
groups = "eth_mdio",
"eth_mdc",
@@ -463,6 +463,21 @@
};
};
+ eth_rmii_pins: eth-rmii {
+ mux {
+ groups = "eth_mdio",
+ "eth_mdc",
+ "eth_clk_rx_clk",
+ "eth_rx_dv",
+ "eth_rxd0",
+ "eth_rxd1",
+ "eth_tx_en",
+ "eth_txd0",
+ "eth_txd1";
+ function = "eth";
+ };
+ };
+
pwm_a_x_pins: pwm_a_x {
mux {
groups = "pwm_a_x";
--
1.9.1
^ permalink raw reply related
* [PATCH v4 01/10] ethernet: add sun8i-emac driver
From: Joe Perches @ 2016-10-07 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475828757-926-2-git-send-email-clabbe.montjoie@gmail.com>
On Fri, 2016-10-07 at 10:25 +0200, Corentin Labbe wrote:
> This patch add support for sun8i-emac ethernet MAC hardware.
> It could be found in Allwinner H3/A83T/A64 SoCs.
trivial notes:
> diff --git a/drivers/net/ethernet/allwinner/sun8i-emac.c b/drivers/net/ethernet/allwinner/sun8i-emac.c
[]
> +static const char const estats_str[][ETH_GSTRING_LEN] = {
one too many const
> +/* MAGIC value for knowing if a descriptor is available or not */
> +#define DCLEAN cpu_to_le32(BIT(16) | BIT(14) | BIT(12) | BIT(10) | BIT(9))
Aren't there #defines for these bits?
> +static void sun8i_emac_flow_ctrl(struct sun8i_emac_priv *priv, int duplex,
> + int fc)
> +{
> + u32 flow = 0;
> +
> + flow = readl(priv->base + EMAC_RX_CTL0);
> + if (fc & EMAC_FLOW_RX)
> + flow |= BIT(16);
> + else
> + flow &= ~BIT(16);
> + writel(flow, priv->base + EMAC_RX_CTL0);
> +
> + flow = readl(priv->base + EMAC_TX_FLOW_CTL);
> + if (fc & EMAC_FLOW_TX)
> + flow |= BIT(0);
> + else
> + flow &= ~BIT(0);
more magic bits that could be #defines
> +static int sun8i_emac_rx_from_ddesc(struct net_device *ndev, int i)
> +{
> []
> + /* the checksum or length of received frame's payload is wrong*/
> + if (dstatus & BIT(0)) {
[]
> + if (dstatus & BIT(1)) {
[]
> + if ((dstatus & BIT(3))) {
etc...
^ permalink raw reply
* [PATCH v3 0/6] Support PWM polarity control
From: Bhuvanchandra DV @ 2016-10-07 15:11 UTC (permalink / raw)
To: linux-arm-kernel
Changes since v3:
- Set pwm->args.polarity, before using pwm_set_polarity() function as suggested
by Lukasz.
- Squash Lukasz patch( https://lkml.org/lkml/2016/10/6/32 )
Tested on Toradex Colibri iMX6S module.
Changes since v2:
- Picked the stalled patchset[1] from Lothar Wassmann which adds the basic
support for polarity control on imx-pwm driver and adds backward compatibility
support for devices which does not have polarity control feature.
Changes since Lothars v6:
- Squash Lukasz patch[2].
[1] http://thread.gmane.org/gmane.linux.pwm/1621
[2] https://www.spinics.net/lists/arm-kernel/msg530818.html
Bhuvanchandra DV (3):
arm: dts: imx7: Update #pwm-cells for PWM polarity control
arm: dts: imx7-colibri: Use pwm polarity control
arm: dts: imx7-colibri: Use enable-gpios for BL_ON
Lothar Wassmann (3):
pwm: print error messages with pr_err() instead of pr_debug()
pwm: core: make the PWM_POLARITY flag in DTB optional
pwm: imx: support output polarity inversion
Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +--
arch/arm/boot/dts/imx7-colibri.dtsi | 12 +++++-
arch/arm/boot/dts/imx7s.dtsi | 8 ++--
drivers/pwm/core.c | 26 ++++++------
drivers/pwm/pwm-imx.c | 51 +++++++++++++++++++++--
5 files changed, 79 insertions(+), 24 deletions(-)
--
2.10.0
^ permalink raw reply
* [PATCH v3 1/6] pwm: print error messages with pr_err() instead of pr_debug()
From: Bhuvanchandra DV @ 2016-10-07 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007151129.6043-1-bhuvanchandra.dv@toradex.com>
From: Lothar Wassmann <LW@KARO-electronics.de>
Make the messages that are printed in case of fatal errors actually
visible to the user without having to recompile the driver with
debugging enabled.
Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
drivers/pwm/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 0dbd29e..195373e 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -661,13 +661,13 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id)
err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index,
&args);
if (err) {
- pr_debug("%s(): can't parse \"pwms\" property\n", __func__);
+ pr_err("%s(): can't parse \"pwms\" property\n", __func__);
return ERR_PTR(err);
}
pc = of_node_to_pwmchip(args.np);
if (IS_ERR(pc)) {
- pr_debug("%s(): PWM chip not found\n", __func__);
+ pr_err("%s(): PWM chip not found\n", __func__);
pwm = ERR_CAST(pc);
goto put;
}
--
2.10.0
^ permalink raw reply related
* [PATCH v3 2/6] pwm: core: make the PWM_POLARITY flag in DTB optional
From: Bhuvanchandra DV @ 2016-10-07 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007151129.6043-1-bhuvanchandra.dv@toradex.com>
From: Lothar Wassmann <LW@KARO-electronics.de>
Change the pwm chip driver registration, so that a chip driver that
supports polarity inversion can still be used with DTBs that don't
provide the 'PWM_POLARITY' flag.
This is done to provide polarity inversion support for the pwm-imx
driver without having to modify all existing DTS files.
Signed-off-by: Lothar Wassmann <LW@KARO-electronics.de>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Suggested-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/pwm/core.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 195373e..85cdda6 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -137,9 +137,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
{
struct pwm_device *pwm;
+ /* check, whether the driver supports a third cell for flags */
if (pc->of_pwm_n_cells < 3)
return ERR_PTR(-EINVAL);
+ /* flags in the third cell are optional */
+ if (args->args_count < 2)
+ return ERR_PTR(-EINVAL);
+
if (args->args[0] >= pc->npwm)
return ERR_PTR(-EINVAL);
@@ -148,11 +153,10 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
return pwm;
pwm->args.period = args->args[1];
+ pwm->args.polarity = PWM_POLARITY_NORMAL;
- if (args->args[2] & PWM_POLARITY_INVERTED)
+ if (args->args_count > 2 && args->args[2] & PWM_POLARITY_INVERTED)
pwm->args.polarity = PWM_POLARITY_INVERSED;
- else
- pwm->args.polarity = PWM_POLARITY_NORMAL;
return pwm;
}
@@ -163,9 +167,14 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
{
struct pwm_device *pwm;
+ /* sanity check driver support */
if (pc->of_pwm_n_cells < 2)
return ERR_PTR(-EINVAL);
+ /* all cells are required */
+ if (args->args_count != pc->of_pwm_n_cells)
+ return ERR_PTR(-EINVAL);
+
if (args->args[0] >= pc->npwm)
return ERR_PTR(-EINVAL);
@@ -672,13 +681,6 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id)
goto put;
}
- if (args.args_count != pc->of_pwm_n_cells) {
- pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
- args.np->full_name);
- pwm = ERR_PTR(-EINVAL);
- goto put;
- }
-
pwm = pc->of_xlate(pc, &args);
if (IS_ERR(pwm))
goto put;
--
2.10.0
^ permalink raw reply related
* [PATCH v3 3/6] pwm: imx: support output polarity inversion
From: Bhuvanchandra DV @ 2016-10-07 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007151129.6043-1-bhuvanchandra.dv@toradex.com>
From: Lothar Wassmann <LW@KARO-electronics.de>
The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable output
polarity. This patch adds support to utilize this feature where available.
Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +--
drivers/pwm/pwm-imx.c | 51 +++++++++++++++++++++--
2 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
index e00c2e9..c61bdf8 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -6,8 +6,8 @@ Required properties:
- "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
- "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
- reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
- the cells format.
+- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
+ in this directory for a description of the cells format.
- clocks : Clock specifiers for both ipg and per clocks.
- clock-names : Clock names should include both "ipg" and "per"
See the clock consumer binding,
@@ -17,7 +17,7 @@ See the clock consumer binding,
Example:
pwm1: pwm at 53fb4000 {
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
reg = <0x53fb4000 0x4000>;
clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index d600fd5..c37d223 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -38,6 +38,7 @@
#define MX3_PWMCR_DOZEEN (1 << 24)
#define MX3_PWMCR_WAITEN (1 << 23)
#define MX3_PWMCR_DBGEN (1 << 22)
+#define MX3_PWMCR_POUTC (1 << 18)
#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
#define MX3_PWMCR_SWR (1 << 3)
@@ -180,6 +181,9 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
if (enable)
cr |= MX3_PWMCR_EN;
+ if (pwm->args.polarity == PWM_POLARITY_INVERSED)
+ cr |= MX3_PWMCR_POUTC;
+
writel(cr, imx->mmio_base + MX3_PWMCR);
return 0;
@@ -240,27 +244,62 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
clk_disable_unprepare(imx->clk_per);
}
-static struct pwm_ops imx_pwm_ops = {
+static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ u32 val;
+
+ if (polarity == pwm->args.polarity)
+ return 0;
+
+ val = readl(imx->mmio_base + MX3_PWMCR);
+
+ if (polarity == PWM_POLARITY_INVERSED)
+ val |= MX3_PWMCR_POUTC;
+ else
+ val &= ~MX3_PWMCR_POUTC;
+
+ writel(val, imx->mmio_base + MX3_PWMCR);
+
+ dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__,
+ polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal");
+
+ return 0;
+}
+
+static struct pwm_ops imx_pwm_ops_v1 = {
.enable = imx_pwm_enable,
.disable = imx_pwm_disable,
.config = imx_pwm_config,
.owner = THIS_MODULE,
};
+static struct pwm_ops imx_pwm_ops_v2 = {
+ .enable = imx_pwm_enable,
+ .disable = imx_pwm_disable,
+ .set_polarity = imx_pwm_set_polarity,
+ .config = imx_pwm_config,
+ .owner = THIS_MODULE,
+};
+
struct imx_pwm_data {
int (*config)(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns);
void (*set_enable)(struct pwm_chip *chip, bool enable);
+ struct pwm_ops *pwm_ops;
};
static struct imx_pwm_data imx_pwm_data_v1 = {
.config = imx_pwm_config_v1,
.set_enable = imx_pwm_set_enable_v1,
+ .pwm_ops = &imx_pwm_ops_v1,
};
static struct imx_pwm_data imx_pwm_data_v2 = {
.config = imx_pwm_config_v2,
.set_enable = imx_pwm_set_enable_v2,
+ .pwm_ops = &imx_pwm_ops_v2,
};
static const struct of_device_id imx_pwm_dt_ids[] = {
@@ -282,6 +321,8 @@ static int imx_pwm_probe(struct platform_device *pdev)
if (!of_id)
return -ENODEV;
+ data = of_id->data;
+
imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
if (imx == NULL)
return -ENOMEM;
@@ -300,18 +341,22 @@ static int imx_pwm_probe(struct platform_device *pdev)
return PTR_ERR(imx->clk_ipg);
}
- imx->chip.ops = &imx_pwm_ops;
+ imx->chip.ops = data->pwm_ops;
imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
imx->chip.npwm = 1;
imx->chip.can_sleep = true;
+ if (data->pwm_ops->set_polarity) {
+ dev_dbg(&pdev->dev, "PWM supports output inversion\n");
+ imx->chip.of_xlate = of_pwm_xlate_with_flags;
+ imx->chip.of_pwm_n_cells = 3;
+ }
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(imx->mmio_base))
return PTR_ERR(imx->mmio_base);
- data = of_id->data;
imx->config = data->config;
imx->set_enable = data->set_enable;
--
2.10.0
^ permalink raw reply related
* [PATCH v3 4/6] arm: dts: imx7: Update #pwm-cells for PWM polarity control
From: Bhuvanchandra DV @ 2016-10-07 15:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161007151129.6043-1-bhuvanchandra.dv@toradex.com>
Update #pwm-cells to 3 in order to support PWM signal polarity control.
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Acked-by: Rob Herring <robh@kernel.org>
---
arch/arm/boot/dts/imx7s.dtsi | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 0d7d5ac..8d1d471 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -601,7 +601,7 @@
clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
<&clks IMX7D_PWM1_ROOT_CLK>;
clock-names = "ipg", "per";
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
status = "disabled";
};
@@ -612,7 +612,7 @@
clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
<&clks IMX7D_PWM2_ROOT_CLK>;
clock-names = "ipg", "per";
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
status = "disabled";
};
@@ -623,7 +623,7 @@
clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
<&clks IMX7D_PWM3_ROOT_CLK>;
clock-names = "ipg", "per";
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
status = "disabled";
};
@@ -634,7 +634,7 @@
clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
<&clks IMX7D_PWM4_ROOT_CLK>;
clock-names = "ipg", "per";
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
status = "disabled";
};
--
2.10.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox