* [PATCH v4 2/5] dt-bindings: Add a clocks property to the simple-framebuffer binding
From: Hans de Goede @ 2014-10-22 16:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1413996311-4287-1-git-send-email-hdegoede@redhat.com>
A simple-framebuffer node represents a framebuffer setup by the firmware /
bootloader. Such a framebuffer may have a number of clocks in use, add a
property to communicate this to the OS.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Mike Turquette <mturquette@linaro.org>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
--
Changes in v2:
-Added Reviewed-by: Mike Turquette <mturquette@linaro.org>
Changes in v3:
-Updated description to make clear simplefb deals with more then just memory
---
Documentation/devicetree/bindings/video/simple-framebuffer.txt | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
index 70c26f3..172ad5f 100644
--- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt
+++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt
@@ -1,8 +1,8 @@
Simple Framebuffer
-A simple frame-buffer describes a raw memory region that may be rendered to,
-with the assumption that the display hardware has already been set up to scan
-out from that buffer.
+A simple frame-buffer describes a frame-buffer setup by firmware or
+the bootloader, with the assumption that the display hardware has already
+been set up to scan out from the memory pointed to by the reg property.
Required properties:
- compatible: "simple-framebuffer"
@@ -14,6 +14,9 @@ Required properties:
- r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b).
- 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
+
Example:
framebuffer {
--
2.1.0
^ permalink raw reply related
* [PATCH v4 3/5] simplefb: formalize pseudo palette handling
From: Hans de Goede @ 2014-10-22 16:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1413996311-4287-1-git-send-email-hdegoede@redhat.com>
From: Luc Verhaegen <libv@skynet.be>
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Stephen Warren <swarren@nvidia.com>
[hdegoede@redhat.com: drop unnecessary void * cast]
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/video/fbdev/simplefb.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 210f3a0..ec112c1 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -41,6 +41,8 @@ static struct fb_var_screeninfo simplefb_var = {
.vmode = FB_VMODE_NONINTERLACED,
};
+#define PSEUDO_PALETTE_SIZE 16
+
static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
@@ -50,7 +52,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u32 cb = blue >> (16 - info->var.blue.length);
u32 value;
- if (regno >= 16)
+ if (regno >= PSEUDO_PALETTE_SIZE)
return -EINVAL;
value = (cr << info->var.red.offset) |
@@ -163,11 +165,16 @@ static int simplefb_parse_pd(struct platform_device *pdev,
return 0;
}
+struct simplefb_par {
+ u32 palette[PSEUDO_PALETTE_SIZE];
+};
+
static int simplefb_probe(struct platform_device *pdev)
{
int ret;
struct simplefb_params params;
struct fb_info *info;
+ struct simplefb_par *par;
struct resource *mem;
if (fb_get_options("simplefb", NULL))
@@ -188,11 +195,13 @@ static int simplefb_probe(struct platform_device *pdev)
return -EINVAL;
}
- info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
+ info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
if (!info)
return -ENOMEM;
platform_set_drvdata(pdev, info);
+ par = info->par;
+
info->fix = simplefb_fix;
info->fix.smem_start = mem->start;
info->fix.smem_len = resource_size(mem);
@@ -225,7 +234,7 @@ static int simplefb_probe(struct platform_device *pdev)
framebuffer_release(info);
return -ENODEV;
}
- info->pseudo_palette = (void *)(info + 1);
+ info->pseudo_palette = par->palette;
dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
info->fix.smem_start, info->fix.smem_len,
--
2.1.0
^ permalink raw reply related
* [PATCH v4 4/5] simplefb: add goto error path to probe
From: Hans de Goede @ 2014-10-22 16:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1413996311-4287-1-git-send-email-hdegoede@redhat.com>
From: Luc Verhaegen <libv@skynet.be>
While at it update ioremap_wc error return from ENODEV to ENOMEM.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
Acked-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/video/fbdev/simplefb.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index ec112c1..cdcf1fe 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -220,8 +220,8 @@ static int simplefb_probe(struct platform_device *pdev)
info->apertures = alloc_apertures(1);
if (!info->apertures) {
- framebuffer_release(info);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error_fb_release;
}
info->apertures->ranges[0].base = info->fix.smem_start;
info->apertures->ranges[0].size = info->fix.smem_len;
@@ -231,8 +231,8 @@ static int simplefb_probe(struct platform_device *pdev)
info->screen_base = ioremap_wc(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
- framebuffer_release(info);
- return -ENODEV;
+ ret = -ENOMEM;
+ goto error_fb_release;
}
info->pseudo_palette = par->palette;
@@ -247,14 +247,18 @@ 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);
- iounmap(info->screen_base);
- framebuffer_release(info);
- return ret;
+ goto error_unmap;
}
dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
return 0;
+
+error_unmap:
+ iounmap(info->screen_base);
+error_fb_release:
+ framebuffer_release(info);
+ return ret;
}
static int simplefb_remove(struct platform_device *pdev)
--
2.1.0
^ permalink raw reply related
* [PATCH v4 5/5] simplefb: add clock handling code
From: Hans de Goede @ 2014-10-22 16:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1413996311-4287-1-git-send-email-hdegoede@redhat.com>
From: Luc Verhaegen <libv@skynet.be>
This claims and enables clocks listed in the simple framebuffer dt node.
This is needed so that the display engine, in case the required clocks
are known by the kernel code and are described in the dt, will remain
properly enabled.
Signed-off-by: Luc Verhaegen <libv@skynet.be>
[hdegoede@redhat.com: Change clks from list to dynamic array]
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
--
Changes in v4:
-change clks from linkedlist to dynamic allocated array
-propagate EPROBE_DEFER up from simplefb_clocks_init to simplefb_probe
---
drivers/video/fbdev/simplefb.c | 101 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index cdcf1fe..cd96edd 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
static struct fb_fix_screeninfo simplefb_fix = {
.id = "simple",
@@ -167,8 +168,98 @@ static int simplefb_parse_pd(struct platform_device *pdev,
struct simplefb_par {
u32 palette[PSEUDO_PALETTE_SIZE];
+ int clk_count;
+ struct clk **clks;
};
+/*
+ * Clock handling code.
+ *
+ * Here we handle the clocks property of our "simple-framebuffer" dt node.
+ * This is necessary so that we can make sure that any clocks needed by
+ * the display engine 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 clocks.
+ *
+ * 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 clock 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_clocks_init(struct simplefb_par *par, struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct clk *clock;
+ int i, ret;
+
+ if (dev_get_platdata(&pdev->dev) || !np)
+ return 0;
+
+ par->clk_count = of_clk_get_parent_count(np);
+ if (par->clk_count <= 0)
+ return 0;
+
+ par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
+ if (!par->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < par->clk_count; i++) {
+ clock = of_clk_get(np, i);
+ if (IS_ERR(clock)) {
+ if (PTR_ERR(clock) = -EPROBE_DEFER) {
+ while (--i >= 0) {
+ if (par->clks[i])
+ clk_put(par->clks[i]);
+ }
+ kfree(par->clks);
+ return -EPROBE_DEFER;
+ }
+ dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
+ __func__, i, PTR_ERR(clock));
+ continue;
+ }
+ par->clks[i] = clock;
+ }
+
+ for (i = 0; i < par->clk_count; i++) {
+ if (par->clks[i]) {
+ ret = clk_prepare_enable(par->clks[i]);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: failed to enable clock %d: %d\n",
+ __func__, i, ret);
+ clk_put(par->clks[i]);
+ par->clks[i] = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void
+simplefb_clocks_destroy(struct simplefb_par *par)
+{
+ int i;
+
+ if (!par->clks)
+ return;
+
+ for (i = 0; i < par->clk_count; i++) {
+ if (par->clks[i]) {
+ clk_disable_unprepare(par->clks[i]);
+ clk_put(par->clks[i]);
+ }
+ }
+
+ kfree(par->clks);
+}
+
static int simplefb_probe(struct platform_device *pdev)
{
int ret;
@@ -236,6 +327,10 @@ static int simplefb_probe(struct platform_device *pdev)
}
info->pseudo_palette = par->palette;
+ ret = simplefb_clocks_init(par, pdev);
+ if (ret < 0)
+ goto error_unmap;
+
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);
@@ -247,13 +342,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_unmap;
+ goto error_clocks;
}
dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
return 0;
+error_clocks:
+ simplefb_clocks_destroy(par);
error_unmap:
iounmap(info->screen_base);
error_fb_release:
@@ -264,8 +361,10 @@ error_fb_release:
static int simplefb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
+ struct simplefb_par *par = info->par;
unregister_framebuffer(info);
+ simplefb_clocks_destroy(par);
framebuffer_release(info);
return 0;
--
2.1.0
^ permalink raw reply related
* Re: [PATCH] drivers: depend on instead of select BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO
From: Daniel Vetter @ 2014-10-23 8:10 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jean-Christophe Plagniol-Villard, linux-fbdev, Jingoo Han,
Daniel Drake, Jens Frederich, Jani Nikula, Greg Kroah-Hartman,
Jon Nettleton, linux-usb, linux-kernel, dri-devel,
platform-driver-x86, Randy Dunlap, Daniel Vetter, Darren Hart,
Bryan Wu, linuxppc-dev, Lee Jones, Laurent Pinchart
In-Reply-To: <54476492.6090105@ti.com>
On Wed, Oct 22, 2014 at 11:02:26AM +0300, Tomi Valkeinen wrote:
> On 18/10/14 00:13, Jani Nikula wrote:
> > Documentation/kbuild/kconfig-language.txt warns to use select with care,
> > and in general use select only for non-visible symbols and for symbols
> > with no dependencies, because select will force a symbol to a value
> > without visiting the dependencies.
> >
> > Select has become particularly problematic, interdependently, with the
> > BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO configs. For example:
> >
> > scripts/kconfig/conf --randconfig Kconfig
> > KCONFIG_SEED=0x48312B00
> > warning: (DRM_RADEON && DRM_NOUVEAU && DRM_I915 && DRM_GMA500 &&
> > DRM_SHMOBILE && DRM_TILCDC && FB_BACKLIGHT && FB_MX3 && USB_APPLEDISPLAY
> > && FB_OLPC_DCON && ASUS_LAPTOP && SONY_LAPTOP && THINKPAD_ACPI &&
> > EEEPC_LAPTOP && ACPI_CMPC && SAMSUNG_Q10) selects BACKLIGHT_CLASS_DEVICE
> > which has unmet direct dependencies (HAS_IOMEM && BACKLIGHT_LCD_SUPPORT)
> > warning: (DRM_RADEON && DRM_NOUVEAU && DRM_I915 && DRM_GMA500 &&
> > DRM_SHMOBILE && DRM_TILCDC && FB_BACKLIGHT && FB_MX3 && USB_APPLEDISPLAY
> > && FB_OLPC_DCON && ASUS_LAPTOP && SONY_LAPTOP && THINKPAD_ACPI &&
> > EEEPC_LAPTOP && ACPI_CMPC && SAMSUNG_Q10) selects BACKLIGHT_CLASS_DEVICE
> > which has unmet direct dependencies (HAS_IOMEM && BACKLIGHT_LCD_SUPPORT)
> >
> > With tristates it's possible to end up selecting FOO=y depending on
> > BAR=m in the config, which gets discovered at build time, not config
> > time, like reported in the thread referenced below.
> >
> > Do the following to fix the dependencies:
> >
> > * Depend on instead of select BACKLIGHT_CLASS_DEVICE everywhere. Drop
> > select BACKLIGHT_LCD_SUPPORT in such cases, as it's a dependency of
> > BACKLIGHT_CLASS_DEVICE.
> >
> > * Remove config FB_BACKLIGHT altogether, and replace it with a
> > dependency on BACKLIGHT_CLASS_DEVICE. All configs selecting
> > FB_BACKLIGHT select or depend on FB anyway, so we can simplify.
> >
> > * Depend on (ACPI && ACPI_VIDEO) || ACPI=n in several places instead of
> > selecting ACPI_VIDEO and a number of its dependencies if ACPI is
> > enabled. This is tied to backlight, as ACPI_VIDEO depends on
> > BACKLIGHT_CLASS_DEVICE.
> >
> > * Replace a couple of select INPUT/VT with depends as it seemed to be
> > necessary.
>
> While doing 'depends on' instead of 'select' is an "easy" fix for this,
> I do dislike it quite a bit. It's a major pain to go around the kernel
> config, trying to find all the dependencies that a particular driver
> wants. If I need fb-foobar, I should just be able to enable it, instead
> of first searching and selecting its minor dependencies individually.
>
> So, not a NACK, but a "isn't there an another way to fix this?".
>
> Looking at backlight... BACKLIGHT_LCD_SUPPORT seems to be a "meta"
> option, it only enables a Kconfig submenu.
>
> So I think we could just remove the whole BACKLIGHT_LCD_SUPPORT option.
> But if we do that, all the items in drivers/video/backlight/Kconfig with
> default 'y' or 'm' would get enabled by default, so I think we should
> remove the 'default's from that file. That makes sense in any case, as I
> don't see why "HP Jornada 700 series LCD Driver" should be "default y".
>
> BACKLIGHT_CLASS_DEVICE doesn't depend on anything except
> BACKLIGHT_LCD_SUPPORT, so after removing BACKLIGHT_LCD_SUPPORT it should
> be safe to 'select' BACKLIGHT_CLASS_DEVICE.
>
> BACKLIGHT_CLASS_DEVICE could be made a hidden option, and the drivers in
> drivers/video/backlight/Kconfig which are under BACKLIGHT_CLASS_DEVICE
> could be made to select BACKLIGHT_CLASS_DEVICE instead.
>
> That doesn't exactly fix anything, but I think it makes sense as
> BACKLIGHT_CLASS_DEVICE is something that's selected from all around the
> kernel, so it should be a selectable "library" instead of a Kconfig menu
> option.
>
> I didn't look at the ACPI_VIDEO side, so no idea how messy that is.
If we want to make BACKLIGHT_CLASS_DEVICE into a library thing then I
guess we could do that, but we must then also drag it out of all the other
meta options to make sure it's always available. No need I think to ditch
the entire BACKLIGHT_LCD_SUPPORT meta option. And then everyone could
select it.
The problem is if you mix depends and select Kconfig falls over and starts
to see loops where there are none. So you really can't ever mix them for
the same symbol.
I think if we get the BACKLIGHT_CLASS_DEVICE out of the picture with that
ACPI_VIDEO should be fixable with some
select ACPI_VIDEO if ACPI
or so. Currently that doesn't work because of the backlight class knob and
select being broken.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply
* Re: [PATCH] drivers: depend on instead of select BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO
From: Tomi Valkeinen @ 2014-10-23 11:38 UTC (permalink / raw)
To: Daniel Vetter
Cc: Jani Nikula, linux-kernel, dri-devel, linuxppc-dev,
platform-driver-x86, linux-usb, linux-fbdev, Jingoo Han,
Daniel Drake, Jens Frederich, Greg Kroah-Hartman, Jon Nettleton,
Randy Dunlap, Laurent Pinchart, Darren Hart, Daniel Vetter,
Bryan Wu, Jean-Christophe Plagniol-Villard, Lee Jones
In-Reply-To: <20141023081034.GA26941@phenom.ffwll.local>
[-- Attachment #1: Type: text/plain, Size: 857 bytes --]
On 23/10/14 11:10, Daniel Vetter wrote:
> If we want to make BACKLIGHT_CLASS_DEVICE into a library thing then I
> guess we could do that, but we must then also drag it out of all the other
> meta options to make sure it's always available. No need I think to ditch
BACKLIGHT_CLASS_DEVICE only depends on HAS_IOMEM and
BACKLIGHT_LCD_SUPPORT so there are no other meta options to avoid.
HAS_IOMEM comes from drivers/video/Kconfig's "Graphics support", and I
guess we can ignore it.
> the entire BACKLIGHT_LCD_SUPPORT meta option. And then everyone could
> select it.
I don't quite understand what purpose does BACKLIGHT_LCD_SUPPORT serve.
It doesn't enable any code, it just opens up new Kconfig options. Why
can't the Kconfig options be always available? It's just another option
to 'select', without any reason I can see.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH 0/5] arm: sa1100: fix sa1100 fb and pcmcia w/o cpufreq
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
These patches were sitting in my queue for some time. On SA-1100
framebuffer and PCMCIA drivers make use of cpufreq_get(0) function call
to determine the cpu frequency. Russell's commit
1937f5b91833e2e8e53bcc821fc7a5fbe6ccb9b5 (ARM: fix sa1100 build) fixed
the build issues, but broke two devices (Collie and Jornada720). For
those two boards the cpufreq code gets compiled but is not enabled (as
board files do not provide timing information for the CPUFREQ driver).
Thus cpufreq_get(0) returns incorrect values and incorrect timings get
programmed into the hardware.
PXA2xx (the very similar platform) uses Clock API to determine CPU
frequency both in framebuffer and PCMCIA drivers. These patches make
similar changes to StrongARM drivers.
These patches are required to make use of framebuffer and CF card on
Sharp Collie (and possibly on HP Jornada 720).
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH 1/5] arm: sa1100: add cpu clock
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1414147047-12892-1-git-send-email-dbaryshkov@gmail.com>
Both SA1100 framebuffer and PCMCIA drivers require knowledge of cpu
frequency to correctly program timings. Currently they receive timing
information by calling cpufreq_get(0). However if cpu frequency driver
is not enabled (e.g. due to unsupported DRAM chip/board on sa1110)
cpufreq_get(0) returns 0, causing incorrect timings to be programmed.
Add cpu clock returning cpu frequency, to be used by sa11x0 fb and
pcmcia drivers.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/clock.c | 41 ++++++++++++++++++++++++++++++++++-------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 9fa6a99..53f750d 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -15,10 +15,12 @@
#include <linux/clkdev.h>
#include <mach/hardware.h>
+#include <mach/generic.h>
struct clkops {
void (*enable)(struct clk *);
void (*disable)(struct clk *);
+ unsigned long (*get_rate)(struct clk *);
};
struct clk {
@@ -33,13 +35,6 @@ struct clk clk_##_name = { \
static DEFINE_SPINLOCK(clocks_lock);
-/* Dummy clk routine to build generic kernel parts that may be using them */
-unsigned long clk_get_rate(struct clk *clk)
-{
- return 0;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
static void clk_gpio27_enable(struct clk *clk)
{
/*
@@ -58,6 +53,19 @@ static void clk_gpio27_disable(struct clk *clk)
GAFR &= ~GPIO_32_768kHz;
}
+static void clk_cpu_enable(struct clk *clk)
+{
+}
+
+static void clk_cpu_disable(struct clk *clk)
+{
+}
+
+static unsigned long clk_cpu_get_rate(struct clk *clk)
+{
+ return sa11x0_getspeed(0) * 1000;
+}
+
int clk_enable(struct clk *clk)
{
unsigned long flags;
@@ -87,16 +95,35 @@ void clk_disable(struct clk *clk)
}
EXPORT_SYMBOL(clk_disable);
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk && clk->ops && clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
const struct clkops clk_gpio27_ops = {
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
+const struct clkops clk_cpu_ops = {
+ .enable = clk_cpu_enable,
+ .disable = clk_cpu_disable,
+ .get_rate = clk_cpu_get_rate,
+};
+
static DEFINE_CLK(gpio27, &clk_gpio27_ops);
+static DEFINE_CLK(cpu, &clk_cpu_ops);
+
static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
CLKDEV_INIT("sa1100-rtc", NULL, NULL),
+ CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
+ CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
};
static int __init sa11xx_clk_init(void)
--
2.1.1
^ permalink raw reply related
* [PATCH 2/5] arm: sa1100: add a clock alias for sa1111 pcmcia device
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1414147047-12892-1-git-send-email-dbaryshkov@gmail.com>
SA-1111 uses internal MMIO space offsets as a device name, so device
name for sa1111 pcmcia is 1800 (PCMCIA is at offset 0x1800).
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/clock.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 53f750d..03c75a8 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -124,6 +124,8 @@ static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT("sa1100-rtc", NULL, NULL),
CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
+ /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
+ CLKDEV_INIT("1800", NULL, &clk_cpu),
};
static int __init sa11xx_clk_init(void)
--
2.1.1
^ permalink raw reply related
* [PATCH 3/5] fbdev: sa1100fb: make use of device clock
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1414147047-12892-1-git-send-email-dbaryshkov@gmail.com>
Use per-device clock (instead of calling cpufreq_get(0), which can
return 0 if no cpu frequency driver is selected) to program timings.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/video/fbdev/sa1100fb.c | 24 +++++++++++++++++-------
drivers/video/fbdev/sa1100fb.h | 1 +
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c
index 580c444e..8933840 100644
--- a/drivers/video/fbdev/sa1100fb.c
+++ b/drivers/video/fbdev/sa1100fb.c
@@ -178,6 +178,7 @@
#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <video/sa1100fb.h>
@@ -413,9 +414,9 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->transp.offset);
#ifdef CONFIG_CPU_FREQ
- dev_dbg(fbi->dev, "dma period = %d ps, clock = %d kHz\n",
+ dev_dbg(fbi->dev, "dma period = %d ps, clock = %ld kHz\n",
sa1100fb_display_dma_period(var),
- cpufreq_get(smp_processor_id()));
+ clk_get_rate(fbi->clk) / 1000);
#endif
return 0;
@@ -586,9 +587,10 @@ static struct fb_ops sa1100fb_ops = {
* Calculate the PCD value from the clock rate (in picoseconds).
* We take account of the PPCR clock setting.
*/
-static inline unsigned int get_pcd(unsigned int pixclock, unsigned int cpuclock)
+static inline unsigned int get_pcd(struct sa1100fb_info *fbi,
+ unsigned int pixclock)
{
- unsigned int pcd = cpuclock / 100;
+ unsigned int pcd = clk_get_rate(fbi->clk) / 100 / 1000;
pcd *= pixclock;
pcd /= 10000000;
@@ -667,7 +669,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
LCCR2_BegFrmDel(var->upper_margin) +
LCCR2_EndFrmDel(var->lower_margin);
- pcd = get_pcd(var->pixclock, cpufreq_get(0));
+ pcd = get_pcd(fbi, var->pixclock);
new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 |
(var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
(var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
@@ -1003,7 +1005,6 @@ sa1100fb_freq_transition(struct notifier_block *nb, unsigned long val,
void *data)
{
struct sa1100fb_info *fbi = TO_INF(nb, freq_transition);
- struct cpufreq_freqs *f = data;
u_int pcd;
switch (val) {
@@ -1012,7 +1013,7 @@ sa1100fb_freq_transition(struct notifier_block *nb, unsigned long val,
break;
case CPUFREQ_POSTCHANGE:
- pcd = get_pcd(fbi->fb.var.pixclock, f->new);
+ pcd = get_pcd(fbi, fbi->fb.var.pixclock);
fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
break;
@@ -1219,6 +1220,13 @@ static int sa1100fb_probe(struct platform_device *pdev)
if (!fbi)
goto failed;
+ fbi->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fbi->clk)) {
+ ret = PTR_ERR(fbi->clk);
+ fbi->clk = NULL;
+ goto failed;
+ }
+
fbi->base = ioremap(res->start, resource_size(res));
if (!fbi->base)
goto failed;
@@ -1271,6 +1279,8 @@ static int sa1100fb_probe(struct platform_device *pdev)
failed:
if (fbi)
iounmap(fbi->base);
+ if (fbi->clk)
+ clk_put(fbi->clk);
kfree(fbi);
release_mem_region(res->start, resource_size(res));
return ret;
diff --git a/drivers/video/fbdev/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h
index fc5d429..0139d13 100644
--- a/drivers/video/fbdev/sa1100fb.h
+++ b/drivers/video/fbdev/sa1100fb.h
@@ -68,6 +68,7 @@ struct sa1100fb_info {
#endif
const struct sa1100fb_mach_info *inf;
+ struct clk *clk;
};
#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member)
--
2.1.1
^ permalink raw reply related
* [PATCH 4/5] pcmcia: sa1100: make use of device clock
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1414147047-12892-1-git-send-email-dbaryshkov@gmail.com>
Use per-device clock (instead of calling cpufreq_get(0), which can
return 0 if no cpu frequency driver is selected) to program timings.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/pcmcia/sa1100_generic.c | 1 +
drivers/pcmcia/sa11xx_base.c | 14 ++++++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index ff8a027..d2ab060 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -93,6 +93,7 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
for (i = 0; i < sinfo->nskt; i++)
soc_pcmcia_remove_one(&sinfo->skt[i]);
+ clk_put(sinfo->clk);
kfree(sinfo);
return 0;
}
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 54d3089..6dd94bb 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -135,14 +135,16 @@ sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
static int
sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
- return sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
+ unsigned long clk = clk_get_rate(skt->clk);
+
+ return sa1100_pcmcia_set_mecr(skt, clk / 1000);
}
static int
sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
{
struct soc_pcmcia_timing timing;
- unsigned int clock = cpufreq_get(0);
+ unsigned int clock = clk_get_rate(skt->clk);
unsigned long mecr = MECR;
char *p = buf;
@@ -218,6 +220,11 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
int i, ret = 0;
+ struct clk *clk;
+
+ clk = clk_get(dev, NULL);
+ if (IS_ERR(clk))
+ return -ENODEV;
sa11xx_drv_pcmcia_ops(ops);
@@ -226,12 +233,14 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
return -ENOMEM;
sinfo->nskt = nr;
+ sinfo->clk = clk;
/* Initialize processor specific parameters */
for (i = 0; i < nr; i++) {
skt = &sinfo->skt[i];
skt->nr = first + i;
+ skt->clk = clk;
soc_pcmcia_init_one(skt, ops, dev);
ret = sa11xx_drv_pcmcia_add_one(skt);
@@ -242,6 +251,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
if (ret) {
while (--i >= 0)
soc_pcmcia_remove_one(&sinfo->skt[i]);
+ clk_put(clk);
kfree(sinfo);
} else {
dev_set_drvdata(dev, sinfo);
--
2.1.1
^ permalink raw reply related
* [PATCH 5/5] pcmcia: sa1111: provide device clock
From: Dmitry Eremin-Solenikov @ 2014-10-24 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1414147047-12892-1-git-send-email-dbaryshkov@gmail.com>
Both pxa2xx (long ago) and sa1100 (now) make use of clock device to get
the cpu speed. Make sa1111 glue code provide clock to platform layer.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/pcmcia/sa1111_generic.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 65b02c3..c5988be 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -145,6 +145,9 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
return -ENOMEM;
s->soc.nr = ops->first + i;
+ s->soc.clk = clk_get(&dev->dev, NULL);
+ if (IS_ERR(s->soc.clk))
+ return -ENODEV;
soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
s->dev = dev;
if (s->soc.nr) {
@@ -220,6 +223,7 @@ static int pcmcia_remove(struct sa1111_dev *dev)
for (; s; s = next) {
next = s->next;
soc_pcmcia_remove_one(&s->soc);
+ clk_put(s->soc.clk);
kfree(s);
}
--
2.1.1
^ permalink raw reply related
* [PATCH] fbdev: mxsfb: Add support for mx6sl and mx6sx
From: Fabio Estevam @ 2014-10-25 13:28 UTC (permalink / raw)
To: linux-fbdev
From: Fabio Estevam <fabio.estevam@freescale.com>
mx6sl and mx6sx share the same LCD controller as mx23 and mx28.
Add support for it.
The basic difference is the number of clocks that are required:
- mx23/mx28: only one clock
- mx6sl: two clocks
- mx6sx: three clocks
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
Changes since RFC:
- Simplified the clock handling as suggested by Tomi
drivers/video/fbdev/Kconfig | 2 +-
drivers/video/fbdev/mxsfb.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index c7bf606..025b439 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2425,7 +2425,7 @@ config FB_JZ4740
config FB_MXS
tristate "MXS LCD framebuffer support"
- depends on FB && ARCH_MXS
+ depends on FB && (ARCH_MXS || ARCH_MXC)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index accf48a2..f8ac4a4 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -172,6 +172,8 @@ struct mxsfb_info {
struct fb_info fb_info;
struct platform_device *pdev;
struct clk *clk;
+ struct clk *clk_axi;
+ struct clk *clk_disp_axi;
void __iomem *base; /* registers */
unsigned allocated_size;
int enabled;
@@ -331,6 +333,11 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
}
}
+ if (host->clk_axi)
+ clk_prepare_enable(host->clk_axi);
+
+ if (host->clk_disp_axi)
+ clk_prepare_enable(host->clk_disp_axi);
clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
@@ -374,6 +381,10 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
clk_disable_unprepare(host->clk);
+ if (host->clk_disp_axi)
+ clk_disable_unprepare(host->clk_disp_axi);
+ if (host->clk_axi)
+ clk_disable_unprepare(host->clk_axi);
host->enabled = 0;
@@ -867,6 +878,14 @@ static int mxsfb_probe(struct platform_device *pdev)
goto fb_release;
}
+ host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
+ if (IS_ERR(host->clk_axi))
+ host->clk_axi = NULL;
+
+ host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
+ if (IS_ERR(host->clk_disp_axi))
+ host->clk_disp_axi = NULL;
+
host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
if (IS_ERR(host->reg_lcd))
host->reg_lcd = NULL;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] drivers: depend on instead of select BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO
From: Jani Nikula @ 2014-10-27 11:59 UTC (permalink / raw)
To: Tomi Valkeinen, linux-kernel, dri-devel, linuxppc-dev,
platform-driver-x86, linux-usb, linux-fbdev
Cc: Randy Dunlap, David Airlie, Daniel Vetter, Greg Kroah-Hartman,
Darren Hart, Laurent Pinchart, Benjamin Herrenschmidt,
Jens Frederich, Daniel Drake, Jon Nettleton,
Jean-Christophe Plagniol-Villard, Jingoo Han, Bryan Wu, Lee Jones
In-Reply-To: <54476492.6090105@ti.com>
On Wed, 22 Oct 2014, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On 18/10/14 00:13, Jani Nikula wrote:
>> Documentation/kbuild/kconfig-language.txt warns to use select with care,
>> and in general use select only for non-visible symbols and for symbols
>> with no dependencies, because select will force a symbol to a value
>> without visiting the dependencies.
>>
>> Select has become particularly problematic, interdependently, with the
>> BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO configs. For example:
>>
>> scripts/kconfig/conf --randconfig Kconfig
>> KCONFIG_SEED=0x48312B00
>> warning: (DRM_RADEON && DRM_NOUVEAU && DRM_I915 && DRM_GMA500 &&
>> DRM_SHMOBILE && DRM_TILCDC && FB_BACKLIGHT && FB_MX3 && USB_APPLEDISPLAY
>> && FB_OLPC_DCON && ASUS_LAPTOP && SONY_LAPTOP && THINKPAD_ACPI &&
>> EEEPC_LAPTOP && ACPI_CMPC && SAMSUNG_Q10) selects BACKLIGHT_CLASS_DEVICE
>> which has unmet direct dependencies (HAS_IOMEM && BACKLIGHT_LCD_SUPPORT)
>> warning: (DRM_RADEON && DRM_NOUVEAU && DRM_I915 && DRM_GMA500 &&
>> DRM_SHMOBILE && DRM_TILCDC && FB_BACKLIGHT && FB_MX3 && USB_APPLEDISPLAY
>> && FB_OLPC_DCON && ASUS_LAPTOP && SONY_LAPTOP && THINKPAD_ACPI &&
>> EEEPC_LAPTOP && ACPI_CMPC && SAMSUNG_Q10) selects BACKLIGHT_CLASS_DEVICE
>> which has unmet direct dependencies (HAS_IOMEM && BACKLIGHT_LCD_SUPPORT)
>>
>> With tristates it's possible to end up selecting FOO=y depending on
>> BAR=m in the config, which gets discovered at build time, not config
>> time, like reported in the thread referenced below.
>>
>> Do the following to fix the dependencies:
>>
>> * Depend on instead of select BACKLIGHT_CLASS_DEVICE everywhere. Drop
>> select BACKLIGHT_LCD_SUPPORT in such cases, as it's a dependency of
>> BACKLIGHT_CLASS_DEVICE.
>>
>> * Remove config FB_BACKLIGHT altogether, and replace it with a
>> dependency on BACKLIGHT_CLASS_DEVICE. All configs selecting
>> FB_BACKLIGHT select or depend on FB anyway, so we can simplify.
>>
>> * Depend on (ACPI && ACPI_VIDEO) || ACPI=n in several places instead of
>> selecting ACPI_VIDEO and a number of its dependencies if ACPI is
>> enabled. This is tied to backlight, as ACPI_VIDEO depends on
>> BACKLIGHT_CLASS_DEVICE.
>>
>> * Replace a couple of select INPUT/VT with depends as it seemed to be
>> necessary.
>
> While doing 'depends on' instead of 'select' is an "easy" fix for this,
> I do dislike it quite a bit. It's a major pain to go around the kernel
> config, trying to find all the dependencies that a particular driver
> wants. If I need fb-foobar, I should just be able to enable it, instead
> of first searching and selecting its minor dependencies individually.
Agreed, but I don't think that's specific to this patch.
> So, not a NACK, but a "isn't there an another way to fix this?".
I think the real answer would be to fix kconfig to also show menu items
whose dependencies are not met, and then recursively enabling the
dependencies when the item is enabled. Beyond my scope.
> Looking at backlight... BACKLIGHT_LCD_SUPPORT seems to be a "meta"
> option, it only enables a Kconfig submenu.
>
> So I think we could just remove the whole BACKLIGHT_LCD_SUPPORT option.
> But if we do that, all the items in drivers/video/backlight/Kconfig with
> default 'y' or 'm' would get enabled by default, so I think we should
> remove the 'default's from that file. That makes sense in any case, as I
> don't see why "HP Jornada 700 series LCD Driver" should be "default y".
>
> BACKLIGHT_CLASS_DEVICE doesn't depend on anything except
> BACKLIGHT_LCD_SUPPORT, so after removing BACKLIGHT_LCD_SUPPORT it should
> be safe to 'select' BACKLIGHT_CLASS_DEVICE.
>
> BACKLIGHT_CLASS_DEVICE could be made a hidden option, and the drivers in
> drivers/video/backlight/Kconfig which are under BACKLIGHT_CLASS_DEVICE
> could be made to select BACKLIGHT_CLASS_DEVICE instead.
I think it should be possible to choose between y and m when it's
selected, and it should be possible to enable it when it's not selected
by any drivers. I'm not sure a hidden option is good for that.
> That doesn't exactly fix anything, but I think it makes sense as
> BACKLIGHT_CLASS_DEVICE is something that's selected from all around the
> kernel, so it should be a selectable "library" instead of a Kconfig menu
> option.
At least for drm/i915 BACKLIGHT_CLASS_DEVICE is "an option". We use it
if it's enabled, but we are just fine if it's not. I've learned the way
to express that is
depends on BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=n
but I don't think there's a way to express that in terms of select, is
there? The dependency above guarantees there's no DRM_I915=y and
BACKLIGHT_CLASS_DEVICE=m combo which would fail. And this, btw, is where
this whole patch got started, as select didn't handle that properly.
> I didn't look at the ACPI_VIDEO side, so no idea how messy that is.
Basically it's another dependency on BACKLIGHT_CLASS_DEVICE. I can only
imagine trying to solve this problem with select is going to end up in
recursive dependencies that spread out and need changing about as wide
as this patch.
In the end, I agree with the problem you have with this patch, but yet I
think it's the right thing to do in terms of expressing the
dependencies.
BR,
Jani.
--
Jani Nikula, Intel Open Source Technology Center
^ permalink raw reply
* Re: [PATCH] drivers: depend on instead of select BACKLIGHT_CLASS_DEVICE and ACPI_VIDEO
From: Tomi Valkeinen @ 2014-10-27 13:13 UTC (permalink / raw)
To: Jani Nikula
Cc: linux-kernel, dri-devel, linuxppc-dev, platform-driver-x86,
linux-usb, linux-fbdev, Randy Dunlap, David Airlie, Daniel Vetter,
Greg Kroah-Hartman, Darren Hart, Laurent Pinchart,
Benjamin Herrenschmidt, Jens Frederich, Daniel Drake,
Jon Nettleton, Jean-Christophe Plagniol-Villard, Jingoo Han,
Bryan Wu, Lee Jones
In-Reply-To: <87a94hu3j0.fsf@intel.com>
[-- Attachment #1: Type: text/plain, Size: 5005 bytes --]
On 27/10/14 13:59, Jani Nikula wrote:
>> While doing 'depends on' instead of 'select' is an "easy" fix for this,
>> I do dislike it quite a bit. It's a major pain to go around the kernel
>> config, trying to find all the dependencies that a particular driver
>> wants. If I need fb-foobar, I should just be able to enable it, instead
>> of first searching and selecting its minor dependencies individually.
>
> Agreed, but I don't think that's specific to this patch.
Well, no, the generic problem is not specific to this patch, but we can
avoid the issue with proper use of 'select' (at least in some cases),
which is specific to this patch.
>> So, not a NACK, but a "isn't there an another way to fix this?".
>
> I think the real answer would be to fix kconfig to also show menu items
> whose dependencies are not met, and then recursively enabling the
> dependencies when the item is enabled. Beyond my scope.
>
>> Looking at backlight... BACKLIGHT_LCD_SUPPORT seems to be a "meta"
>> option, it only enables a Kconfig submenu.
>>
>> So I think we could just remove the whole BACKLIGHT_LCD_SUPPORT option.
>> But if we do that, all the items in drivers/video/backlight/Kconfig with
>> default 'y' or 'm' would get enabled by default, so I think we should
>> remove the 'default's from that file. That makes sense in any case, as I
>> don't see why "HP Jornada 700 series LCD Driver" should be "default y".
>>
>> BACKLIGHT_CLASS_DEVICE doesn't depend on anything except
>> BACKLIGHT_LCD_SUPPORT, so after removing BACKLIGHT_LCD_SUPPORT it should
>> be safe to 'select' BACKLIGHT_CLASS_DEVICE.
>>
>> BACKLIGHT_CLASS_DEVICE could be made a hidden option, and the drivers in
>> drivers/video/backlight/Kconfig which are under BACKLIGHT_CLASS_DEVICE
>> could be made to select BACKLIGHT_CLASS_DEVICE instead.
>
> I think it should be possible to choose between y and m when it's
If I'm not mistaken, if CONFIG_FOO is 'm', and it 'select's CONFIG_BAR,
and CONFIG_BAR is tristate, then CONFIG_BAR will be set to 'm'.
> selected, and it should be possible to enable it when it's not selected
> by any drivers. I'm not sure a hidden option is good for that.
Why would you want to enable it if no one uses it? Does
BACKLIGHT_CLASS_DEVICE enable something even if no driver uses it?
>> That doesn't exactly fix anything, but I think it makes sense as
>> BACKLIGHT_CLASS_DEVICE is something that's selected from all around the
>> kernel, so it should be a selectable "library" instead of a Kconfig menu
>> option.
>
> At least for drm/i915 BACKLIGHT_CLASS_DEVICE is "an option". We use it
> if it's enabled, but we are just fine if it's not. I've learned the way
> to express that is
>
> depends on BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=n
>
> but I don't think there's a way to express that in terms of select, is
> there? The dependency above guarantees there's no DRM_I915=y and
> BACKLIGHT_CLASS_DEVICE=m combo which would fail. And this, btw, is where
> this whole patch got started, as select didn't handle that properly.
If backlight support is considered an option for drm/i915, then I think
there should be a Kconfig option for i915 to enable backlight support,
which in turn selects BACKLIGHT_CLASS_DEVICE. And that select will force
BACKLIGHT_CLASS_DEVICE to be built-in if drm/i915 is built-in.
Oh, but it doesn't work optimally with modules. The new option needed
for that would be boolean, so BACKLIGHT_CLASS_DEVICE would always be
either y or n. Sigh...
>> I didn't look at the ACPI_VIDEO side, so no idea how messy that is.
>
> Basically it's another dependency on BACKLIGHT_CLASS_DEVICE. I can only
> imagine trying to solve this problem with select is going to end up in
> recursive dependencies that spread out and need changing about as wide
> as this patch.
If ACPI_VIDEO uses select to enable BACKLIGHT_CLASS_DEVICE, then, I
think, selecting ACPI_VIDEO will also select BACKLIGHT_CLASS_DEVICE. So
I don't right away see any recursive dependencies. Or what did you have
in mind?
> In the end, I agree with the problem you have with this patch, but yet I
> think it's the right thing to do in terms of expressing the
> dependencies.
Well, dri/i915 doesn't exactly depend on backlight, if I understood you
correctly. Instead, backlight is an option for dri/i915, and you kind of
hack it to be implemented with that 'depends on BACKLIGHT_CLASS_DEVICE
|| BACKLIGHT_CLASS_DEVICE=n'.
I guess it's debatable whether drivers should automatically use features
in the kernel if they happen to be enabled in the Kconfig, or should
they be individually enabled for that driver. I personally like the
latter option, as it allows more precise control, but it probably also
depends on the feature in question.
I also think the 'depends on BACKLIGHT_CLASS_DEVICE ||
BACKLIGHT_CLASS_DEVICE=n' pattern is quite... interesting (i.e. sounds
like a hack to me =).
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH] omap: dss: connector-analog-tv: Add missing module device table
From: Marek Belisko @ 2014-10-27 20:24 UTC (permalink / raw)
To: tomi.valkeinen, plagnioj
Cc: hns, marek, linux-omap, linux-fbdev, linux-kernel
Without that fix connector-analog-tv driver isn't probed when compiled
as module.
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
index 5ee3b55..d29cf72 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
@@ -301,6 +301,8 @@ static const struct of_device_id tvc_of_match[] = {
{},
};
+MODULE_DEVICE_TABLE(of, tvc_of_match);
+
static struct platform_driver tvc_connector_driver = {
.probe = tvc_probe,
.remove = __exit_p(tvc_remove),
--
1.9.1
^ permalink raw reply related
* [PATCH 00/15] new locomo driver
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
Sharp Zaurus SL-5500 and SL-5600 use special companion Gate Array. Current
drivers present in Linux kernel has some problems:
* It uses custom bus instead of platform bus/mfd core.
* Device drivers are not well layered/separated.
* It uses custom gpio accessors instead of using GPIOLIB.
With this patchset I tried to modernise and restructure the LoCoMo driver.
Also I added an experimental SPI driver that will be used by mmc-spi on
Sharp SL-5500 collie devices.
----------------------------------------------------------------
Dmitry Eremin-Solenikov (15):
mfd: add new driver for Sharp LoCoMo
GPIO: port LoCoMo gpio support from old driver
leds: port locomo leds driver to new locomo core
input: convert LoCoMo keyboard driver to use new locomo core
video: backlight: add new locomo backlight driver
video: lcd: add LoCoMo LCD driver
video: backlight: drop old locomo bl/lcd driver
ARM: sa1100: make collie use new locomo drivers
ARM: sa1100: don't preallocate IRQ space for locomo
ARM: pxa: poodle: use new LoCoMo driver
sound: soc: poodle: make use of new locomo GPIO interface
ARM: pxa: poodle: don't preallocate IRQ space for locomo
ARM: drop old LoCoMo driver
gpio: locomo: implement per-pin irq handling
spi: add locomo SPI driver
arch/arm/common/Kconfig | 3 -
arch/arm/common/Makefile | 1 -
arch/arm/common/locomo.c | 914 ---------------------
arch/arm/mach-pxa/Kconfig | 1 -
arch/arm/mach-pxa/include/mach/poodle.h | 16 +-
arch/arm/mach-pxa/poodle.c | 23 +-
arch/arm/mach-sa1100/Kconfig | 1 -
arch/arm/mach-sa1100/collie.c | 112 +--
arch/arm/mach-sa1100/include/mach/collie.h | 25 +-
arch/arm/mach-sa1100/include/mach/irqs.h | 19 +-
drivers/gpio/Kconfig | 7 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-locomo.c | 386 +++++++++
drivers/input/keyboard/Kconfig | 1 -
drivers/input/keyboard/locomokbd.c | 165 ++--
drivers/leds/Kconfig | 1 -
drivers/leds/leds-locomo.c | 104 ++-
drivers/mfd/Kconfig | 8 +
drivers/mfd/Makefile | 1 +
drivers/mfd/locomo.c | 644 +++++++++++++++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-locomo.c | 370 +++++++++
drivers/video/backlight/Kconfig | 14 +-
drivers/video/backlight/Makefile | 3 +-
drivers/video/backlight/locomo_bl.c | 171 ++++
drivers/video/backlight/locomo_lcd.c | 224 +++++
drivers/video/backlight/locomolcd.c | 255 ------
.../asm/hardware => include/linux/mfd}/locomo.h | 148 ++--
sound/soc/pxa/poodle.c | 51 +-
30 files changed, 2185 insertions(+), 1493 deletions(-)
delete mode 100644 arch/arm/common/locomo.c
create mode 100644 drivers/gpio/gpio-locomo.c
create mode 100644 drivers/mfd/locomo.c
create mode 100644 drivers/spi/spi-locomo.c
create mode 100644 drivers/video/backlight/locomo_bl.c
create mode 100644 drivers/video/backlight/locomo_lcd.c
delete mode 100644 drivers/video/backlight/locomolcd.c
rename {arch/arm/include/asm/hardware => include/linux/mfd}/locomo.h (55%)
^ permalink raw reply
* [PATCH 02/15] GPIO: port LoCoMo gpio support from old driver
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
Add gpiolib driver for gpio pins placed on the LoCoMo GA.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/gpio/Kconfig | 7 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-locomo.c | 228 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 236 insertions(+)
create mode 100644 drivers/gpio/gpio-locomo.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0959ca9..11c03d4 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -457,6 +457,13 @@ config GPIO_TB10X
select GENERIC_IRQ_CHIP
select OF_GPIO
+config GPIO_LOCOMO
+ bool "Sharp LoCoMo GPIO support"
+ depends on MFD_LOCOMO
+ help
+ Select this to support GPIO pins on Sharp LoCoMo Grid Array found
+ in Sharp Zaurus collie and poodle models.
+
comment "I2C GPIO expanders:"
config GPIO_ARIZONA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index e5d346c..ed73f63 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_INTEL_MID) += gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LOCOMO) += gpio-locomo.o
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
new file mode 100644
index 0000000..3b54b07
--- /dev/null
+++ b/drivers/gpio/gpio-locomo.c
@@ -0,0 +1,228 @@
+/*
+ * Sharp LoCoMo support for GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_gpio {
+ void __iomem *regs;
+
+ spinlock_t lock;
+ struct gpio_chip gpio;
+
+ u16 rising_edge;
+ u16 falling_edge;
+
+ u16 save_gpo;
+ u16 save_gpe;
+};
+
+static int locomo_gpio_get(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+ return readw(lg->regs + LOCOMO_GPL) & (1 << offset);
+}
+
+static void __locomo_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+ u16 r;
+
+ r = readw(lg->regs + LOCOMO_GPO);
+ if (value)
+ r |= 1 << offset;
+ else
+ r &= ~(1 << offset);
+ writew(r, lg->regs + LOCOMO_GPO);
+}
+
+static void locomo_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lg->lock, flags);
+
+ __locomo_gpio_set(chip, offset, value);
+
+ spin_unlock_irqrestore(&lg->lock, flags);
+}
+
+static int locomo_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+ unsigned long flags;
+ u16 r;
+
+ spin_lock_irqsave(&lg->lock, flags);
+
+ r = readw(lg->regs + LOCOMO_GPD);
+ r |= (1 << offset);
+ writew(r, lg->regs + LOCOMO_GPD);
+
+ r = readw(lg->regs + LOCOMO_GPE);
+ r |= (1 << offset);
+ writew(r, lg->regs + LOCOMO_GPE);
+
+ spin_unlock_irqrestore(&lg->lock, flags);
+
+ return 0;
+}
+
+static int locomo_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+ unsigned long flags;
+ u16 r;
+
+ spin_lock_irqsave(&lg->lock, flags);
+
+ __locomo_gpio_set(chip, offset, value);
+
+ r = readw(lg->regs + LOCOMO_GPD);
+ r &= ~(1 << offset);
+ writew(r, lg->regs + LOCOMO_GPD);
+
+ r = readw(lg->regs + LOCOMO_GPE);
+ r &= ~(1 << offset);
+ writew(r, lg->regs + LOCOMO_GPE);
+
+ spin_unlock_irqrestore(&lg->lock, flags);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_gpio_suspend(struct device *dev)
+{
+ struct locomo_gpio *lg = dev_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lg->lock, flags);
+
+ lg->save_gpo = readw(lg->regs + LOCOMO_GPO);
+ writew(0x00, lg->regs + LOCOMO_GPO);
+
+ lg->save_gpo = readw(lg->regs + LOCOMO_GPE);
+ writew(0x00, lg->regs + LOCOMO_GPE);
+
+ spin_unlock_irqrestore(&lg->lock, flags);
+ return 0;
+}
+
+static int locomo_gpio_resume(struct device *dev)
+{
+ struct locomo_gpio *lg = dev_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lg->lock, flags);
+
+ writew(lg->save_gpo, lg->regs + LOCOMO_GPO);
+
+ writew(lg->save_gpe, lg->regs + LOCOMO_GPE);
+
+ spin_unlock_irqrestore(&lg->lock, flags);
+ return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_gpio_pm,
+ locomo_gpio_suspend, locomo_gpio_resume);
+#define LOCOMO_GPIO_PM (&locomo_gpio_pm)
+#else
+#define LOCOMO_GPIO_PM NULL
+#endif
+
+static int locomo_gpio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct locomo_gpio *lg;
+ int ret;
+ struct locomo_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ lg = devm_kzalloc(&pdev->dev, sizeof(struct locomo_gpio),
+ GFP_KERNEL);
+ if (!lg)
+ return -ENOMEM;
+
+ lg->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(lg->regs))
+ return PTR_ERR(lg->regs);
+
+ spin_lock_init(&lg->lock);
+
+ platform_set_drvdata(pdev, lg);
+
+ writew(0, lg->regs + LOCOMO_GPO);
+ writew(0, lg->regs + LOCOMO_GPE);
+ writew(0, lg->regs + LOCOMO_GPD);
+ writew(0, lg->regs + LOCOMO_GIE);
+
+ lg->gpio.base = pdata ? pdata->gpio_base : -1;
+ lg->gpio.label = "locomo-gpio";
+ lg->gpio.ngpio = 16;
+ lg->gpio.set = locomo_gpio_set;
+ lg->gpio.get = locomo_gpio_get;
+ lg->gpio.direction_input = locomo_gpio_direction_input;
+ lg->gpio.direction_output = locomo_gpio_direction_output;
+
+ ret = gpiochip_add(&lg->gpio);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int locomo_gpio_remove(struct platform_device *pdev)
+{
+ struct locomo_gpio *lg = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = gpiochip_remove(&lg->gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't remove gpio chip: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver locomo_gpio_driver = {
+ .probe = locomo_gpio_probe,
+ .remove = locomo_gpio_remove,
+ .driver = {
+ .name = "locomo-gpio",
+ .owner = THIS_MODULE,
+ .pm = LOCOMO_GPIO_PM,
+ },
+};
+module_platform_driver(locomo_gpio_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo GPIO driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo-gpio");
--
2.1.1
^ permalink raw reply related
* [PATCH 03/15] leds: port locomo leds driver to new locomo core
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
Adapt locomo leds driver to new locomo core setup.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/leds/Kconfig | 1 -
drivers/leds/leds-locomo.c | 104 +++++++++++++++++++++++++++------------------
2 files changed, 62 insertions(+), 43 deletions(-)
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a210338..22ebf1c 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -69,7 +69,6 @@ config LEDS_LM3642
config LEDS_LOCOMO
tristate "LED Support for Locomo device"
depends on LEDS_CLASS
- depends on SHARP_LOCOMO
help
This option enables support for the LEDs on Sharp Locomo.
Zaurus models SL-5500 and SL-5600.
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 80ba048..acb288f 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -11,87 +11,107 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/leds.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/mfd/locomo.h>
-#include <mach/hardware.h>
-#include <asm/hardware/locomo.h>
+struct locomo_led {
+ struct led_classdev led;
+ void __iomem *reg;
+};
static void locomoled_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness value, int offset)
+ enum led_brightness value)
{
- struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
+ struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
unsigned long flags;
local_irq_save(flags);
if (value)
- locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
+ writew(LOCOMO_LPT_TOFH, led->reg);
else
- locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
+ writew(LOCOMO_LPT_TOFL, led->reg);
local_irq_restore(flags);
}
-static void locomoled_brightness_set0(struct led_classdev *led_cdev,
- enum led_brightness value)
+static int locomo_led_register(
+ struct locomo_led *led,
+ struct device *dev,
+ const char *name,
+ const char *trigger,
+ void __iomem *reg)
{
- locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
+ led->led.name = name;
+ led->led.default_trigger = trigger;
+ led->led.brightness_set = locomoled_brightness_set;
+ led->reg = reg;
+
+ return led_classdev_register(dev, &led->led);
}
-static void locomoled_brightness_set1(struct led_classdev *led_cdev,
- enum led_brightness value)
+static int locomoled_probe(struct platform_device *pdev)
{
- locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
-}
+ int ret;
+ struct resource *mem;
+ void __iomem *regs;
+ struct locomo_led *leds;
-static struct led_classdev locomo_led0 = {
- .name = "locomo:amber:charge",
- .default_trigger = "main-battery-charging",
- .brightness_set = locomoled_brightness_set0,
-};
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -EINVAL;
-static struct led_classdev locomo_led1 = {
- .name = "locomo:green:mail",
- .default_trigger = "nand-disk",
- .brightness_set = locomoled_brightness_set1,
-};
+ regs = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
-static int locomoled_probe(struct locomo_dev *ldev)
-{
- int ret;
+ leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
+ if (!leds)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, leds);
- ret = led_classdev_register(&ldev->dev, &locomo_led0);
+ ret = locomo_led_register(leds,
+ &pdev->dev,
+ "locomo:amber:charge",
+ "main-battery-charging",
+ regs + LOCOMO_LPT0);
if (ret < 0)
return ret;
- ret = led_classdev_register(&ldev->dev, &locomo_led1);
+ ret = locomo_led_register(leds + 1,
+ &pdev->dev,
+ "locomo:green:mail",
+ "nand-disk",
+ regs + LOCOMO_LPT1);
if (ret < 0)
- led_classdev_unregister(&locomo_led0);
+ led_classdev_unregister(&leds[0].led);
return ret;
}
-static int locomoled_remove(struct locomo_dev *dev)
+static int locomoled_remove(struct platform_device *pdev)
{
- led_classdev_unregister(&locomo_led0);
- led_classdev_unregister(&locomo_led1);
+ struct locomo_led *leds = platform_get_drvdata(pdev);
+
+ led_classdev_unregister(&leds[0].led);
+ led_classdev_unregister(&leds[1].led);
+
return 0;
}
-static struct locomo_driver locomoled_driver = {
- .drv = {
- .name = "locomoled"
+static struct platform_driver locomoled_driver = {
+ .driver = {
+ .name = "locomo-led"
},
- .devid = LOCOMO_DEVID_LED,
.probe = locomoled_probe,
.remove = locomoled_remove,
};
-static int __init locomoled_init(void)
-{
- return locomo_driver_register(&locomoled_driver);
-}
-module_init(locomoled_init);
+module_platform_driver(locomoled_driver);
MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
MODULE_DESCRIPTION("Locomo LED driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-led");
--
2.1.1
^ permalink raw reply related
* [PATCH 04/15] input: convert LoCoMo keyboard driver to use new locomo core
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-leds-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
As LoCoMo is switching to new device model, adapt keyboard driver to
support new locomo core driver.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/input/keyboard/Kconfig | 1 -
drivers/input/keyboard/locomokbd.c | 165 ++++++++++++++++++++-----------------
2 files changed, 91 insertions(+), 75 deletions(-)
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a3958c6..b660516 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -337,7 +337,6 @@ config KEYBOARD_LM8333
config KEYBOARD_LOCOMO
tristate "LoCoMo Keyboard Support"
- depends on SHARP_LOCOMO
help
Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index c94d610..c2fabf3 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -28,16 +28,10 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
-MODULE_DESCRIPTION("LoCoMo keyboard driver");
-MODULE_LICENSE("GPL");
+#include <linux/io.h>
+#include <linux/mfd/locomo.h>
#define LOCOMOKBD_NUMKEYS 128
@@ -75,7 +69,8 @@ struct locomokbd {
struct input_dev *input;
char phys[32];
- unsigned long base;
+ void __iomem *base;
+ int irq;
spinlock_t lock;
struct timer_list timer;
@@ -84,37 +79,37 @@ struct locomokbd {
};
/* helper functions for reading the keyboard matrix */
-static inline void locomokbd_charge_all(unsigned long membase)
+static inline void locomokbd_charge_all(void __iomem *membase)
{
- locomo_writel(0x00FF, membase + LOCOMO_KSC);
+ writew(0x00FF, membase + LOCOMO_KSC);
}
-static inline void locomokbd_activate_all(unsigned long membase)
+static inline void locomokbd_activate_all(void __iomem *membase)
{
unsigned long r;
- locomo_writel(0, membase + LOCOMO_KSC);
- r = locomo_readl(membase + LOCOMO_KIC);
+ writew(0, membase + LOCOMO_KSC);
+ r = readw(membase + LOCOMO_KIC);
r &= 0xFEFF;
- locomo_writel(r, membase + LOCOMO_KIC);
+ writew(r, membase + LOCOMO_KIC);
}
-static inline void locomokbd_activate_col(unsigned long membase, int col)
+static inline void locomokbd_activate_col(void __iomem *membase, int col)
{
unsigned short nset;
unsigned short nbset;
nset = 0xFF & ~(1 << col);
nbset = (nset << 8) + nset;
- locomo_writel(nbset, membase + LOCOMO_KSC);
+ writew(nbset, membase + LOCOMO_KSC);
}
-static inline void locomokbd_reset_col(unsigned long membase, int col)
+static inline void locomokbd_reset_col(void __iomem *membase, int col)
{
unsigned short nbset;
nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
- locomo_writel(nbset, membase + LOCOMO_KSC);
+ writew(nbset, membase + LOCOMO_KSC);
}
/*
@@ -129,7 +124,7 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
unsigned int row, col, rowd;
unsigned long flags;
unsigned int num_pressed;
- unsigned long membase = locomokbd->base;
+ void __iomem *membase = locomokbd->base;
spin_lock_irqsave(&locomokbd->lock, flags);
@@ -141,7 +136,7 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
locomokbd_activate_col(membase, col);
udelay(KB_DELAY);
- rowd = ~locomo_readl(membase + LOCOMO_KIB);
+ rowd = ~readw(membase + LOCOMO_KIB);
for (row = 0; row < KB_ROWS; row++) {
unsigned int scancode, pressed, key;
@@ -194,11 +189,11 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
struct locomokbd *locomokbd = dev_id;
u16 r;
- r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+ r = readw(locomokbd->base + LOCOMO_KIC);
if ((r & 0x0001) = 0)
return IRQ_HANDLED;
- locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+ writew(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
/** wait chattering delay **/
udelay(100);
@@ -222,8 +217,8 @@ static int locomokbd_open(struct input_dev *dev)
struct locomokbd *locomokbd = input_get_drvdata(dev);
u16 r;
- r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
- locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+ r = readw(locomokbd->base + LOCOMO_KIC) | 0x0010;
+ writew(r, locomokbd->base + LOCOMO_KIC);
return 0;
}
@@ -232,35 +227,39 @@ static void locomokbd_close(struct input_dev *dev)
struct locomokbd *locomokbd = input_get_drvdata(dev);
u16 r;
- r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
- locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+ r = readw(locomokbd->base + LOCOMO_KIC) & ~0x0010;
+ writew(r, locomokbd->base + LOCOMO_KIC);
}
-static int locomokbd_probe(struct locomo_dev *dev)
+static int locomokbd_probe(struct platform_device *dev)
{
struct locomokbd *locomokbd;
struct input_dev *input_dev;
int i, err;
+ struct resource *res;
+
+ locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
+ GFP_KERNEL);
+ if (!locomokbd)
+ return -ENOMEM;
- locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
input_dev = input_allocate_device();
- if (!locomokbd || !input_dev) {
- err = -ENOMEM;
- goto err_free_mem;
- }
+ if (!input_dev)
+ return -ENOMEM;
- /* try and claim memory region */
- if (!request_mem_region((unsigned long) dev->mapbase,
- dev->length,
- LOCOMO_DRIVER_NAME(dev))) {
- err = -EBUSY;
- printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
- goto err_free_mem;
- }
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
- locomo_set_drvdata(dev, locomokbd);
+ locomokbd->irq = platform_get_irq(dev, 0);
+ if (locomokbd->irq < 0)
+ return -ENXIO;
- locomokbd->base = (unsigned long) dev->mapbase;
+ platform_set_drvdata(dev, locomokbd);
+
+ locomokbd->base = devm_ioremap_resource(&dev->dev, res);
+ if (IS_ERR(locomokbd->base))
+ return PTR_ERR(locomokbd->base);
spin_lock_init(&locomokbd->lock);
@@ -296,11 +295,15 @@ static int locomokbd_probe(struct locomo_dev *dev)
set_bit(locomokbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
+ writew(0, locomokbd->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+ writew(0, locomokbd->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+
/* attempt to get the interrupt */
- err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
+ err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
+ "locomokbd", locomokbd);
if (err) {
printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
- goto err_release_region;
+ goto err_free_mem;
}
err = input_register_device(locomokbd->input);
@@ -309,54 +312,68 @@ static int locomokbd_probe(struct locomo_dev *dev)
return 0;
- err_free_irq:
- free_irq(dev->irq[0], locomokbd);
- err_release_region:
- release_mem_region((unsigned long) dev->mapbase, dev->length);
- locomo_set_drvdata(dev, NULL);
- err_free_mem:
+err_free_irq:
+ free_irq(locomokbd->irq, locomokbd);
+err_free_mem:
+ platform_set_drvdata(dev, NULL);
input_free_device(input_dev);
- kfree(locomokbd);
return err;
}
-static int locomokbd_remove(struct locomo_dev *dev)
+static int locomokbd_remove(struct platform_device *dev)
{
- struct locomokbd *locomokbd = locomo_get_drvdata(dev);
+ struct locomokbd *locomokbd = platform_get_drvdata(dev);
- free_irq(dev->irq[0], locomokbd);
+ free_irq(locomokbd->irq, locomokbd);
del_timer_sync(&locomokbd->timer);
input_unregister_device(locomokbd->input);
- locomo_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
+
+ return 0;
+}
- release_mem_region((unsigned long) dev->mapbase, dev->length);
+#ifdef CONFIG_PM_SLEEP
+static int locomokbd_resume(struct device *dev)
+{
+ struct locomokbd *locomokbd = dev_get_drvdata(dev);
+ unsigned long flags;
+ u16 r;
+
+ spin_lock_irqsave(&locomokbd->lock, flags);
+
+ writew(0, locomokbd->base + LOCOMO_KSC);
+ r = readw(locomokbd->base + LOCOMO_KIC);
+ r &= 0xFEFF;
+ writew(r, locomokbd->base + LOCOMO_KIC);
+ writew(0x1, locomokbd->base + LOCOMO_KCMD);
- kfree(locomokbd);
+ spin_unlock_irqrestore(&locomokbd->lock, flags);
return 0;
}
-static struct locomo_driver keyboard_driver = {
- .drv = {
- .name = "locomokbd"
+static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, NULL, locomokbd_resume);
+#define LOCOMO_KBD_PM (&locomo_kbd_pm)
+#else
+#define LOCOMO_KBD_PM NULL
+#endif
+
+static struct platform_driver locomokbd_driver = {
+ .driver = {
+ .name = "locomo-kbd",
+ .owner = THIS_MODULE,
+ .pm = LOCOMO_KBD_PM,
},
- .devid = LOCOMO_DEVID_KEYBOARD,
.probe = locomokbd_probe,
.remove = locomokbd_remove,
};
-static int __init locomokbd_init(void)
-{
- return locomo_driver_register(&keyboard_driver);
-}
-
-static void __exit locomokbd_exit(void)
-{
- locomo_driver_unregister(&keyboard_driver);
-}
+module_platform_driver(locomokbd_driver);
-module_init(locomokbd_init);
-module_exit(locomokbd_exit);
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_DESCRIPTION("LoCoMo keyboard driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-kbd");
--
2.1.1
^ permalink raw reply related
* [PATCH 05/15] video: backlight: add new locomo backlight driver
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
Add new simple backlight driver - it cares only about PWM/frontlight
part of LoCoMo, it does not touch TFT settings and does not export TFT
power control.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/video/backlight/Kconfig | 6 +-
drivers/video/backlight/Makefile | 2 +-
drivers/video/backlight/locomo_bl.c | 171 ++++++++++++++++++++++++++++++++++++
3 files changed, 175 insertions(+), 4 deletions(-)
create mode 100644 drivers/video/backlight/locomo_bl.c
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 8d03924..03b77b33 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -218,12 +218,12 @@ config BACKLIGHT_LM3533
levels.
config BACKLIGHT_LOCOMO
- tristate "Sharp LOCOMO LCD/Backlight Driver"
- depends on SHARP_LOCOMO
+ tristate "Sharp LOCOMO Backlight Driver"
+ depends on MFD_LOCOMO
default y
help
If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
- enable the LCD/backlight driver.
+ enable the backlight driver.
config BACKLIGHT_OMAP1
tristate "OMAP1 PWL-based LCD Backlight"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index fcd50b73..2a61b7e 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o
obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o
obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
-obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomo_bl.o
obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
obj-$(CONFIG_BACKLIGHT_LV5207LP) += lv5207lp.o
diff --git a/drivers/video/backlight/locomo_bl.c b/drivers/video/backlight/locomo_bl.c
new file mode 100644
index 0000000..cec1b51
--- /dev/null
+++ b/drivers/video/backlight/locomo_bl.c
@@ -0,0 +1,171 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_bl {
+ void __iomem *regs;
+ int current_intensity;
+ int gpio_fl_vr;
+};
+
+static const struct {
+ u16 duty, bpwf;
+ bool vr;
+} locomo_bl_pwm[] = {
+ { 0, 161, false },
+ { 117, 161, false },
+ { 163, 148, false },
+ { 194, 161, false },
+ { 194, 161, true },
+};
+
+static int locomo_bl_set_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+ struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+ if (bd->props.power != FB_BLANK_UNBLANK)
+ intensity = 0;
+ if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+ intensity = 0;
+ if (bd->props.state & BL_CORE_SUSPENDED)
+ intensity = 0;
+
+ gpio_set_value(bl->gpio_fl_vr, locomo_bl_pwm[intensity].vr);
+
+ writew(locomo_bl_pwm[intensity].bpwf, bl->regs + LOCOMO_ALS);
+ udelay(100);
+ writew(locomo_bl_pwm[intensity].duty, bl->regs + LOCOMO_ALD);
+ udelay(100);
+ writew(locomo_bl_pwm[intensity].bpwf | LOCOMO_ALC_EN,
+ bl->regs + LOCOMO_ALS);
+
+ bl->current_intensity = intensity;
+ if (bd->props.state & BL_CORE_SUSPENDED)
+ writew(0x00, bl->regs + LOCOMO_ALS);
+
+ return 0;
+}
+
+static int locomo_bl_get_intensity(struct backlight_device *bd)
+{
+ struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+ return bl->current_intensity;
+}
+
+static const struct backlight_ops locomo_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = locomo_bl_get_intensity,
+ .update_status = locomo_bl_set_intensity,
+};
+
+static int locomo_bl_probe(struct platform_device *dev)
+{
+ struct backlight_properties props;
+ struct resource *res;
+ struct locomo_bl_platform_data *pdata;
+ struct locomo_bl *bl;
+ struct backlight_device *locomo_bl_device;
+ int rc;
+
+ bl = devm_kmalloc(&dev->dev, sizeof(struct locomo_bl), GFP_KERNEL);
+ if (!bl)
+ return -ENOMEM;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+ bl->regs = devm_ioremap_resource(&dev->dev, res);
+ if (!bl->regs)
+ return -EINVAL;
+
+ pdata = dev_get_platdata(&dev->dev);
+ if (!pdata)
+ return -EINVAL;
+
+ bl->gpio_fl_vr = pdata->gpio_fl_vr;
+ rc = devm_gpio_request_one(&dev->dev, bl->gpio_fl_vr,
+ GPIOF_OUT_INIT_LOW, "FL VR");
+ if (rc)
+ return rc;
+
+ writew(0, bl->regs + LOCOMO_ALS);
+ writew(0, bl->regs + LOCOMO_ALD);
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = ARRAY_SIZE(locomo_bl_pwm) - 1;
+ props.brightness = props.max_brightness / 2;
+ locomo_bl_device = backlight_device_register("locomo-bl",
+ &dev->dev, bl,
+ &locomo_bl_ops, &props);
+
+ if (IS_ERR(locomo_bl_device))
+ return PTR_ERR(locomo_bl_device);
+
+ platform_set_drvdata(dev, locomo_bl_device);
+
+ /* Set up frontlight so that screen is readable */
+ backlight_update_status(locomo_bl_device);
+
+ return 0;
+}
+
+static int locomo_bl_remove(struct platform_device *dev)
+{
+ struct backlight_device *locomo_bl_device = platform_get_drvdata(dev);
+
+ locomo_bl_device->props.brightness = 0;
+ locomo_bl_device->props.power = 0;
+ locomo_bl_set_intensity(locomo_bl_device);
+
+ backlight_device_unregister(locomo_bl_device);
+
+ return 0;
+}
+
+static void locomo_bl_shutdown(struct platform_device *dev)
+{
+ struct backlight_device *locomo_bl_device = platform_get_drvdata(dev);
+
+ locomo_bl_device->props.brightness = 0;
+ locomo_bl_device->props.power = 0;
+ locomo_bl_set_intensity(locomo_bl_device);
+}
+
+static struct platform_driver locomo_bl_driver = {
+ .driver = {
+ .name = "locomo-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = locomo_bl_probe,
+ .remove = locomo_bl_remove,
+ /* Turn off bl on power off/reboot */
+ .shutdown = locomo_bl_shutdown,
+};
+
+module_platform_driver(locomo_bl_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("Collie Backlight driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-backlight");
--
2.1.1
^ permalink raw reply related
* [PATCH 06/15] video: lcd: add LoCoMo LCD driver
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:01 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
LoCoMo has some special handling for TFT screens attached to Collie and
Poodle. Implement that as a separate driver.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/video/backlight/Kconfig | 8 ++
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/locomo_lcd.c | 224 +++++++++++++++++++++++++++++++++++
3 files changed, 233 insertions(+)
create mode 100644 drivers/video/backlight/locomo_lcd.c
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 03b77b33..bc5c671 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -48,6 +48,14 @@ config LCD_LMS283GF05
SPI driver for Samsung LMS283GF05. This provides basic support
for powering the LCD up/down through a sysfs interface.
+config LCD_LOCOMO
+ tristate "Sharp LOCOMO LCD Driver"
+ depends on MFD_LOCOMO
+ default y
+ help
+ If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
+ enable the LCD driver.
+
config LCD_LTV350QV
tristate "Samsung LTV350QV LCD Panel"
depends on SPI_MASTER
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 2a61b7e..b2580e7 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_LCD_ILI922X) += ili922x.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o
obj-$(CONFIG_LCD_LD9040) += ld9040.o
+obj-$(CONFIG_LCD_LOCOMO) += locomo_lcd.o
obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o
obj-$(CONFIG_LCD_LMS501KF03) += lms501kf03.o
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
diff --git a/drivers/video/backlight/locomo_lcd.c b/drivers/video/backlight/locomo_lcd.c
new file mode 100644
index 0000000..245efb8
--- /dev/null
+++ b/drivers/video/backlight/locomo_lcd.c
@@ -0,0 +1,224 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+/* LCD power functions */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/lcd.h>
+#include <linux/mfd/locomo.h>
+
+static struct platform_device *locomolcd_dev;
+static struct locomo_lcd_platform_data lcd_data;
+static bool locomolcd_is_on;
+static bool locomolcd_is_suspended;
+static void __iomem *locomolcd_regs;
+static struct lcd_device *lcd_dev;
+
+static struct gpio locomo_gpios[] = {
+ { 0, GPIOF_OUT_INIT_LOW, "LCD VSHA on" },
+ { 0, GPIOF_OUT_INIT_LOW, "LCD VSHD on" },
+ { 0, GPIOF_OUT_INIT_LOW, "LCD Vee on" },
+ { 0, GPIOF_OUT_INIT_LOW, "LCD MOD" },
+};
+
+static void locomolcd_on(void)
+{
+ gpio_set_value(lcd_data.gpio_lcd_vsha_on, 1);
+ mdelay(2);
+
+ gpio_set_value(lcd_data.gpio_lcd_vshd_on, 1);
+ mdelay(2);
+
+ locomo_m62332_senddata(locomolcd_dev->dev.parent, lcd_data.comadj, 0);
+ mdelay(5);
+
+ gpio_set_value(lcd_data.gpio_lcd_vee_on, 1);
+ mdelay(10);
+
+ /* TFTCRST | CPSOUT=0 | CPSEN */
+ writew(0x01, locomolcd_regs + LOCOMO_TC);
+
+ /* Set CPSD */
+ writew(6, locomolcd_regs + LOCOMO_CPSD);
+
+ /* TFTCRST | CPSOUT=0 | CPSEN */
+ writew((0x04 | 0x01), locomolcd_regs + LOCOMO_TC);
+ mdelay(10);
+
+ gpio_set_value(lcd_data.gpio_lcd_mod, 1);
+}
+
+static void locomolcd_off(void)
+{
+ /* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
+ writew(0x06, locomolcd_regs + LOCOMO_TC);
+ mdelay(1);
+
+ gpio_set_value(lcd_data.gpio_lcd_vsha_on, 0);
+ mdelay(110);
+
+ gpio_set_value(lcd_data.gpio_lcd_vee_on, 0);
+ mdelay(700);
+
+ locomo_m62332_senddata(locomolcd_dev->dev.parent, 0, 0);
+ mdelay(5);
+
+ /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
+ writew(0, locomolcd_regs + LOCOMO_TC);
+ gpio_set_value(lcd_data.gpio_lcd_mod, 0);
+ gpio_set_value(lcd_data.gpio_lcd_vshd_on, 0);
+}
+
+int locomo_lcd_set_power(struct lcd_device *lcd, int power)
+{
+ dev_dbg(&lcd->dev, "LCD power %d (is %d)\n", power, locomolcd_is_on);
+ if (power = 0 && !locomolcd_is_on) {
+ locomolcd_is_on = 1;
+ locomolcd_on();
+ }
+ if (power != 0 && locomolcd_is_on) {
+ locomolcd_is_on = 0;
+ locomolcd_off();
+ }
+ return 0;
+}
+
+static int locomo_lcd_get_power(struct lcd_device *lcd)
+{
+ return !locomolcd_is_on;
+}
+
+static struct lcd_ops locomo_lcd_ops = {
+ .set_power = locomo_lcd_set_power,
+ .get_power = locomo_lcd_get_power,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int locomolcd_suspend(struct device *dev)
+{
+ locomolcd_is_suspended = true;
+ locomolcd_off();
+
+ return 0;
+}
+
+static int locomolcd_resume(struct device *dev)
+{
+ locomolcd_is_suspended = false;
+
+ if (locomolcd_is_on)
+ locomolcd_on();
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomolcd_pm, locomolcd_suspend, locomolcd_resume);
+#define LOCOMOLCD_PM (&locomolcd_pm)
+#else
+#define LOCOMOLCD_PM NULL
+#endif
+
+static int locomolcd_probe(struct platform_device *dev)
+{
+ unsigned long flags;
+ struct resource *res;
+ struct locomo_lcd_platform_data *pdata;
+ int rc;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+ locomolcd_regs = devm_ioremap_resource(&dev->dev, res);
+ if (!locomolcd_regs)
+ return -EINVAL;
+
+ pdata = dev_get_platdata(&dev->dev);
+ if (!pdata)
+ return -EINVAL;
+
+ lcd_data = *pdata;
+
+ locomo_gpios[0].gpio = lcd_data.gpio_lcd_vsha_on;
+ locomo_gpios[1].gpio = lcd_data.gpio_lcd_vshd_on;
+ locomo_gpios[2].gpio = lcd_data.gpio_lcd_vee_on;
+ locomo_gpios[3].gpio = lcd_data.gpio_lcd_mod;
+ dev_info(&dev->dev, "GPIOs: %d %d %d %d\n",
+ locomo_gpios[0].gpio,
+ locomo_gpios[1].gpio,
+ locomo_gpios[2].gpio,
+ locomo_gpios[3].gpio);
+
+ rc = gpio_request_array(locomo_gpios, ARRAY_SIZE(locomo_gpios));
+ if (rc)
+ return rc;
+
+ local_irq_save(flags);
+ locomolcd_dev = dev;
+
+ locomolcd_is_on = 1;
+ if (locomolcd_is_on)
+ locomolcd_on();
+
+ local_irq_restore(flags);
+
+ lcd_dev = lcd_device_register("locomo", &dev->dev, NULL,
+ &locomo_lcd_ops);
+
+ return 0;
+}
+
+static int locomolcd_remove(struct platform_device *dev)
+{
+ unsigned long flags;
+
+ lcd_device_unregister(lcd_dev);
+
+ local_irq_save(flags);
+
+ locomolcd_off();
+ locomolcd_dev = NULL;
+
+ local_irq_restore(flags);
+
+ gpio_free_array(locomo_gpios, ARRAY_SIZE(locomo_gpios));
+
+ return 0;
+}
+
+static void locomolcd_shutdown(struct platform_device *dev)
+{
+ locomolcd_off();
+}
+
+static struct platform_driver locomolcd_driver = {
+ .driver = {
+ .name = "locomo-lcd",
+ .owner = THIS_MODULE,
+ .pm = LOCOMOLCD_PM,
+ },
+ .probe = locomolcd_probe,
+ .remove = locomolcd_remove,
+ .shutdown = locomolcd_shutdown,
+};
+
+module_platform_driver(locomolcd_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("Collie LCD driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-lcd");
--
2.1.1
^ permalink raw reply related
* [PATCH 07/15] video: backlight: drop old locomo bl/lcd driver
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:02 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
Old locomolcd driver is now completely obsolete by new locomo_bl and
locomo_lcd drivers, so let's drop it.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/video/backlight/locomolcd.c | 255 ------------------------------------
1 file changed, 255 deletions(-)
delete mode 100644 drivers/video/backlight/locomolcd.c
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
deleted file mode 100644
index 6c3ec42..0000000
--- a/drivers/video/backlight/locomolcd.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Backlight control code for Sharp Zaurus SL-5500
- *
- * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
- * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
- * GPL v2
- *
- * This driver assumes single CPU. That's okay, because collie is
- * slightly old hardware, and no one is going to retrofit second CPU to
- * old PDA.
- */
-
-/* LCD power functions */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-#include <asm/mach/sharpsl_param.h>
-#include <asm/mach-types.h>
-
-#include "../../../arch/arm/mach-sa1100/generic.h"
-
-static struct backlight_device *locomolcd_bl_device;
-static struct locomo_dev *locomolcd_dev;
-static unsigned long locomolcd_flags;
-#define LOCOMOLCD_SUSPENDED 0x01
-
-static void locomolcd_on(int comadj)
-{
- locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
- mdelay(2);
-
- locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
- mdelay(2);
-
- locomo_m62332_senddata(locomolcd_dev, comadj, 0);
- mdelay(5);
-
- locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
- mdelay(10);
-
- /* TFTCRST | CPSOUT=0 | CPSEN */
- locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
-
- /* Set CPSD */
- locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
-
- /* TFTCRST | CPSOUT=0 | CPSEN */
- locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
- mdelay(10);
-
- locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
-}
-
-static void locomolcd_off(int comadj)
-{
- /* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
- locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
- mdelay(1);
-
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
- mdelay(110);
-
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
- mdelay(700);
-
- /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
- locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
- locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-}
-
-void locomolcd_power(int on)
-{
- int comadj = sharpsl_param.comadj;
- unsigned long flags;
-
- local_irq_save(flags);
-
- if (!locomolcd_dev) {
- local_irq_restore(flags);
- return;
- }
-
- /* read comadj */
- if (comadj = -1 && machine_is_collie())
- comadj = 128;
- if (comadj = -1 && machine_is_poodle())
- comadj = 118;
-
- if (on)
- locomolcd_on(comadj);
- else
- locomolcd_off(comadj);
-
- local_irq_restore(flags);
-}
-EXPORT_SYMBOL(locomolcd_power);
-
-static int current_intensity;
-
-static int locomolcd_set_intensity(struct backlight_device *bd)
-{
- int intensity = bd->props.brightness;
-
- if (bd->props.power != FB_BLANK_UNBLANK)
- intensity = 0;
- if (bd->props.fb_blank != FB_BLANK_UNBLANK)
- intensity = 0;
- if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
- intensity = 0;
-
- switch (intensity) {
- /*
- * AC and non-AC are handled differently,
- * but produce same results in sharp code?
- */
- case 0:
- locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
- break;
- case 1:
- locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
- break;
- case 2:
- locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
- break;
- case 3:
- locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
- break;
- case 4:
- locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
- break;
- default:
- return -ENODEV;
- }
- current_intensity = intensity;
- return 0;
-}
-
-static int locomolcd_get_intensity(struct backlight_device *bd)
-{
- return current_intensity;
-}
-
-static const struct backlight_ops locomobl_data = {
- .get_brightness = locomolcd_get_intensity,
- .update_status = locomolcd_set_intensity,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int locomolcd_suspend(struct device *dev)
-{
- locomolcd_flags |= LOCOMOLCD_SUSPENDED;
- locomolcd_set_intensity(locomolcd_bl_device);
- return 0;
-}
-
-static int locomolcd_resume(struct device *dev)
-{
- locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
- locomolcd_set_intensity(locomolcd_bl_device);
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
-
-static int locomolcd_probe(struct locomo_dev *ldev)
-{
- struct backlight_properties props;
- unsigned long flags;
-
- local_irq_save(flags);
- locomolcd_dev = ldev;
-
- locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
- /*
- * the poodle_lcd_power function is called for the first time
- * from fs_initcall, which is before locomo is activated.
- * We need to recall poodle_lcd_power here
- */
- if (machine_is_poodle())
- locomolcd_power(1);
-
- local_irq_restore(flags);
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = 4;
- locomolcd_bl_device = backlight_device_register("locomo-bl",
- &ldev->dev, NULL,
- &locomobl_data, &props);
-
- if (IS_ERR(locomolcd_bl_device))
- return PTR_ERR(locomolcd_bl_device);
-
- /* Set up frontlight so that screen is readable */
- locomolcd_bl_device->props.brightness = 2;
- locomolcd_set_intensity(locomolcd_bl_device);
-
- return 0;
-}
-
-static int locomolcd_remove(struct locomo_dev *dev)
-{
- unsigned long flags;
-
- locomolcd_bl_device->props.brightness = 0;
- locomolcd_bl_device->props.power = 0;
- locomolcd_set_intensity(locomolcd_bl_device);
-
- backlight_device_unregister(locomolcd_bl_device);
- local_irq_save(flags);
- locomolcd_dev = NULL;
- local_irq_restore(flags);
- return 0;
-}
-
-static struct locomo_driver poodle_lcd_driver = {
- .drv = {
- .name = "locomo-backlight",
- .pm = &locomolcd_pm_ops,
- },
- .devid = LOCOMO_DEVID_BACKLIGHT,
- .probe = locomolcd_probe,
- .remove = locomolcd_remove,
-};
-
-static int __init locomolcd_init(void)
-{
- return locomo_driver_register(&poodle_lcd_driver);
-}
-
-static void __exit locomolcd_exit(void)
-{
- locomo_driver_unregister(&poodle_lcd_driver);
-}
-
-module_init(locomolcd_init);
-module_exit(locomolcd_exit);
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
-MODULE_DESCRIPTION("Collie LCD driver");
-MODULE_LICENSE("GPL");
--
2.1.1
^ permalink raw reply related
* [PATCH 08/15] ARM: sa1100: make collie use new locomo drivers
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:02 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-leds-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Switch collie to new mfd-based locomo driver.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/Kconfig | 1 -
arch/arm/mach-sa1100/collie.c | 112 +++++++++++++++--------------
arch/arm/mach-sa1100/include/mach/collie.h | 25 ++++++-
3 files changed, 79 insertions(+), 59 deletions(-)
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index c6f6ed1..37af126 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -48,7 +48,6 @@ endchoice
config SA1100_COLLIE
bool "Sharp Zaurus SL5500"
# FIXME: select ARM_SA11x0_CPUFREQ
- select SHARP_LOCOMO
select SHARP_PARAM
select SHARP_SCOOP
help
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 108939f..43d3291 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -24,6 +24,7 @@
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
+#include <linux/mfd/locomo.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/timer.h>
@@ -47,7 +48,6 @@
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
-#include <asm/hardware/locomo.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/irqs.h>
@@ -189,36 +189,54 @@ static struct platform_device collie_power_device = {
.num_resources = ARRAY_SIZE(collie_power_resource),
};
-#ifdef CONFIG_SHARP_LOCOMO
/*
* low-level UART features.
*/
-struct platform_device collie_locomo_device;
+static struct gpio collie_uart_gpio[] = {
+ { COLLIE_GPIO_CTS, GPIOF_IN, "CTS" },
+ { COLLIE_GPIO_RTS, GPIOF_OUT_INIT_LOW, "RTS" },
+ { COLLIE_GPIO_DTR, GPIOF_OUT_INIT_LOW, "DTR" },
+ { COLLIE_GPIO_DSR, GPIOF_IN, "DSR" },
+};
+
+static bool collie_uart_gpio_ok;
static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
{
- if (mctrl & TIOCM_RTS)
- locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
- else
- locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
-
- if (mctrl & TIOCM_DTR)
- locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
- else
- locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+ if (!collie_uart_gpio_ok) {
+ int rc = gpio_request_array(collie_uart_gpio,
+ ARRAY_SIZE(collie_uart_gpio));
+ if (rc)
+ pr_err("collie_uart_set_mctrl: gpio request %d\n", rc);
+ else
+ collie_uart_gpio_ok = true;
+ }
+
+ if (collie_uart_gpio_ok) {
+ gpio_set_value(COLLIE_GPIO_RTS, !(mctrl & TIOCM_RTS));
+ gpio_set_value(COLLIE_GPIO_DTR, !(mctrl & TIOCM_DTR));
+ }
}
static u_int collie_uart_get_mctrl(struct uart_port *port)
{
int ret = TIOCM_CD;
- unsigned int r;
- r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
- if (r = -ENODEV)
+ if (!collie_uart_gpio_ok) {
+ int rc = gpio_request_array(collie_uart_gpio,
+ ARRAY_SIZE(collie_uart_gpio));
+ if (rc)
+ pr_err("collie_uart_get_mctrl: gpio request %d\n", rc);
+ else
+ collie_uart_gpio_ok = true;
+ }
+
+ if (!collie_uart_gpio_ok)
return ret;
- if (r & LOCOMO_GPIO_CTS)
+
+ if (gpio_get_value(COLLIE_GPIO_CTS))
ret |= TIOCM_CTS;
- if (r & LOCOMO_GPIO_DSR)
+ if (gpio_get_value(COLLIE_GPIO_DSR))
ret |= TIOCM_DSR;
return ret;
@@ -229,33 +247,6 @@ static struct sa1100_port_fns collie_port_fns __initdata = {
.get_mctrl = collie_uart_get_mctrl,
};
-static int collie_uart_probe(struct locomo_dev *dev)
-{
- return 0;
-}
-
-static int collie_uart_remove(struct locomo_dev *dev)
-{
- return 0;
-}
-
-static struct locomo_driver collie_uart_driver = {
- .drv = {
- .name = "collie_uart",
- },
- .devid = LOCOMO_DEVID_UART,
- .probe = collie_uart_probe,
- .remove = collie_uart_remove,
-};
-
-static int __init collie_uart_init(void)
-{
- return locomo_driver_register(&collie_uart_driver);
-}
-device_initcall(collie_uart_init);
-
-#endif
-
static struct resource locomo_resources[] = {
[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
@@ -263,14 +254,28 @@ static struct resource locomo_resources[] = {
};
static struct locomo_platform_data locomo_info = {
- .irq_base = IRQ_BOARD_START,
+ .gpio_data = {
+ .gpio_base = COLLIE_LOCOMO_GPIO_BASE,
+ },
+ .lcd_data = {
+ .comadj = 128,
+ .gpio_lcd_vsha_on = COLLIE_GPIO_LCD_VSHA_ON,
+ .gpio_lcd_vshd_on = COLLIE_GPIO_LCD_VSHD_ON,
+ .gpio_lcd_vee_on = COLLIE_GPIO_LCD_VEE_ON,
+ .gpio_lcd_mod = COLLIE_GPIO_LCD_MOD,
+ },
+ .bl_data = {
+ .gpio_fl_vr = COLLIE_GPIO_FL_VR,
+ },
+ .gpio_amp1_on = COLLIE_GPIO_AMP1_ON,
+ .gpio_amp2_on = COLLIE_GPIO_AMP2_ON,
};
-struct platform_device collie_locomo_device = {
+static struct platform_device collie_locomo_device = {
.name = "locomo",
.id = 0,
.dev = {
- .platform_data = &locomo_info,
+ .platform_data = &locomo_info,
},
.num_resources = ARRAY_SIZE(locomo_resources),
.resource = locomo_resources,
@@ -385,10 +390,6 @@ static struct sa1100fb_mach_info collie_lcd_info = {
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-
-#ifdef CONFIG_BACKLIGHT_LOCOMO
- .lcd_power = locomolcd_power
-#endif
};
static void __init collie_init(void)
@@ -420,6 +421,8 @@ static void __init collie_init(void)
GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
+ sharpsl_save_param();
+
collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
@@ -428,6 +431,9 @@ static void __init collie_init(void)
platform_scoop_config = &collie_pcmcia_config;
+ if (sharpsl_param.comadj != -1)
+ locomo_info.lcd_data.comadj = sharpsl_param.comadj;
+
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret) {
printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
@@ -438,8 +444,6 @@ static void __init collie_init(void)
ARRAY_SIZE(collie_flash_resources));
sa11x0_register_mcp(&collie_mcp_data);
sa11x0_register_irda(&collie_ir_data);
-
- sharpsl_save_param();
}
static struct map_desc collie_io_desc[] __initdata = {
@@ -461,9 +465,7 @@ static void __init collie_map_io(void)
sa1100_map_io();
iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
-#ifdef CONFIG_SHARP_LOCOMO
sa1100_register_uart_fns(&collie_port_fns);
-#endif
sa1100_register_uart(0, 3);
sa1100_register_uart(1, 1);
}
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index b478ca1..22a7c7e 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -24,12 +24,12 @@ extern void locomolcd_power(int on);
#define COLLIE_SCP_MUTE_L SCOOP_GPCR_PA14
#define COLLIE_SCP_MUTE_R SCOOP_GPCR_PA15
#define COLLIE_SCP_5VON SCOOP_GPCR_PA16
-#define COLLIE_SCP_AMP_ON SCOOP_GPCR_PA17
+#define COLLIE_GPIO_AMP2_ON (COLLIE_SCOOP_GPIO_BASE + 6)
#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
#define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
- COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+ COLLIE_SCP_5VON | \
COLLIE_SCP_LB_VOL_CHG)
#define COLLIE_SCOOP_IO_OUT (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
@@ -81,7 +81,7 @@ extern void locomolcd_power(int on);
#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
#define COLLIE_GPIO_IR_ON (COLLIE_TC35143_GPIO_BASE + 3)
-#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
+#define COLLIE_GPIO_AMP1_ON (COLLIE_TC35143_GPIO_BASE + 4)
#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
@@ -92,4 +92,23 @@ extern void locomolcd_power(int on);
#define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
| UCB_IO_6)
+/* GPIOs on LoCoMo GA */
+#define COLLIE_LOCOMO_GPIO_BASE (GPIO_MAX + 23)
+#define COLLIE_GPIO_RTS (COLLIE_LOCOMO_GPIO_BASE + 0)
+#define COLLIE_GPIO_CTS (COLLIE_LOCOMO_GPIO_BASE + 1)
+#define COLLIE_GPIO_DSR (COLLIE_LOCOMO_GPIO_BASE + 2)
+#define COLLIE_GPIO_DTR (COLLIE_LOCOMO_GPIO_BASE + 3)
+#define COLLIE_GPIO_LCD_VSHA_ON (COLLIE_LOCOMO_GPIO_BASE + 4)
+#define COLLIE_GPIO_LCD_VSHD_ON (COLLIE_LOCOMO_GPIO_BASE + 5)
+#define COLLIE_GPIO_LCD_VEE_ON (COLLIE_LOCOMO_GPIO_BASE + 6)
+#define COLLIE_GPIO_LCD_MOD (COLLIE_LOCOMO_GPIO_BASE + 7)
+#define COLLIE_LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8)
+#define COLLIE_GPIO_FL_VR (COLLIE_LOCOMO_GPIO_BASE + 9)
+#define COLLIE_LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10)
+#define COLLIE_LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11)
+#define COLLIE_LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12)
+#define COLLIE_LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13)
+#define COLLIE_LOCOMO_GPIO_WRITE_PROT LOCOMO_GPIO(14)
+#define COLLIE_LOCOMO_GPIO_CARD_POWER LOCOMO_GPIO(15)
+
#endif
--
2.1.1
^ permalink raw reply related
* [PATCH 09/15] ARM: sa1100: don't preallocate IRQ space for locomo
From: Dmitry Eremin-Solenikov @ 2014-10-28 0:02 UTC (permalink / raw)
To: linux-arm-kernel, linux-gpio, linux-input, linux-leds, linux-spi,
linux-fbdev, alsa-devel
Cc: Andrea Adami, Russell King, Daniel Mack, Haojian Zhuang,
Robert Jarzmik, Linus Walleij, Alexandre Courbot, Dmitry Torokhov,
Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
Jingoo Han, Liam Girdwood
In-Reply-To: <1414454528-24240-1-git-send-email-dbaryshkov@gmail.com>
As new locomo driver properly supports SPARSE_IRQ, stop playing with
NR_IRQS on sa1100 (locomo was the last chip requiring NR_IRQ tricks).
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/include/mach/irqs.h | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 3790298..99e7202 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -68,22 +68,7 @@
#define IRQ_BOARD_START 49
#define IRQ_BOARD_END 65
-/*
- * Figure out the MAX IRQ number.
- *
- * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
- * allocate their IRQs above NR_IRQS.
- *
- * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
- * to be included in the NR_IRQS calculation.
- */
-#ifdef CONFIG_SHARP_LOCOMO
-#define NR_IRQS_LOCOMO 4
-#else
-#define NR_IRQS_LOCOMO 0
-#endif
-
#ifndef NR_IRQS
-#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define NR_IRQS IRQ_BOARD_START
#endif
-#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define SA1100_NR_IRQS IRQ_BOARD_START
--
2.1.1
^ 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