* Re: [PATCH v2] backlight: pwm: reject legacy pwm request for device defined in dt
From: Boris Brezillon @ 2015-10-12 15:19 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Nicolas Ferre, Thierry Reding, Lee Jones, Jingoo Han,
Robert Jarzmik, linux-pwm, linux-fbdev
In-Reply-To: <561BC177.2050000@mentor.com>
On Mon, 12 Oct 2015 17:19:35 +0300
Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> wrote:
>
> > Thierry's patch makes sure that EPROBE_DEFER is not returned when the
> > PWM device definition is not found using in the PWM lookup tables or
> > the DT definition,
>
> This is okay, but I'm interested in proper handling of cases other than
> EPROBE_DEFER. EPROBE_DEFER and the related issues are on your balance
> and I'm attempting to avoid interfering with it here :)
I keep thinking we should fix all platforms using the ->pwm_id pdata
field to attach a PWM device to a PWM backlight instead of trying to
guess when falling back to the legacy API is acceptable...
>
> > and in this case the pwm_bl code will fallback to
> > the legacy PWM API, which AFAICT is what you're trying to solve.
>
> Fallback must happen exclusively under (IS_ERR(pb->pwm) &&
> PTR_ERR(pb->pwm) != -EPROBE_DEFER && !pdev->dev.of_node) condition IMHO.
>
> Before EPROBE_DEFER appeared on the scene the condition was
> (IS_ERR(pb->pwm) && !pdev->dev.of_node).
>
> So, the question is if my change requires any updates or not from your
> point of view.
... but from a functional point of view your patch seems correct.
Best Regards,
Boris
--
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH v2] backlight: pwm: reject legacy pwm request for device defined in dt
From: Vladimir Zapolskiy @ 2015-10-12 15:32 UTC (permalink / raw)
To: Boris Brezillon, Robert Jarzmik
Cc: Nicolas Ferre, Thierry Reding, Lee Jones, Jingoo Han, linux-pwm,
linux-fbdev
In-Reply-To: <20151012171931.3fb922d2@bbrezillon>
On 12.10.2015 18:19, Boris Brezillon wrote:
> On Mon, 12 Oct 2015 17:19:35 +0300
> Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> wrote:
>>
>>> Thierry's patch makes sure that EPROBE_DEFER is not returned when the
>>> PWM device definition is not found using in the PWM lookup tables or
>>> the DT definition,
>>
>> This is okay, but I'm interested in proper handling of cases other than
>> EPROBE_DEFER. EPROBE_DEFER and the related issues are on your balance
>> and I'm attempting to avoid interfering with it here :)
>
> I keep thinking we should fix all platforms using the ->pwm_id pdata
> field to attach a PWM device to a PWM backlight instead of trying to
> guess when falling back to the legacy API is acceptable...
>
>>
>>> and in this case the pwm_bl code will fallback to
>>> the legacy PWM API, which AFAICT is what you're trying to solve.
>>
>> Fallback must happen exclusively under (IS_ERR(pb->pwm) &&
>> PTR_ERR(pb->pwm) != -EPROBE_DEFER && !pdev->dev.of_node) condition IMHO.
>>
>> Before EPROBE_DEFER appeared on the scene the condition was
>> (IS_ERR(pb->pwm) && !pdev->dev.of_node).
>>
>> So, the question is if my change requires any updates or not from your
>> point of view.
>
> ... but from a functional point of view your patch seems correct.
Sounds good, thank you for review.
Robert,
because you found a regression in the related area of code on a
platform, which uses legacy PWM API, could you please confirm that three
patches applied in a row don't break anything for you, the changes are:
* Nicolas' 68feaca0b1 ("backlight: pwm: Handle EPROBE_DEFER while
requesting the PWM")
* Thierry' https://lkml.org/lkml/2015/10/5/319
* and this one is the last in the series:
http://thread.gmane.org/gmane.linux.pwm/2813
--
With best wishes,
Vladimir
^ permalink raw reply
* [PATCH RFC 0/2] simplefb: Add regulator handling support
From: Chen-Yu Tsai @ 2015-10-12 17:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi everyone,
This series adds regulator claiming and enabling support for simplefb.
Sometimes the simplefb display output path consits of external conversion
chips and/or LCD drivers and backlights. These devices normally have
GPIOs to turn them on and/or bring them out of reset, and regulators
supplying power to them.
While the kernel does not touch unclaimed GPIOs, the regulator core
happily disables unused regulators. Thus we need simplefb to claim
and enable the regulators used throughout the display pipeline.
Now the DT bindings don't support a list of regulators directly, so
I'm working around it by having a "num-supplies" property to specify
the number of supply properties to check, and name the actual supplies
as "vinN-supply".
Hans, Maxime, AXP223 support for the A23/A33 Q8 tablets will need this
to keep the LCD on. The Primo81 needs this as well.
Patch 1 adds the regulator properties to the DT binding.
Patch 2 adds code to the simplefb driver to claim and enable regulators.
Regards
ChenYu
Chen-Yu Tsai (2):
dt-bindings: simplefb: Support a list of regulator supply properties
simplefb: Claim and enable regulators
.../bindings/video/simple-framebuffer.txt | 14 ++-
drivers/video/fbdev/simplefb.c | 102 ++++++++++++++++++++-
2 files changed, 111 insertions(+), 5 deletions(-)
--
2.5.3
^ permalink raw reply
* [PATCH RFC 1/2] dt-bindings: simplefb: Support a list of regulator supply properties
From: Chen-Yu Tsai @ 2015-10-12 17:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1444669458-5588-1-git-send-email-wens@csie.org>
The physical display tied to the framebuffer may have regulators
providing power to it, such as power for LCDs or interface conversion
chips.
The number of regulators in use may vary, but the regulator supply
binding can not be a list. Work around this by adding a "num-supplies"
property to communicate the number of supplies, and a list of 0 ~ N
"vinN-supply" properties for the actual regulator supply.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
.../devicetree/bindings/video/simple-framebuffer.txt | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
index 4474ef6e0b95..0cc43e1be8b5 100644
--- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
+++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
@@ -47,10 +47,14 @@ Required properties:
- a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
Optional properties:
-- clocks : List of clocks used by the framebuffer. Clocks listed here
- are expected to already be configured correctly. The OS must
- ensure these clocks are not modified or disabled while the
- simple framebuffer remains active.
+- clocks : List of clocks used by the framebuffer.
+- num-supplies : The number of regulators used by the framebuffer.
+- vinN-supply : The N-th (from 0) regulator used by the framebuffer.
+
+ The above resources are expected to already be configured correctly.
+ The OS must ensure they are not modified or disabled while the simple
+ framebuffer remains active.
+
- display : phandle pointing to the primary display hardware node
Example:
@@ -68,6 +72,8 @@ chosen {
stride = <(1600 * 2)>;
format = "r5g6b5";
clocks = <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>;
+ num-supplies = <1>;
+ vin0-supply = <®_dc1sw>;
display = <&lcdc0>;
};
stdout-path = "display0";
--
2.5.3
^ permalink raw reply related
* [PATCH RFC 2/2] simplefb: Claim and enable regulators
From: Chen-Yu Tsai @ 2015-10-12 17:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1444669458-5588-1-git-send-email-wens@csie.org>
This claims and enables regulators listed in the simple framebuffer dt
node. This is needed so that regulators powering the display pipeline
and external hardware, described in the device node and known by the
kernel code, will remain properly enabled.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/video/fbdev/simplefb.c | 102 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 101 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 52c5c7e63b52..b2e419d9be3d 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -28,7 +28,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/regulator/consumer.h>
static struct fb_fix_screeninfo simplefb_fix = {
.id = "simple",
@@ -174,6 +176,10 @@ struct simplefb_par {
int clk_count;
struct clk **clks;
#endif
+#if defined CONFIG_OF && defined CONFIG_REGULATOR
+ u32 regulator_count;
+ struct regulator **regulators;
+#endif
};
#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
@@ -269,6 +275,93 @@ static int simplefb_clocks_init(struct simplefb_par *par,
static void simplefb_clocks_destroy(struct simplefb_par *par) { }
#endif
+#if defined CONFIG_OF && defined CONFIG_REGULATOR
+/*
+ * Regulator handling code.
+ *
+ * Here we handle the num-supplies and vin*-supply properties of our
+ * "simple-framebuffer" dt node. This is necessary so that we can make sure
+ * that any regulators needed by the display hardware that the bootloader
+ * set up for us (and for which it provided a simplefb dt node), stay up,
+ * for the life of the simplefb driver.
+ *
+ * When the driver unloads, we cleanly disable, and then release the
+ * regulators.
+ *
+ * We only complain about errors here, no action is taken as the most likely
+ * error can only happen due to a mismatch between the bootloader which set
+ * up simplefb, and the regulator definitions in the device tree. Chances are
+ * that there are no adverse effects, and if there are, a clean teardown of
+ * the fb probe will not help us much either. So just complain and carry on,
+ * and hope that the user actually gets a working fb at the end of things.
+ */
+static int simplefb_regulators_init(struct simplefb_par *par,
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct regulator *regulator;
+ int i, ret;
+
+ if (dev_get_platdata(&pdev->dev) || !np)
+ return 0;
+
+ ret = of_property_read_u32(np, "num-supplies", &par->regulator_count);
+ if (ret < 0)
+ return 0;
+
+ par->regulators = devm_kcalloc(&pdev->dev, par->regulator_count,
+ sizeof(struct regulator *), GFP_KERNEL);
+ if (!par->regulators)
+ return -ENOMEM;
+
+ for (i = 0; i < par->regulator_count; i++) {
+ char name[8];
+
+ snprintf(name, sizeof(name), "vin%d", i);
+ regulator = devm_regulator_get_optional(&pdev->dev, name);
+ if (IS_ERR(regulator)) {
+ if (PTR_ERR(regulator) = -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_err(&pdev->dev, "%s: regulator %d not found: %ld\n",
+ __func__, i, PTR_ERR(regulator));
+ continue;
+ }
+ par->regulators[i] = regulator;
+ }
+
+ for (i = 0; i < par->regulator_count; i++) {
+ if (par->regulators[i]) {
+ ret = regulator_enable(par->regulators[i]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: failed to enable regulator %d: %d\n",
+ __func__, i, ret);
+ devm_regulator_put(par->regulators[i]);
+ par->regulators[i] = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void simplefb_regulators_destroy(struct simplefb_par *par)
+{
+ int i;
+
+ if (!par->regulators)
+ return;
+
+ for (i = 0; i < par->regulator_count; i++)
+ if (par->regulators[i])
+ regulator_disable(par->regulators[i]);
+}
+#else
+static int simplefb_regulators_init(struct simplefb_par *par,
+ struct platform_device *pdev) { return 0; }
+static void simplefb_regulators_destroy(struct simplefb_par *par) { }
+#endif
+
static int simplefb_probe(struct platform_device *pdev)
{
int ret;
@@ -340,6 +433,10 @@ static int simplefb_probe(struct platform_device *pdev)
if (ret < 0)
goto error_unmap;
+ ret = simplefb_regulators_init(par, pdev);
+ if (ret < 0)
+ goto error_clocks;
+
dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
info->fix.smem_start, info->fix.smem_len,
info->screen_base);
@@ -351,13 +448,15 @@ static int simplefb_probe(struct platform_device *pdev)
ret = register_framebuffer(info);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
- goto error_clocks;
+ goto error_regulators;
}
dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
return 0;
+error_regulators:
+ simplefb_regulators_destroy(par);
error_clocks:
simplefb_clocks_destroy(par);
error_unmap:
@@ -373,6 +472,7 @@ static int simplefb_remove(struct platform_device *pdev)
struct simplefb_par *par = info->par;
unregister_framebuffer(info);
+ simplefb_regulators_destroy(par);
simplefb_clocks_destroy(par);
framebuffer_release(info);
--
2.5.3
^ permalink raw reply related
* Re: [PATCH RFC 1/2] dt-bindings: simplefb: Support a list of regulator supply properties
From: Mark Rutland @ 2015-10-12 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1444669458-5588-2-git-send-email-wens@csie.org>
On Tue, Oct 13, 2015 at 01:04:17AM +0800, Chen-Yu Tsai wrote:
> The physical display tied to the framebuffer may have regulators
> providing power to it, such as power for LCDs or interface conversion
> chips.
>
> The number of regulators in use may vary, but the regulator supply
> binding can not be a list. Work around this by adding a "num-supplies"
> property to communicate the number of supplies, and a list of 0 ~ N
> "vinN-supply" properties for the actual regulator supply.
This is getting more complicated by the minute...
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> .../devicetree/bindings/video/simple-framebuffer.txt | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
> index 4474ef6e0b95..0cc43e1be8b5 100644
> --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
> +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
> @@ -47,10 +47,14 @@ Required properties:
> - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
>
> Optional properties:
> -- clocks : List of clocks used by the framebuffer. Clocks listed here
> - are expected to already be configured correctly. The OS must
> - ensure these clocks are not modified or disabled while the
> - simple framebuffer remains active.
> +- clocks : List of clocks used by the framebuffer.
> +- num-supplies : The number of regulators used by the framebuffer.
> +- vinN-supply : The N-th (from 0) regulator used by the framebuffer.
I don't see why you need num-supplies. Why not just try probing
vin${N}-supply until such a property isn't present in the DT?
Thanks,
Mark.
^ permalink raw reply
* Re: [PATCH v2] backlight: pwm: reject legacy pwm request for device defined in dt
From: Robert Jarzmik @ 2015-10-12 17:11 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Boris Brezillon, Nicolas Ferre, Thierry Reding, Lee Jones,
Jingoo Han, linux-pwm, linux-fbdev
In-Reply-To: <561BD282.70305@mentor.com>
Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> writes:
> Sounds good, thank you for review.
>
>
> Robert,
>
> because you found a regression in the related area of code on a
> platform, which uses legacy PWM API, could you please confirm that three
> patches applied in a row don't break anything for you, the changes are:
>
> * Nicolas' 68feaca0b1 ("backlight: pwm: Handle EPROBE_DEFER while
> requesting the PWM")
> * Thierry' https://lkml.org/lkml/2015/10/5/319
> * and this one is the last in the series:
> http://thread.gmane.org/gmane.linux.pwm/2813
>
> --
> With best wishes,
> Vladimir
Of course, on my way.
Cheers.
--
Robert
^ permalink raw reply
* Re: [PATCH v3] video: fbdev: add Marvell PXA LCD controller binding
From: Philipp Zabel @ 2015-10-12 18:41 UTC (permalink / raw)
To: Robert Jarzmik
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
devicetree, LKML, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, linux-fbdev
In-Reply-To: <1444649423-25369-1-git-send-email-robert.jarzmik@free.fr>
On Mon, Oct 12, 2015 at 1:30 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
> Add documentation for the PXA LCD controller devicetree binding.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Reviewed-by: Philipp Zabel <philipp.zabel@gmail.com>
regards
Philipp
^ permalink raw reply
* [PATCH 0/3] delete unneeded of_node_put
From: Julia Lawall @ 2015-10-12 20:43 UTC (permalink / raw)
To: linux-arm-kernel
Device node iterators perform an of_node_put on each iteration, so putting
an of_node_put before going around to the next iteration results in a
double put.
The complete semantic patch that fixes this problem is as follows
(http://coccinelle.lip6.fr):
// <smpl>
@r exists@
expression e1,e2;
local idexpression n;
iterator name for_each_node_by_name, for_each_node_by_type,
for_each_compatible_node, for_each_matching_node,
for_each_matching_node_and_match, for_each_child_of_node,
for_each_available_child_of_node, for_each_node_with_property;
iterator i;
position p1,p2;
statement S;
@@
(
(
for_each_node_by_name(n,e1) S
|
for_each_node_by_type(n,e1) S
|
for_each_compatible_node(n,e1,e2) S
|
for_each_matching_node(n,e1) S
|
for_each_matching_node_and_match(n,e1,e2) S
|
for_each_child_of_node(e1,n) S
|
for_each_available_child_of_node(e1,n) S
|
for_each_node_with_property(n,e1) S
)
&
i@p1(...) {
... when != of_node_get(n)
when any
of_node_put@p2(n);
... when any
}
)
@s exists@
local idexpression r.n;
statement S;
position r.p1,r.p2;
iterator i;
@@
of_node_put@p2(n);
... when any
i@p1(..., n, ...)
S
@depends on s@
local idexpression n;
position r.p2;
@@
- of_node_put@p2(n);
// </smpl>
---
arch/arm/mach-exynos/pm_domains.c | 8 +++-----
drivers/soc/qcom/smd.c | 4 +---
drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 4 +---
3 files changed, 5 insertions(+), 11 deletions(-)
^ permalink raw reply
* [PATCH 1/3] video: omapdss: delete unneeded of_node_put
From: Julia Lawall @ 2015-10-12 20:43 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: kernel-janitors, Jean-Christophe Plagniol-Villard, linux-omap,
linux-fbdev, linux-kernel, Russell King - ARM Linux,
Thomas Petazzoni, Andrew Lunn, Bjorn Helgaas, Jason Cooper
In-Reply-To: <1444682596-3065-1-git-send-email-Julia.Lawall@lip6.fr>
Device node iterators perform an of_node_put on each iteration, so putting
an of_node_put before a continue results in a double put.
A simplified version of the semantic match that finds this problem is as
follows (http://coccinelle.lip6.fr):
// <smpl>
@@
expression root,e;
local idexpression child;
iterator i;
@@
i(..., child, ...) {
... when != of_node_get(child)
* of_node_put(child);
...
* continue;
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
index 8b6f6d5..136d304 100644
--- a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
+++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
@@ -199,10 +199,8 @@ static int __init omapdss_boot_init(void)
omapdss_walk_device(dss, true);
for_each_available_child_of_node(dss, child) {
- if (!of_find_property(child, "compatible", NULL)) {
- of_node_put(child);
+ if (!of_find_property(child, "compatible", NULL))
continue;
- }
omapdss_walk_device(child, true);
}
^ permalink raw reply related
* Re: [PATCH RFC 1/2] dt-bindings: simplefb: Support a list of regulator supply properties
From: Chen-Yu Tsai @ 2015-10-13 2:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20151012171018.GB3659@leverpostej>
On Tue, Oct 13, 2015 at 1:10 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Oct 13, 2015 at 01:04:17AM +0800, Chen-Yu Tsai wrote:
>> The physical display tied to the framebuffer may have regulators
>> providing power to it, such as power for LCDs or interface conversion
>> chips.
>>
>> The number of regulators in use may vary, but the regulator supply
>> binding can not be a list. Work around this by adding a "num-supplies"
>> property to communicate the number of supplies, and a list of 0 ~ N
>> "vinN-supply" properties for the actual regulator supply.
>
> This is getting more complicated by the minute...
Yeah...
I considered "backlight" and "panel" properties, but that seems to need
more effort to parse. Regulators seemed easier.
>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>> .../devicetree/bindings/video/simple-framebuffer.txt | 14 ++++++++++----
>> 1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>> index 4474ef6e0b95..0cc43e1be8b5 100644
>> --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>> +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>> @@ -47,10 +47,14 @@ Required properties:
>> - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
>>
>> Optional properties:
>> -- clocks : List of clocks used by the framebuffer. Clocks listed here
>> - are expected to already be configured correctly. The OS must
>> - ensure these clocks are not modified or disabled while the
>> - simple framebuffer remains active.
>> +- clocks : List of clocks used by the framebuffer.
>> +- num-supplies : The number of regulators used by the framebuffer.
>> +- vinN-supply : The N-th (from 0) regulator used by the framebuffer.
>
> I don't see why you need num-supplies. Why not just try probing
> vin${N}-supply until such a property isn't present in the DT?
That's doable. Though I'd add a hard limit on it. Does 16 seem reasonable?
Thanks
ChenYu
^ permalink raw reply
* [PATCH] video: fbdev: fsl: Split DIU initialization entry
From: Dongsheng Wang @ 2015-10-13 4:09 UTC (permalink / raw)
To: linux-fbdev
From: Wang Dongsheng <dongsheng.wang@freescale.com>
Split diu initialize from fsl_diu_init into diu probe function, because
it should be initialized when get the diu device tree node, not always
do initialization.
Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index b335c1a..1969863 100644
--- a/drivers/video/fbdev/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
@@ -1687,6 +1687,104 @@ static ssize_t show_monitor(struct device *device,
return 0;
}
+#ifndef MODULE
+static int __init fsl_diu_setup(char *options)
+{
+ char *opt;
+ unsigned long val;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+ if (!strncmp(opt, "monitor=", 8)) {
+ monitor_port = fsl_diu_name_to_port(opt + 8);
+ } else if (!strncmp(opt, "bpp=", 4)) {
+ if (!kstrtoul(opt + 4, 10, &val))
+ default_bpp = val;
+ } else {
+ fb_mode = opt;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int fsl_diu_perpare(void)
+{
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ struct device_node *np;
+ const u32 *prop;
+#endif
+#ifndef MODULE
+ char *option;
+#endif
+
+ if (!diu_ops.set_pixel_clock)
+ return -ENODEV;
+
+#ifndef MODULE
+ /*
+ * For kernel boot options (in 'video=xxxfb:<options>' format)
+ */
+ if (fb_get_options("fslfb", &option))
+ return -ENODEV;
+ fsl_diu_setup(option);
+#else
+ monitor_port = fsl_diu_name_to_port(monitor_string);
+#endif
+ pr_info("Freescale Display Interface Unit (DIU) framebuffer driver\n");
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ np = of_find_node_by_type(NULL, "cpu");
+ if (!np) {
+ pr_err("fsl-diu-fb: can't find 'cpu' device node\n");
+ return -ENODEV;
+ }
+
+ prop = of_get_property(np, "d-cache-size", NULL);
+ if (!prop) {
+ pr_err("fsl-diu-fb: missing 'd-cache-size'\n");
+ of_node_put(np);
+ return -ENODEV;
+ }
+
+ /*
+ * Freescale PLRU requires 13/8 times the cache size to do a proper
+ * displacement flush
+ */
+ coherence_data_size = be32_to_cpup(prop) * 13;
+ coherence_data_size /= 8;
+
+ pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
+ coherence_data_size);
+
+ prop = of_get_property(np, "d-cache-line-size", NULL);
+ if (!prop) {
+ pr_err("fsl-diu-fb: missing 'd-cache-line-size'\n");
+ of_node_put(np);
+ return -ENODEV;
+ }
+ d_cache_line_size = be32_to_cpup(prop);
+
+ pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
+ d_cache_line_size);
+
+ of_node_put(np);
+ coherence_data = vmalloc(coherence_data_size);
+ if (!coherence_data) {
+ pr_err("fsl-diu-fb: could not allocate coherence data\n");
+ pr_err("coherence_data_size=%zu)\n", coherence_data_size);
+ return -ENOMEM;
+ }
+
+#endif
+ return 0;
+}
+
static int fsl_diu_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -1697,10 +1795,16 @@ static int fsl_diu_probe(struct platform_device *pdev)
unsigned int i;
int ret;
+ ret = fsl_diu_perpare();
+ if (ret)
+ goto out_diu_perpare;
+
data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
&dma_addr, GFP_DMA | __GFP_ZERO);
- if (!data)
- return -ENOMEM;
+ if (!data) {
+ ret = -ENOMEM;
+ goto out_diu_perpare;
+ }
data->dma_addr = dma_addr;
/*
@@ -1826,6 +1930,11 @@ error:
iounmap(data->diu_reg);
+out_diu_perpare:
+#if defined(CONFIG_NOT_COHERENT_CACHE)
+ if (coherence_data)
+ vfree(coherence_data);
+#endif
return ret;
}
@@ -1844,34 +1953,12 @@ static int fsl_diu_remove(struct platform_device *pdev)
iounmap(data->diu_reg);
+#if defined(CONFIG_NOT_COHERENT_CACHE)
+ vfree(coherence_data);
+#endif
return 0;
}
-#ifndef MODULE
-static int __init fsl_diu_setup(char *options)
-{
- char *opt;
- unsigned long val;
-
- if (!options || !*options)
- return 0;
-
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
- if (!strncmp(opt, "monitor=", 8)) {
- monitor_port = fsl_diu_name_to_port(opt + 8);
- } else if (!strncmp(opt, "bpp=", 4)) {
- if (!kstrtoul(opt + 4, 10, &val))
- default_bpp = val;
- } else
- fb_mode = opt;
- }
-
- return 0;
-}
-#endif
-
static struct of_device_id fsl_diu_match[] = {
#ifdef CONFIG_PPC_MPC512x
{
@@ -1898,88 +1985,12 @@ static struct platform_driver fsl_diu_driver = {
static int __init fsl_diu_init(void)
{
-#ifdef CONFIG_NOT_COHERENT_CACHE
- struct device_node *np;
- const u32 *prop;
-#endif
- int ret;
-#ifndef MODULE
- char *option;
-
- /*
- * For kernel boot options (in 'video=xxxfb:<options>' format)
- */
- if (fb_get_options("fslfb", &option))
- return -ENODEV;
- fsl_diu_setup(option);
-#else
- monitor_port = fsl_diu_name_to_port(monitor_string);
-#endif
- pr_info("Freescale Display Interface Unit (DIU) framebuffer driver\n");
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
- np = of_find_node_by_type(NULL, "cpu");
- if (!np) {
- pr_err("fsl-diu-fb: can't find 'cpu' device node\n");
- return -ENODEV;
- }
-
- prop = of_get_property(np, "d-cache-size", NULL);
- if (prop = NULL) {
- pr_err("fsl-diu-fb: missing 'd-cache-size' property' "
- "in 'cpu' node\n");
- of_node_put(np);
- return -ENODEV;
- }
-
- /*
- * Freescale PLRU requires 13/8 times the cache size to do a proper
- * displacement flush
- */
- coherence_data_size = be32_to_cpup(prop) * 13;
- coherence_data_size /= 8;
-
- pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
- coherence_data_size);
-
- prop = of_get_property(np, "d-cache-line-size", NULL);
- if (prop = NULL) {
- pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' "
- "in 'cpu' node\n");
- of_node_put(np);
- return -ENODEV;
- }
- d_cache_line_size = be32_to_cpup(prop);
-
- pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
- d_cache_line_size);
-
- of_node_put(np);
- coherence_data = vmalloc(coherence_data_size);
- if (!coherence_data) {
- pr_err("fsl-diu-fb: could not allocate coherence data "
- "(size=%zu)\n", coherence_data_size);
- return -ENOMEM;
- }
-
-#endif
-
- ret = platform_driver_register(&fsl_diu_driver);
- if (ret) {
- pr_err("fsl-diu-fb: failed to register platform driver\n");
-#if defined(CONFIG_NOT_COHERENT_CACHE)
- vfree(coherence_data);
-#endif
- }
- return ret;
+ return platform_driver_register(&fsl_diu_driver);
}
static void __exit fsl_diu_exit(void)
{
platform_driver_unregister(&fsl_diu_driver);
-#if defined(CONFIG_NOT_COHERENT_CACHE)
- vfree(coherence_data);
-#endif
}
module_init(fsl_diu_init);
--
2.1.0.27.g96db324
^ permalink raw reply related
* Re: [PATCH RFC 1/2] dt-bindings: simplefb: Support a list of regulator supply properties
From: Hans de Goede @ 2015-10-13 7:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGb2v651=uaHEQK4wpEQywgr311NSbqEvYkpsC5zSHPSFq-HHg@mail.gmail.com>
Hi,
On 13-10-15 04:22, Chen-Yu Tsai wrote:
> On Tue, Oct 13, 2015 at 1:10 AM, Mark Rutland <mark.rutland@arm.com> wrote:
>> On Tue, Oct 13, 2015 at 01:04:17AM +0800, Chen-Yu Tsai wrote:
>>> The physical display tied to the framebuffer may have regulators
>>> providing power to it, such as power for LCDs or interface conversion
>>> chips.
>>>
>>> The number of regulators in use may vary, but the regulator supply
>>> binding can not be a list. Work around this by adding a "num-supplies"
>>> property to communicate the number of supplies, and a list of 0 ~ N
>>> "vinN-supply" properties for the actual regulator supply.
>>
>> This is getting more complicated by the minute...
>
> Yeah...
>
> I considered "backlight" and "panel" properties, but that seems to need
> more effort to parse. Regulators seemed easier.
>
>>
>>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>>> ---
>>> .../devicetree/bindings/video/simple-framebuffer.txt | 14 ++++++++++----
>>> 1 file changed, 10 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>>> index 4474ef6e0b95..0cc43e1be8b5 100644
>>> --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>>> +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
>>> @@ -47,10 +47,14 @@ Required properties:
>>> - a8b8g8r8 (32-bit pixels, d[31:24]=a, d[23:16]=b, d[15:8]=g, d[7:0]=r).
>>>
>>> Optional properties:
>>> -- clocks : List of clocks used by the framebuffer. Clocks listed here
>>> - are expected to already be configured correctly. The OS must
>>> - ensure these clocks are not modified or disabled while the
>>> - simple framebuffer remains active.
>>> +- clocks : List of clocks used by the framebuffer.
>>> +- num-supplies : The number of regulators used by the framebuffer.
>>> +- vinN-supply : The N-th (from 0) regulator used by the framebuffer.
>>
>> I don't see why you need num-supplies. Why not just try probing
>> vin${N}-supply until such a property isn't present in the DT?
+1 for this.
> That's doable. Though I'd add a hard limit on it. Does 16 seem reasonable?
I would not add a hard limit to the binding, you can use a fixed array in
the code to make the code simpler. I would say 8 should be sufficient, since
the limit will only be in the code we can always bump it when we need to.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH RFC 0/2] simplefb: Add regulator handling support
From: Hans de Goede @ 2015-10-13 7:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1444669458-5588-1-git-send-email-wens@csie.org>
Hi,
On 12-10-15 19:04, Chen-Yu Tsai wrote:
> Hi everyone,
>
> This series adds regulator claiming and enabling support for simplefb.
>
> Sometimes the simplefb display output path consits of external conversion
> chips and/or LCD drivers and backlights. These devices normally have
> GPIOs to turn them on and/or bring them out of reset, and regulators
> supplying power to them.
>
> While the kernel does not touch unclaimed GPIOs, the regulator core
> happily disables unused regulators. Thus we need simplefb to claim
> and enable the regulators used throughout the display pipeline.
Ack for doing something like this (adding regulator support) to simplefb,
it makes sense to have this.
> Now the DT bindings don't support a list of regulators directly, so
> I'm working around it by having a "num-supplies" property to specify
> the number of supply properties to check, and name the actual supplies
> as "vinN-supply".
Hmm, I can see the need for a "supplies" property with a list of regulators
in other use-cases (e.g. the generic mmc-pwrseq driver) too. Now as discussed
we can simply do vin0-supply - vinN-supply properties and be done with it,
but maybe we need to actually add support for a generic "supplies" property ?
And if not then maybe we need a few generic helper devm helper function which
takes a node, figures out how much vinN-supply properties there are and returns
a dynamically allocated array containing references to all the regulators, or
a PTR_ERR in case of err, at which point the caller is expected to fail the
probe so that any successfully acquired regulators are released.
Mark, what are your thoughts on this ?
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v2] backlight: pwm: reject legacy pwm request for device defined in dt
From: Lee Jones @ 2015-10-13 7:29 UTC (permalink / raw)
To: Vladimir Zapolskiy
Cc: Boris Brezillon, Robert Jarzmik, Nicolas Ferre, Thierry Reding,
Jingoo Han, linux-pwm, linux-fbdev
In-Reply-To: <561BD282.70305@mentor.com>
On Mon, 12 Oct 2015, Vladimir Zapolskiy wrote:
> On 12.10.2015 18:19, Boris Brezillon wrote:
> > On Mon, 12 Oct 2015 17:19:35 +0300
> > Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> wrote:
> >>
> >>> Thierry's patch makes sure that EPROBE_DEFER is not returned when the
> >>> PWM device definition is not found using in the PWM lookup tables or
> >>> the DT definition,
> >>
> >> This is okay, but I'm interested in proper handling of cases other than
> >> EPROBE_DEFER. EPROBE_DEFER and the related issues are on your balance
> >> and I'm attempting to avoid interfering with it here :)
> >
> > I keep thinking we should fix all platforms using the ->pwm_id pdata
> > field to attach a PWM device to a PWM backlight instead of trying to
> > guess when falling back to the legacy API is acceptable...
> >
> >>
> >>> and in this case the pwm_bl code will fallback to
> >>> the legacy PWM API, which AFAICT is what you're trying to solve.
> >>
> >> Fallback must happen exclusively under (IS_ERR(pb->pwm) &&
> >> PTR_ERR(pb->pwm) != -EPROBE_DEFER && !pdev->dev.of_node) condition IMHO.
> >>
> >> Before EPROBE_DEFER appeared on the scene the condition was
> >> (IS_ERR(pb->pwm) && !pdev->dev.of_node).
> >>
> >> So, the question is if my change requires any updates or not from your
> >> point of view.
> >
> > ... but from a functional point of view your patch seems correct.
>
> Sounds good, thank you for review.
So should I take this patch, or not?
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH 1/5] backlight: 88pm860x_bl: add missing of_node_put
From: Lee Jones @ 2015-10-13 8:15 UTC (permalink / raw)
To: Julia Lawall
Cc: Jingoo Han, kernel-janitors, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, linux-fbdev, linux-kernel,
Russell King - ARM Linux, Thomas Petazzoni, Andrew Lunn,
Bjorn Helgaas, Jason Cooper
In-Reply-To: <1444480254-14399-2-git-send-email-Julia.Lawall@lip6.fr>
On Sat, 10 Oct 2015, Julia Lawall wrote:
> for_each_child_of_node performs an of_node_get on each iteration, so
> a break out of the loop requires an of_node_put.
>
> The semantic patch that fixes this problem is as follows
> (http://coccinelle.lip6.fr):
>
> // <smpl>
> @@
> expression root,e;
> local idexpression child;
> iterator name for_each_child_of_node;
> @@
>
> for_each_child_of_node(root, child) {
> ... when != of_node_put(child)
> when != e = child
> + of_node_put(child);
> ? break;
> ...
> }
> ... when != child
> // </smpl>
>
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
>
> ---
> drivers/video/backlight/88pm860x_bl.c | 1 +
> 1 file changed, 1 insertion(+)
Applied, thanks.
> diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
> index 2da5862..6d8dc2c 100644
> --- a/drivers/video/backlight/88pm860x_bl.c
> +++ b/drivers/video/backlight/88pm860x_bl.c
> @@ -180,6 +180,7 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,
> data->iset = PM8606_WLED_CURRENT(iset);
> of_property_read_u32(np, "marvell,88pm860x-pwm",
> &data->pwm);
> + of_node_put(np);
> break;
> }
> }
>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCHv4 3/3] devicetree: Add led-backlight binding
From: Lee Jones @ 2015-10-13 8:42 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jacek Anaszewski, Jingoo Han, linux-leds, linux-fbdev,
Andrew Lunn, devicetree
In-Reply-To: <1443605522-1118-4-git-send-email-tomi.valkeinen@ti.com>
On Wed, 30 Sep 2015, Tomi Valkeinen wrote:
> Add DT binding for led-backlight.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: devicetree@vger.kernel.org
> ---
> .../bindings/video/backlight/led-backlight.txt | 30 ++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/video/backlight/led-backlight.txt
>
> diff --git a/Documentation/devicetree/bindings/video/backlight/led-backlight.txt b/Documentation/devicetree/bindings/video/backlight/led-backlight.txt
> new file mode 100644
> index 000000000000..d4621d7414bc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/backlight/led-backlight.txt
> @@ -0,0 +1,30 @@
> +led-backlight bindings
Make this look like a heading, rather than just another binding.
I would expect to see "LED Backlight Bindings" or similar.
> +Required properties:
> + - compatible: "led-backlight"
> + - leds: phandle to a led OF node [0]
s/phandle/Phandle/
s/led/LED/
s/[0]/(See: ../leds/common.txt)
> + - brightness-levels: Array of distinct LED brightness levels. These
> + are in the range from 0 to 255, passed to the LED class driver.
> + - default-brightness-level: the default brightness level (index into the
s/the/The/
> + array defined by the "brightness-levels" property)
Tab this out, so:
- compatible : "led-backlight"
- leds : phandle to a led OF node [0]
- brightness-levels : Array of distinct LED brightness levels. These
are in the range from 0 to 255, passed to the LED class driver.
- default-brightness-level : the default brightness level (index into the
array defined by the "brightness-levels" property)
Etc.
> +Optional properties:
> + - power-supply: regulator for supply voltage
s/regulator/Regulator/
> + - enable-gpios: contains a single GPIO specifier for the GPIO which enables
s/contains/Contains/
> + and disables the backlight (see GPIO binding[1])
s/[1]/(See: ../gpio/gpio.txt)
> +[0]: Documentation/devicetree/bindings/leds/common.txt
> +[1]: Documentation/devicetree/bindings/gpio/gpio.txt
Remove these.
> +Example:
> +
> + backlight {
> + compatible = "led-backlight";
> + leds = <&backlight_led>;
> +
> + brightness-levels = <0 4 8 16 32 64 128 255>;
> + default-brightness-level = <6>;
> +
> + power-supply = <&vdd_bl_reg>;
> + enable-gpios = <&gpio 58 0>;
> + };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCHv4 2/3] backlight: add led-backlight driver
From: Lee Jones @ 2015-10-13 8:43 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jacek Anaszewski, Jingoo Han, linux-leds, linux-fbdev,
Andrew Lunn
In-Reply-To: <1443605522-1118-3-git-send-email-tomi.valkeinen@ti.com>
Jingoo?
On Wed, 30 Sep 2015, Tomi Valkeinen wrote:
> This patch adds a led-backlight driver (led_bl), which is similar to
> pwm_bl except the driver uses a LED class driver to adjust the
> brightness in the HW.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
> drivers/video/backlight/Kconfig | 7 ++
> drivers/video/backlight/Makefile | 1 +
> drivers/video/backlight/led_bl.c | 246 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 254 insertions(+)
> create mode 100644 drivers/video/backlight/led_bl.c
>
> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
> index 0505b796d743..d1336196aba2 100644
> --- a/drivers/video/backlight/Kconfig
> +++ b/drivers/video/backlight/Kconfig
> @@ -453,6 +453,13 @@ config BACKLIGHT_BD6107
> help
> If you have a Rohm BD6107 say Y to enable the backlight driver.
>
> +config BACKLIGHT_LED
> + tristate "Generic LED based Backlight Driver"
> + depends on LEDS_CLASS && OF
> + help
> + If you have a LCD backlight adjustable by LED class driver, say Y
> + to enable this driver.
> +
> endif # BACKLIGHT_CLASS_DEVICE
>
> endif # BACKLIGHT_LCD_SUPPORT
> diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
> index d67073f9d421..ecd321daee21 100644
> --- a/drivers/video/backlight/Makefile
> +++ b/drivers/video/backlight/Makefile
> @@ -54,3 +54,4 @@ obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
> obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
> obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
> obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
> +obj-$(CONFIG_BACKLIGHT_LED) += led_bl.o
> diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
> new file mode 100644
> index 000000000000..1befc8ce5964
> --- /dev/null
> +++ b/drivers/video/backlight/led_bl.c
> @@ -0,0 +1,246 @@
> +/*
> + * Copyright 2015 Texas Instruments
> + *
> + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
> + *
> + * Based on pwm_bl.c
> + *
> + * 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; version 2 of the License.
> + */
> +#include <linux/backlight.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/leds.h>
> +#include <linux/of_leds.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +
> +struct led_bl_data {
> + struct device *dev;
> + struct backlight_device *bl_dev;
> +
> + unsigned int *levels;
> + bool enabled;
> + struct regulator *power_supply;
> + struct gpio_desc *enable_gpio;
> +
> + struct led_classdev *led_cdev;
> +
> + unsigned int max_brightness;
> + unsigned int default_brightness;
> +};
> +
> +static void led_bl_set_brightness(struct led_bl_data *priv, int brightness)
> +{
> + int err;
> +
> + if (!priv->enabled) {
> + if (priv->power_supply) {
> + err = regulator_enable(priv->power_supply);
> +
> + if (err < 0)
> + dev_err(priv->dev,
> + "failed to enable power supply\n");
> + }
> +
> + if (priv->enable_gpio)
> + gpiod_set_value_cansleep(priv->enable_gpio, 1);
> + }
> +
> + led_set_brightness(priv->led_cdev, priv->levels[brightness]);
> +
> + priv->enabled = true;
> +}
> +
> +static void led_bl_power_off(struct led_bl_data *priv)
> +{
> + if (!priv->enabled)
> + return;
> +
> + led_set_brightness(priv->led_cdev, LED_OFF);
> +
> + if (priv->enable_gpio)
> + gpiod_set_value_cansleep(priv->enable_gpio, 0);
> +
> + if (priv->power_supply)
> + regulator_disable(priv->power_supply);
> +
> + priv->enabled = false;
> +}
> +
> +static int led_bl_update_status(struct backlight_device *bl)
> +{
> + struct led_bl_data *priv = bl_get_data(bl);
> + int brightness = bl->props.brightness;
> +
> + if (bl->props.power != FB_BLANK_UNBLANK ||
> + bl->props.fb_blank != FB_BLANK_UNBLANK ||
> + bl->props.state & BL_CORE_FBBLANK)
> + brightness = 0;
> +
> + if (brightness > 0)
> + led_bl_set_brightness(priv, brightness);
> + else
> + led_bl_power_off(priv);
> +
> + return 0;
> +}
> +
> +static const struct backlight_ops led_bl_ops = {
> + .update_status = led_bl_update_status,
> +};
> +
> +static int led_bl_parse_dt(struct device *dev,
> + struct led_bl_data *priv)
> +{
> + struct device_node *node = dev->of_node;
> + int num_levels;
> + u32 *levels;
> + u32 value;
> + int ret;
> +
> + if (!node)
> + return -ENODEV;
> +
> + num_levels = of_property_count_u32_elems(node, "brightness-levels");
> + if (num_levels < 0) {
> + dev_err(dev, "failed to find 'brightness-levels'\n");
> + return num_levels;
> + }
> +
> + levels = devm_kzalloc(dev, sizeof(u32) * num_levels, GFP_KERNEL);
> + if (!levels)
> + return -ENOMEM;
> +
> + ret = of_property_read_u32_array(node, "brightness-levels",
> + levels,
> + num_levels);
> + if (ret < 0) {
> + dev_err(dev, "failed to parse 'brightness-levels'\n");
> + return ret;
> + }
> +
> + ret = of_property_read_u32(node, "default-brightness-level", &value);
> + if (ret < 0) {
> + dev_err(dev, "failed to parse 'default-brightness-level'\n");
> + return ret;
> + }
> +
> + if (value >= num_levels) {
> + dev_err(dev, "invalid default-brightness-level\n");
> + return -EINVAL;
> + }
> +
> + priv->levels = levels;
> + priv->max_brightness = num_levels - 1;
> + priv->default_brightness = value;
> +
> + priv->led_cdev = of_led_get(node);
> + if (IS_ERR(priv->led_cdev)) {
> + dev_err(dev, "failed to get LED device\n");
> + return PTR_ERR(priv->led_cdev);
> + }
> +
> + return 0;
> +}
> +
> +static int led_bl_probe(struct platform_device *pdev)
> +{
> + struct backlight_properties props;
> + struct led_bl_data *priv;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, priv);
> +
> + priv->dev = &pdev->dev;
> +
> + ret = led_bl_parse_dt(&pdev->dev, priv);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "failed to parse DT data\n");
> + return ret;
> + }
> +
> + priv->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
> + GPIOD_OUT_LOW);
> + if (IS_ERR(priv->enable_gpio)) {
> + ret = PTR_ERR(priv->enable_gpio);
> + goto err;
> + }
> +
> + priv->power_supply = devm_regulator_get_optional(&pdev->dev, "power");
> + if (IS_ERR(priv->power_supply)) {
> + ret = PTR_ERR(priv->power_supply);
> +
> + if (ret = -ENODEV) {
> + priv->power_supply = NULL;
> + } else {
> + ret = PTR_ERR(priv->power_supply);
> + goto err;
> + }
> + }
> +
> + memset(&props, 0, sizeof(struct backlight_properties));
> + props.type = BACKLIGHT_RAW;
> + props.max_brightness = priv->max_brightness;
> + priv->bl_dev = backlight_device_register(dev_name(&pdev->dev),
> + &pdev->dev, priv, &led_bl_ops, &props);
> + if (IS_ERR(priv->bl_dev)) {
> + dev_err(&pdev->dev, "failed to register backlight\n");
> + ret = PTR_ERR(priv->bl_dev);
> + goto err;
> + }
> +
> + priv->bl_dev->props.brightness = priv->default_brightness;
> + backlight_update_status(priv->bl_dev);
> +
> + return 0;
> +
> +err:
> + if (priv->led_cdev)
> + led_put(priv->led_cdev);
> +
> + return ret;
> +}
> +
> +static int led_bl_remove(struct platform_device *pdev)
> +{
> + struct led_bl_data *priv = platform_get_drvdata(pdev);
> + struct backlight_device *bl = priv->bl_dev;
> +
> + backlight_device_unregister(bl);
> +
> + led_bl_power_off(priv);
> +
> + led_put(priv->led_cdev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id led_bl_of_match[] = {
> + { .compatible = "led-backlight" },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(of, led_bl_of_match);
> +
> +static struct platform_driver led_bl_driver = {
> + .driver = {
> + .name = "led-backlight",
> + .of_match_table = of_match_ptr(led_bl_of_match),
> + },
> + .probe = led_bl_probe,
> + .remove = led_bl_remove,
> +};
> +
> +module_platform_driver(led_bl_driver);
> +
> +MODULE_DESCRIPTION("LED based Backlight Driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:led-backlight");
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v2] backlight: pwm: reject legacy pwm request for device defined in dt
From: Robert Jarzmik @ 2015-10-13 9:21 UTC (permalink / raw)
To: Vladimir Zapolskiy, Lee Jones
Cc: Boris Brezillon, Nicolas Ferre, Thierry Reding, Jingoo Han,
linux-pwm, linux-fbdev
In-Reply-To: <561BD282.70305@mentor.com>
Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> writes:
> Robert,
>
> because you found a regression in the related area of code on a
> platform, which uses legacy PWM API, could you please confirm that three
> patches applied in a row don't break anything for you, the changes are:
>
> * Nicolas' 68feaca0b1 ("backlight: pwm: Handle EPROBE_DEFER while
> requesting the PWM")
> * Thierry' https://lkml.org/lkml/2015/10/5/319
> * and this one is the last in the series:
> http://thread.gmane.org/gmane.linux.pwm/2813
I confirm, my backlight works again with it :
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
Cheers.
--
Robert
^ permalink raw reply
* Re: [PATCHv4 3/3] devicetree: Add led-backlight binding
From: Rob Herring @ 2015-10-13 14:21 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jacek Anaszewski, Jingoo Han, Lee Jones, Linux LED Subsystem,
linux-fbdev@vger.kernel.org, Andrew Lunn,
devicetree@vger.kernel.org
In-Reply-To: <1443605522-1118-4-git-send-email-tomi.valkeinen@ti.com>
On Wed, Sep 30, 2015 at 4:32 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> Add DT binding for led-backlight.
Please use get_maintainers.pl.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: devicetree@vger.kernel.org
> ---
> .../bindings/video/backlight/led-backlight.txt | 30 ++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/video/backlight/led-backlight.txt
>
> diff --git a/Documentation/devicetree/bindings/video/backlight/led-backlight.txt b/Documentation/devicetree/bindings/video/backlight/led-backlight.txt
> new file mode 100644
> index 000000000000..d4621d7414bc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/backlight/led-backlight.txt
> @@ -0,0 +1,30 @@
> +led-backlight bindings
> +
> +Required properties:
> + - compatible: "led-backlight"
> + - leds: phandle to a led OF node [0]
Why do we need 2 levels of LED nodes?
> + - brightness-levels: Array of distinct LED brightness levels. These
> + are in the range from 0 to 255, passed to the LED class driver.
> + - default-brightness-level: the default brightness level (index into the
> + array defined by the "brightness-levels" property)
> +
> +Optional properties:
> + - power-supply: regulator for supply voltage
> + - enable-gpios: contains a single GPIO specifier for the GPIO which enables
> + and disables the backlight (see GPIO binding[1])
Why are all of these not part of the LED node pointed to by leds?
Describe the h/w, not what you want for a driver.
Rob
^ permalink raw reply
* Re: [PATCH v3] video: fbdev: add Marvell PXA LCD controller binding
From: Rob Herring @ 2015-10-13 18:48 UTC (permalink / raw)
To: Robert Jarzmik
Cc: Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Philipp Zabel,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
linux-fbdev@vger.kernel.org
In-Reply-To: <1444649423-25369-1-git-send-email-robert.jarzmik@free.fr>
On Mon, Oct 12, 2015 at 6:30 AM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
> Add documentation for the PXA LCD controller devicetree binding.
>
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> ---
> Since v1: Philipp's review on the whole binding
> Since v2: moved to display/, Philipp's and Rob's review
> dropped panel description, should be a simple panel with a
> lcd-type optional node that could be added to simple-panel.
Applied, thanks.
Rob
> ---
> .../bindings/display/marvell,pxa2xx-lcdc.txt | 34 ++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt
>
> diff --git a/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt
> new file mode 100644
> index 000000000000..309c47f25b87
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt
> @@ -0,0 +1,34 @@
> +PXA LCD Controller
> +------------------
> +
> +Required properties:
> + - compatible : one of these
> + "marvell,pxa2xx-lcdc",
> + "marvell,pxa270-lcdc",
> + "marvell,pxa300-lcdc"
> + - reg : should contain 1 register range (address and length).
> + - interrupts : framebuffer controller interrupt.
> + - clocks: phandle to input clocks
> +
> +Required nodes:
> + - port: connection to the LCD panel (see video-interfaces.txt)
> + This node must have its properties bus-width and remote-endpoint set.
> + If the panel is not a TFT color panel, then a "lcd-type" property in
> + the panel should specify the panel type.
> + This panel node should be in the board dts.
> +
> +Example:
> + lcd-controller@40500000 {
> + compatible = "marvell,pxa2xx-lcdc";
> + reg = <0x44000000 0x10000>;
> + interrupts = <17>;
> + clocks = <&clks CLK_LCD>;
> + status = "okay";
> +
> + port {
> + lcdc_out: endpoint {
> + remote-endpoint = <&panel_in>;
> + bus-width = <16>;
> + };
> + };
> + };
> --
> 2.1.4
>
^ permalink raw reply
* [PATCH v2 1/2] video: fbdev: pxafb: loosen the platform data bond
From: Robert Jarzmik @ 2015-10-13 19:34 UTC (permalink / raw)
To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
Cc: linux-fbdev, linux-kernel, Philipp Zabel, Robert Jarzmik
In order to prepare the transition to a mixed platform data and
device-tree initialization, remove all the platform data references all
over the driver.
Copy the platform data into the internal structure of the pxafb, and
only use this afterward.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/video/fbdev/pxafb.c | 54 ++++++++++++++++++++++++++++-----------------
drivers/video/fbdev/pxafb.h | 2 ++
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index 94813af97f09..ed4b1a5dc306 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -457,7 +457,7 @@ static int pxafb_adjust_timing(struct pxafb_info *fbi,
static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb);
- struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);
+ struct pxafb_mach_info *inf = fbi->inf;
int err;
if (inf->fixed_modes) {
@@ -1230,7 +1230,7 @@ static unsigned int __smart_timing(unsigned time_ns, unsigned long lcd_clk)
static void setup_smart_timing(struct pxafb_info *fbi,
struct fb_var_screeninfo *var)
{
- struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);
+ struct pxafb_mach_info *inf = fbi->inf;
struct pxafb_mode_info *mode = &inf->modes[0];
unsigned long lclk = clk_get_rate(fbi->clk);
unsigned t1, t2, t3, t4;
@@ -1258,14 +1258,13 @@ static void setup_smart_timing(struct pxafb_info *fbi,
static int pxafb_smart_thread(void *arg)
{
struct pxafb_info *fbi = arg;
- struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);
+ struct pxafb_mach_info *inf = fbi->inf;
if (!inf->smart_update) {
pr_err("%s: not properly initialized, thread terminated\n",
__func__);
return -EINVAL;
}
- inf = dev_get_platdata(fbi->dev);
pr_debug("%s(): task starting\n", __func__);
@@ -1788,11 +1787,11 @@ decode_mode:
fbi->video_mem_size = video_mem_size;
}
-static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)
+static struct pxafb_info *pxafb_init_fbinfo(struct device *dev,
+ struct pxafb_mach_info *inf)
{
struct pxafb_info *fbi;
void *addr;
- struct pxafb_mach_info *inf = dev_get_platdata(dev);
/* Alloc the pxafb_info and pseudo_palette in one step */
fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
@@ -1801,6 +1800,7 @@ static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)
memset(fbi, 0, sizeof(struct pxafb_info));
fbi->dev = dev;
+ fbi->inf = inf;
fbi->clk = clk_get(dev, NULL);
if (IS_ERR(fbi->clk)) {
@@ -1852,10 +1852,9 @@ static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)
}
#ifdef CONFIG_FB_PXA_PARAMETERS
-static int parse_opt_mode(struct device *dev, const char *this_opt)
+static int parse_opt_mode(struct device *dev, const char *this_opt,
+ struct pxafb_mach_info *inf)
{
- struct pxafb_mach_info *inf = dev_get_platdata(dev);
-
const char *name = this_opt+5;
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0;
@@ -1911,9 +1910,9 @@ done:
return 0;
}
-static int parse_opt(struct device *dev, char *this_opt)
+static int parse_opt(struct device *dev, char *this_opt,
+ struct pxafb_mach_info *inf)
{
- struct pxafb_mach_info *inf = dev_get_platdata(dev);
struct pxafb_mode_info *mode = &inf->modes[0];
char s[64];
@@ -1922,7 +1921,7 @@ static int parse_opt(struct device *dev, char *this_opt)
if (!strncmp(this_opt, "vmem:", 5)) {
video_mem_size = memparse(this_opt + 5, NULL);
} else if (!strncmp(this_opt, "mode:", 5)) {
- return parse_opt_mode(dev, this_opt);
+ return parse_opt_mode(dev, this_opt, inf);
} else if (!strncmp(this_opt, "pixclock:", 9)) {
mode->pixclock = simple_strtoul(this_opt+9, NULL, 0);
sprintf(s, "pixclock: %ld\n", mode->pixclock);
@@ -2011,7 +2010,8 @@ static int parse_opt(struct device *dev, char *this_opt)
return 0;
}
-static int pxafb_parse_options(struct device *dev, char *options)
+static int pxafb_parse_options(struct device *dev, char *options,
+ struct pxafb_mach_info *inf)
{
char *this_opt;
int ret;
@@ -2023,7 +2023,7 @@ static int pxafb_parse_options(struct device *dev, char *options)
/* could be made table driven or similar?... */
while ((this_opt = strsep(&options, ",")) != NULL) {
- ret = parse_opt(dev, this_opt);
+ ret = parse_opt(dev, this_opt, inf);
if (ret)
return ret;
}
@@ -2095,19 +2095,33 @@ static void pxafb_check_options(struct device *dev, struct pxafb_mach_info *inf)
static int pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
- struct pxafb_mach_info *inf;
+ struct pxafb_mach_info *inf, *pdata;
struct resource *r;
- int irq, ret;
+ int i, irq, ret;
dev_dbg(&dev->dev, "pxafb_probe\n");
- inf = dev_get_platdata(&dev->dev);
ret = -ENOMEM;
- fbi = NULL;
+ pdata = dev_get_platdata(&dev->dev);
+ inf = devm_kmalloc(&dev->dev, sizeof(*inf), GFP_KERNEL);
if (!inf)
goto failed;
+ if (pdata) {
+ *inf = *pdata;
+ inf->modes + devm_kmalloc_array(&dev->dev, pdata->num_modes,
+ sizeof(inf->modes[0]), GFP_KERNEL);
+ if (!inf->modes)
+ goto failed;
+ for (i = 0; i < inf->num_modes; i++)
+ inf->modes[i] = pdata->modes[i];
+ }
+
+ fbi = NULL;
+ if (!pdata)
+ goto failed;
- ret = pxafb_parse_options(&dev->dev, g_options);
+ ret = pxafb_parse_options(&dev->dev, g_options, inf);
if (ret < 0)
goto failed;
@@ -2125,7 +2139,7 @@ static int pxafb_probe(struct platform_device *dev)
goto failed;
}
- fbi = pxafb_init_fbinfo(&dev->dev);
+ fbi = pxafb_init_fbinfo(&dev->dev, inf);
if (!fbi) {
/* only reason for pxafb_init_fbinfo to fail is kmalloc */
dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
diff --git a/drivers/video/fbdev/pxafb.h b/drivers/video/fbdev/pxafb.h
index 26ba9fa3f737..5dc414e26fc8 100644
--- a/drivers/video/fbdev/pxafb.h
+++ b/drivers/video/fbdev/pxafb.h
@@ -167,6 +167,8 @@ struct pxafb_info {
void (*lcd_power)(int, struct fb_var_screeninfo *);
void (*backlight_power)(int);
+
+ struct pxafb_mach_info *inf;
};
#define TO_INF(ptr,member) container_of(ptr,struct pxafb_info,member)
--
2.1.4
^ permalink raw reply related
* [PATCH v2 2/2] video: fbdev: pxafb: initial devicetree conversion
From: Robert Jarzmik @ 2015-10-13 19:34 UTC (permalink / raw)
To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
Cc: linux-fbdev, linux-kernel, Philipp Zabel, Robert Jarzmik
In-Reply-To: <1444764869-24893-1-git-send-email-robert.jarzmik@free.fr>
This patch brings a first support of pxa framebuffer devices to a
devicetree pxa platform, as was before platform data.
There are restrictions with this port, the biggest one being the lack of
support of smart panels. Moreover the conversion doesn't provide a way
to declare multiple framebuffer configurations with different bits per
pixel, only the LCD hardware bus width is used.
The patch was tested on both pxa25x, pxa27x and pxa3xx platform (namely
lubbock, mainstone and zylonite).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
Since v1: Philipp's review: of_graph usage
---
drivers/video/fbdev/Kconfig | 2 +
drivers/video/fbdev/pxafb.c | 162 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 161 insertions(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 8b1d371b5404..1a24ca5a0624 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1878,6 +1878,8 @@ config FB_PXA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VIDEOMODE_HELPERS if OF
+ select FB_MODE_HELPERS if OF
---help---
Frame buffer driver for the built-in LCD controller in the Intel
PXA2x0 processor.
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index ed4b1a5dc306..8588dd683105 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -55,6 +55,9 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/console.h>
+#include <linux/of_graph.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
#include <mach/hardware.h>
#include <asm/io.h>
@@ -2092,6 +2095,151 @@ static void pxafb_check_options(struct device *dev, struct pxafb_mach_info *inf)
#define pxafb_check_options(...) do {} while (0)
#endif
+#if defined(CONFIG_OF)
+static const char * const lcd_types[] = {
+ "unknown", "mono-stn", "mono-dstn", "color-stn", "color-dstn",
+ "color-tft", "smart-panel", NULL
+};
+
+static int of_get_pxafb_display(struct device *dev, struct device_node *disp,
+ struct pxafb_mach_info *info, u32 bus_width)
+{
+ struct display_timings *timings;
+ struct videomode vm;
+ int i, ret = -EINVAL;
+ const char *s;
+
+ ret = of_property_read_string(disp, "lcd-type", &s);
+ if (ret)
+ s = "color-tft";
+
+ for (i = 0; lcd_types[i]; i++)
+ if (!strcmp(s, lcd_types[i]))
+ break;
+ if (!i || !lcd_types[i]) {
+ dev_err(dev, "lcd-type %s is unknown\n", s);
+ return -EINVAL;
+ }
+ info->lcd_conn |= LCD_CONN_TYPE(i);
+ info->lcd_conn |= LCD_CONN_WIDTH(bus_width);
+
+ timings = of_get_display_timings(disp);
+ if (!timings)
+ goto out;
+
+ ret = -ENOMEM;
+ info->modes = kmalloc_array(timings->num_timings,
+ sizeof(info->modes[0]), GFP_KERNEL);
+ if (!info->modes)
+ goto out;
+ info->num_modes = timings->num_timings;
+
+ for (i = 0; i < timings->num_timings; i++) {
+ ret = videomode_from_timings(timings, &vm, i);
+ if (ret) {
+ dev_err(dev, "videomode_from_timings %d failed: %d\n",
+ i, ret);
+ goto out;
+ }
+ if (vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ info->lcd_conn |= LCD_PCLK_EDGE_RISE;
+ if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+ info->lcd_conn |= LCD_PCLK_EDGE_FALL;
+ if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
+ info->lcd_conn |= LCD_BIAS_ACTIVE_HIGH;
+ if (vm.flags & DISPLAY_FLAGS_DE_LOW)
+ info->lcd_conn |= LCD_BIAS_ACTIVE_LOW;
+ if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
+ info->modes[i].sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
+ info->modes[i].sync |= FB_SYNC_VERT_HIGH_ACT;
+
+ info->modes[i].pixclock = 1000000000UL / (vm.pixelclock / 1000);
+ info->modes[i].xres = vm.hactive;
+ info->modes[i].yres = vm.vactive;
+ info->modes[i].hsync_len = vm.hsync_len;
+ info->modes[i].left_margin = vm.hback_porch;
+ info->modes[i].right_margin = vm.hfront_porch;
+ info->modes[i].vsync_len = vm.vsync_len;
+ info->modes[i].upper_margin = vm.vback_porch;
+ info->modes[i].lower_margin = vm.vfront_porch;
+ }
+ ret = 0;
+
+out:
+ display_timings_release(timings);
+ return ret;
+}
+
+static int of_get_pxafb_mode_info(struct device *dev,
+ struct pxafb_mach_info *info)
+{
+ struct device_node *display, *np;
+ u32 bus_width, depth = 0;
+ int ret, i;
+
+ of_property_read_u32(dev->of_node, "depth", &depth);
+ np = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (!np) {
+ dev_err(dev, "could not find endpoint\n");
+ return -EINVAL;
+ }
+ ret = of_property_read_u32(np, "bus-width", &bus_width);
+ if (ret) {
+ dev_err(dev, "no bus-width specified: %d\n", ret);
+ return ret;
+ }
+
+ display = of_graph_get_remote_port_parent(np);
+ of_node_put(np);
+ if (!display) {
+ dev_err(dev, "no display defined\n");
+ return -EINVAL;
+ }
+
+ ret = of_get_pxafb_display(dev, display, info, bus_width);
+ of_node_put(display);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < info->num_modes; i++) {
+ info->modes[i].depth = depth;
+ info->modes[i].bpp = bus_width;
+ }
+
+ return 0;
+}
+
+static struct pxafb_mach_info *of_pxafb_of_mach_info(struct device *dev)
+{
+ int ret;
+ struct pxafb_mach_info *info;
+
+ if (!dev->of_node)
+ return NULL;
+ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+ ret = of_get_pxafb_mode_info(dev, info);
+ if (ret) {
+ kfree(info->modes);
+ return ERR_PTR(ret);
+ }
+
+ /*
+ * On purpose, neither lccrX registers nor video memory size can be
+ * specified through device-tree, they are considered more a debug hack
+ * available through command line.
+ */
+ return info;
+}
+#else
+static struct pxafb_mach_info *of_pxafb_of_mach_info(struct device *dev)
+{
+ return NULL;
+}
+#endif
+
static int pxafb_probe(struct platform_device *dev)
{
struct pxafb_info *fbi;
@@ -2104,8 +2252,7 @@ static int pxafb_probe(struct platform_device *dev)
ret = -ENOMEM;
pdata = dev_get_platdata(&dev->dev);
inf = devm_kmalloc(&dev->dev, sizeof(*inf), GFP_KERNEL);
- if (!inf)
- goto failed;
+
if (pdata) {
*inf = *pdata;
inf->modes @@ -2117,8 +2264,9 @@ static int pxafb_probe(struct platform_device *dev)
inf->modes[i] = pdata->modes[i];
}
- fbi = NULL;
if (!pdata)
+ inf = of_pxafb_of_mach_info(&dev->dev);
+ if (IS_ERR_OR_NULL(inf))
goto failed;
ret = pxafb_parse_options(&dev->dev, g_options, inf);
@@ -2313,11 +2461,19 @@ static int pxafb_remove(struct platform_device *dev)
return 0;
}
+static const struct of_device_id pxafb_of_dev_id[] = {
+ {
+ .compatible = "marvell,pxa2xx-lcdc",
+ },
+};
+MODULE_DEVICE_TABLE(of, pxafb_of_dev_id);
+
static struct platform_driver pxafb_driver = {
.probe = pxafb_probe,
.remove = pxafb_remove,
.driver = {
.name = "pxa2xx-fb",
+ .of_match_table = pxafb_of_dev_id,
#ifdef CONFIG_PM
.pm = &pxafb_pm_ops,
#endif
--
2.1.4
^ permalink raw reply related
* [GIT PULL] On-demand device probing
From: Tomeu Vizoso @ 2015-10-14 8:34 UTC (permalink / raw)
To: Rob Herring
Cc: Russell King, Greg Kroah-Hartman, Michael Turquette, Stephen Boyd,
Vinod Koul, Dan Williams, Linus Walleij, Alexandre Courbot,
Thierry Reding, David Airlie, Terje Bergström,
Stephen Warren, Wolfram Sang, Frank Rowand, Grant Likely,
Kishon Vijay Abraham I, Sebastian Reichel,
Dmitry Eremin-Solenikov, David Woodhouse, Liam Girdwood,
Mark Brown, Felipe Balbi
Hi Rob,
here is the pull request you asked for, with no changes from the version
that I posted last to the list.
The following changes since commit 6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f:
Linux 4.3-rc1 (2015-09-12 16:35:56 -0700)
are available in the git repository at:
git+ssh://git.collabora.co.uk/git/user/tomeu/linux.git
on-demand-probes-for-next
for you to fetch changes up to 587402133fe433759d2d535e5d92ead87fd7f615:
of/platform: Defer probes of registered devices (2015-10-14 10:08:23 +0200)
----------------------------------------------------------------
Tomeu Vizoso (20):
driver core: handle -EPROBE_DEFER from bus_type.match()
ARM: amba: Move reading of periphid to amba_match()
of/platform: Point to struct device from device node
of: add function to allow probing a device from a OF node
gpio: Probe GPIO drivers on demand
pinctrl: Probe pinctrl devices on demand
regulator: core: Probe regulators on demand
drm: Probe panels on demand
drm/tegra: Probe dpaux devices on demand
i2c: core: Probe i2c adapters and devices on demand
pwm: Probe PWM chip devices on demand
backlight: Probe backlight devices on demand
usb: phy: Probe phy devices on demand
clk: Probe clk providers on demand
pinctrl: Probe pinctrl devices on demand
phy: core: Probe phy providers on demand
dma: of: Probe DMA controllers on demand
power-supply: Probe power supplies on demand
driver core: Allow deferring probes until late init
of/platform: Defer probes of registered devices
drivers/amba/bus.c | 88
++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------
drivers/base/Kconfig | 18 ++++++++++++++++++
drivers/base/dd.c | 30 ++++++++++++++++++++++++++++--
drivers/clk/clk.c | 3 +++
drivers/dma/of-dma.c | 3 +++
drivers/gpio/gpiolib-of.c | 5 +++++
drivers/gpu/drm/drm_panel.c | 3 +++
drivers/gpu/drm/tegra/dpaux.c | 3 +++
drivers/i2c/i2c-core.c | 4 ++++
drivers/of/device.c | 61
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/of/platform.c | 30 ++++++++++++++++++------------
drivers/phy/phy-core.c | 3 +++
drivers/pinctrl/devicetree.c | 3 +++
drivers/power/power_supply_core.c | 3 +++
drivers/pwm/core.c | 3 +++
drivers/regulator/core.c | 2 ++
drivers/usb/phy/phy.c | 3 +++
drivers/video/backlight/backlight.c | 3 +++
include/linux/device.h | 4 +++-
include/linux/of.h | 1 +
include/linux/of_device.h | 3 +++
21 files changed, 219 insertions(+), 57 deletions(-)
Thanks,
Tomeu
^ permalink raw reply
* Re: [GIT PULL] On-demand device probing
From: Mark Brown @ 2015-10-14 9:26 UTC (permalink / raw)
To: Tomeu Vizoso
Cc: Rob Herring, Russell King, Greg Kroah-Hartman, Michael Turquette,
Stephen Boyd, Vinod Koul, Dan Williams, Linus Walleij,
Alexandre Courbot, Thierry Reding, David Airlie,
Terje Bergström, Stephen Warren, Wolfram Sang, Frank Rowand,
Grant Likely, Kishon Vijay Abraham I, Sebastian Reichel,
Dmitry Eremin-Solenikov, David Woodhouse, Liam Girdwood,
Felipe Balbi
In-Reply-To: <561E1378.6000906@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 242 bytes --]
On Wed, Oct 14, 2015 at 10:34:00AM +0200, Tomeu Vizoso wrote:
> git+ssh://git.collabora.co.uk/git/user/tomeu/linux.git
> on-demand-probes-for-next
In don't think that's the URL you intended to use (also everything looks
word wrapped here)?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply
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