* [RFC PATCH 1/5] phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
From: Sylwester Nawrocki @ 2013-06-14 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1371231951-1969-1-git-send-email-s.nawrocki@samsung.com>
Add a PHY provider driver for the Samsung S5P/Exynos SoC MIPI CSI-2
receiver and MIPI DSI transmitter DPHYs.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
.../bindings/phy/exynos-video-mipi-phy.txt | 16 ++
drivers/phy/Kconfig | 10 ++
drivers/phy/Makefile | 3 +-
drivers/phy/exynos_video_mipi_phy.c | 166 ++++++++++++++++++++
4 files changed, 194 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/phy/exynos-video-mipi-phy.txt
create mode 100644 drivers/phy/exynos_video_mipi_phy.c
diff --git a/Documentation/devicetree/bindings/phy/exynos-video-mipi-phy.txt b/Documentation/devicetree/bindings/phy/exynos-video-mipi-phy.txt
new file mode 100644
index 0000000..32311c89
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/exynos-video-mipi-phy.txt
@@ -0,0 +1,16 @@
+Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
+-------------------------------------------------
+
+Required properties:
+- compatible : "samsung,<soc_name>-video-phy", currently most SoCs can claim
+ compatibility with the S5PV210 MIPI CSIS/DSIM PHY and thus should use
+ "samsung,s5pv210-video-phy";
+- reg : offset and length of the MIPI DPHY register set;
+- #phy-cells : from the generic phy bindings, must be 1;
+
+For "samsung,s5pv210-video-phy" compatible DPHYs the second cell in the PHY
+specifier identifies the DPHY and its meaning is as follows:
+ 0 - MIPI CSIS 0,
+ 1 - MIPI DSIM 0,
+ 2 - MIPI CSIS 1,
+ 3 - MIPI DSIM 1.
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 0764a54..d234e99 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -11,3 +11,13 @@ menuconfig GENERIC_PHY
devices present in the kernel. This layer will have the generic
API by which phy drivers can create PHY using the phy framework and
phy users can obtain reference to the PHY.
+
+if GENERIC_PHY
+
+config EXYNOS_VIDEO_MIPI_PHY
+ bool "S5P/EXYNOS MIPI CSI-2/DSI PHY driver"
+ depends on OF
+ help
+ Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung
+ S5P and EXYNOS SoCs.
+endif
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9e9560f..b16f2c1 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -2,4 +2,5 @@
# Makefile for the phy drivers.
#
-obj-$(CONFIG_GENERIC_PHY) += phy-core.o
+obj-$(CONFIG_GENERIC_PHY) += phy-core.o
+obj-$(CONFIG_EXYNOS_VIDEO_MIPI_PHY) += exynos_video_mipi_phy.o
diff --git a/drivers/phy/exynos_video_mipi_phy.c b/drivers/phy/exynos_video_mipi_phy.c
new file mode 100644
index 0000000..8d4976f
--- /dev/null
+++ b/drivers/phy/exynos_video_mipi_phy.c
@@ -0,0 +1,166 @@
+/*
+ * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* MIPI_PHYn_CONTROL register bit definitions */
+#define EXYNOS_MIPI_PHY_ENABLE (1 << 0)
+#define EXYNOS_MIPI_PHY_SRESETN (1 << 1)
+#define EXYNOS_MIPI_PHY_MRESETN (1 << 2)
+#define EXYNOS_MIPI_PHY_RESET_MASK (3 << 1)
+
+#define EXYNOS_MAX_VIDEO_PHYS 4
+
+struct exynos_video_phy {
+ spinlock_t slock;
+ struct phy *phys[EXYNOS_MAX_VIDEO_PHYS];
+ void __iomem *regs;
+};
+
+/*
+ * The @id argument specifies MIPI CSIS or DSIM PHY as follows:
+ * 0 - MIPI CSIS 0
+ * 1 - MIPI DSIM 0
+ * 2 - MIPI CSIS 1
+ * 3 - MIPI DSIM 1
+ */
+static int set_phy_state(struct exynos_video_phy *state,
+ unsigned int id, int on)
+{
+ void __iomem *addr = id < 2 ? state->regs : state->regs + 4;
+ unsigned long flags;
+ u32 reg, reset;
+
+ pr_debug("%s(): id: %d, on: %d, addr: %#x, base: %#x\n",
+ __func__, id, on, (u32)addr, (u32)state->regs);
+
+ if (WARN_ON(id > EXYNOS_MAX_VIDEO_PHYS))
+ return -EINVAL;
+
+ if (id & 1)
+ reset = EXYNOS_MIPI_PHY_MRESETN;
+ else
+ reset = EXYNOS_MIPI_PHY_SRESETN;
+
+ spin_lock_irqsave(&state->slock, flags);
+
+ reg = readl(addr);
+ if (on)
+ reg |= reset;
+ else
+ reg &= ~reset;
+ writel(reg, addr);
+
+ if (on)
+ reg |= EXYNOS_MIPI_PHY_ENABLE;
+ else if (!(reg & EXYNOS_MIPI_PHY_RESET_MASK))
+ reg &= ~EXYNOS_MIPI_PHY_ENABLE;
+
+ writel(reg, addr);
+
+ spin_unlock_irqrestore(&state->slock, flags);
+ return 0;
+}
+
+static int exynos_video_phy_power_on(struct phy *phy)
+{
+ struct exynos_video_phy *state = dev_get_drvdata(&phy->dev);
+ return set_phy_state(state, phy->id, 1);
+}
+
+static int exynos_video_phy_power_off(struct phy *phy)
+{
+ struct exynos_video_phy *state = dev_get_drvdata(&phy->dev);
+ return set_phy_state(state, phy->id, 0);
+}
+
+static struct phy *exynos_video_phy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct exynos_video_phy *state = dev_get_drvdata(dev);
+
+ if (WARN_ON(args->args[0] > EXYNOS_MAX_VIDEO_PHYS))
+ return NULL;
+
+ return state->phys[args->args[0]];
+}
+
+static struct phy_ops exynos_video_phy_ops = {
+ .power_on = exynos_video_phy_power_on,
+ .power_off = exynos_video_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int exynos_video_phy_probe(struct platform_device *pdev)
+{
+ struct exynos_video_phy *state;
+ struct device *dev = &pdev->dev;
+ struct resource res;
+ struct phy_provider *phy_provider;
+ int ret, i;
+
+ state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+
+ ret = of_address_to_resource(dev->of_node, 0, &res);
+ if (ret < 0)
+ return ret;
+
+ state->regs = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(state->regs))
+ return PTR_ERR(state->regs);
+
+ dev_set_drvdata(dev, state);
+
+ phy_provider = devm_of_phy_provider_register(dev, THIS_MODULE,
+ exynos_video_phy_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ for (i = 0; i < EXYNOS_MAX_VIDEO_PHYS; i++) {
+ state->phys[i] = devm_phy_create(dev, i, &exynos_video_phy_ops,
+ state);
+ if (IS_ERR(state->phys[i])) {
+ dev_err(dev, "failed to create PHY %d\n", i);
+ return PTR_ERR(state->phys[i]);
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id exynos_video_phy_of_match[] = {
+ { .compatible = "samsung,s5pv210-video-phy" },
+ { },
+};
+
+static struct platform_driver exynos_video_phy_driver = {
+ .probe = exynos_video_phy_probe,
+ .driver = {
+ .of_match_table = exynos_video_phy_of_match,
+ .name = "exynos-video-phy",
+ .owner = THIS_MODULE,
+ }
+};
+module_platform_driver(exynos_video_phy_driver);
+
+MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI CSI-2/DSI DPHY driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 0/5] Generic PHY driver for Exynos SoCs MIPI CSI-2/DSIM DPHYs
From: Sylwester Nawrocki @ 2013-06-14 17:45 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
The following is a simple driver for the Samsung S5P/Exynos SoCs MIPI CSI-2
receiver and MIPI DSI transmitter DPHYs, using the generic PHY framework [1].
Previously the MIPI CSIS and MIPI DSIM used a platform callback to control
the PHY power enable and reset bits. The callback can be dropped now and
those drivers don't depend any more on any platform code.
Any comments are welcome.
Thanks,
Sylwester
[1] https://lkml.org/lkml/2013/6/13/97
Sylwester Nawrocki (5):
phy: Add driver for Exynos MIPI CSIS/DSIM DPHYs
ARM: dts: Add MIPI PHY node to exynos4.dtsi
video: exynos_dsi: Use generic PHY driver
exynos4-is: Use generic MIPI CSIS PHY driver
ARM: Samsung: Remove MIPI PHY setup code
.../bindings/phy/exynos-video-mipi-phy.txt | 16 ++
arch/arm/boot/dts/exynos4.dtsi | 12 ++
arch/arm/mach-exynos/include/mach/regs-pmu.h | 5 -
arch/arm/mach-s5pv210/include/mach/regs-clock.h | 4 -
arch/arm/plat-samsung/Makefile | 1 -
arch/arm/plat-samsung/setup-mipiphy.c | 60 -------
drivers/media/platform/exynos4-is/mipi-csis.c | 11 +-
drivers/phy/Kconfig | 10 ++
drivers/phy/Makefile | 3 +-
drivers/phy/exynos_video_mipi_phy.c | 166 ++++++++++++++++++++
drivers/video/display/source-exynos_dsi.c | 36 ++---
include/linux/platform_data/mipi-csis.h | 9 --
include/video/exynos_dsi.h | 5 -
13 files changed, 226 insertions(+), 112 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/exynos-video-mipi-phy.txt
delete mode 100644 arch/arm/plat-samsung/setup-mipiphy.c
create mode 100644 drivers/phy/exynos_video_mipi_phy.c
--
1.7.9.5
^ permalink raw reply
* [GIT PULL] fbdev changes for 3.11
From: Tomi Valkeinen @ 2013-06-14 10:23 UTC (permalink / raw)
To: linux-fbdev
[-- Attachment #1: Type: text/plain, Size: 1462 bytes --]
The following changes since commit f722406faae2d073cc1d01063d1123c35425939e:
Linux 3.10-rc1 (2013-05-11 17:14:08 -0700)
are available in the git repository at:
git://gitorious.org/linux-omap-dss2/linux.git tags/fbdev-for-3.11
for you to fetch changes up to ffa3fd21de8ab0db7962b612d4c6e17c0d88e9c2:
videomode: implement public of_get_display_timing() (2013-05-28 14:42:52 +0300)
----------------------------------------------------------------
Small fbdev changes for 3.11
* Add of_get_display_timing() for parsing single DT entry
* Add support for SSD1306 OLED controller
* ssd1307fb performance improvements
----------------------------------------------------------------
Maxime Ripard (4):
video: ssd1307fb: Add support for SSD1306 OLED controller
video: ssd1307fb: Rework the communication functions
video: ssd1307fb: Speed up the communication with the controller
video: ssd1307fb: Make use of horizontal addressing mode
Tomi Valkeinen (2):
videomode: don't allocate mem in of_get_display_timing()
videomode: implement public of_get_display_timing()
.../devicetree/bindings/video/ssd1307fb.txt | 10 +-
drivers/video/of_display_timing.c | 55 ++-
drivers/video/ssd1307fb.c | 392 +++++++++++++++------
include/video/of_display_timing.h | 2 +
4 files changed, 339 insertions(+), 120 deletions(-)
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH v3] simplefb: add support for a8b8g8r8 pixel format
From: Alexandre Courbot @ 2013-06-14 10:18 UTC (permalink / raw)
To: Stephen Warren
Cc: Alexandre Courbot, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Olof Johansson, Linux Kernel Mailing List,
linux-fbdev@vger.kernel.org
In-Reply-To: <51B20922.4070504@wwwdotorg.org>
On Sat, Jun 8, 2013 at 1:24 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 06/07/2013 01:31 AM, Alexandre Courbot wrote:
>> A framebuffer of this format is set up by SHIELD's bootloader.
>>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>> Acked-by: Olof Johansson <olof@lixom.net>
>
> Reviewed-by: Stephen Warren <swarren@nvidia.com>
Jean-Christophe, Tomi, do you plan to merge this?
Alex.
^ permalink raw reply
* RE: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
From: Inki Dae @ 2013-06-14 2:32 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1371112088-15310-1-git-send-email-inki.dae@samsung.com>
Hi Russell,
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk]
> Sent: Friday, June 14, 2013 2:26 AM
> To: Inki Dae
> Cc: maarten.lankhorst@canonical.com; daniel@ffwll.ch; robdclark@gmail.com;
> linux-fbdev@vger.kernel.org; dri-devel@lists.freedesktop.org;
> kyungmin.park@samsung.com; myungjoo.ham@samsung.com; yj44.cho@samsung.com;
> linux-arm-kernel@lists.infradead.org; linux-media@vger.kernel.org
> Subject: Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization
> framework
>
> On Thu, Jun 13, 2013 at 05:28:08PM +0900, Inki Dae wrote:
> > This patch adds a buffer synchronization framework based on DMA BUF[1]
> > and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
> > for lock mechanism.
> >
> > The purpose of this framework is not only to couple cache operations,
> > and buffer access control to CPU and DMA but also to provide easy-to-use
> > interfaces for device drivers and potentially user application
> > (not implemented for user applications, yet). And this framework can be
> > used for all dma devices using system memory as dma buffer, especially
> > for most ARM based SoCs.
> >
> > The mechanism of this framework has the following steps,
> > 1. Register dmabufs to a sync object - A task gets a new sync object
> and
> > can add one or more dmabufs that the task wants to access.
> > This registering should be performed when a device context or an
> event
> > context such as a page flip event is created or before CPU accesses
a
> shared
> > buffer.
> >
> > dma_buf_sync_get(a sync object, a dmabuf);
> >
> > 2. Lock a sync object - A task tries to lock all dmabufs added in
its
> own
> > sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid
> dead
> > lock issue and for race condition between CPU and CPU, CPU and DMA,
> and DMA
> > and DMA. Taking a lock means that others cannot access all locked
> dmabufs
> > until the task that locked the corresponding dmabufs, unlocks all
the
> locked
> > dmabufs.
> > This locking should be performed before DMA or CPU accesses these
> dmabufs.
> >
> > dma_buf_sync_lock(a sync object);
> >
> > 3. Unlock a sync object - The task unlocks all dmabufs added in its
> own sync
> > object. The unlock means that the DMA or CPU accesses to the dmabufs
> have
> > been completed so that others may access them.
> > This unlocking should be performed after DMA or CPU has completed
> accesses
> > to the dmabufs.
> >
> > dma_buf_sync_unlock(a sync object);
> >
> > 4. Unregister one or all dmabufs from a sync object - A task
> unregisters
> > the given dmabufs from the sync object. This means that the task
> dosen't
> > want to lock the dmabufs.
> > The unregistering should be performed after DMA or CPU has completed
> > accesses to the dmabufs or when dma_buf_sync_lock() is failed.
> >
> > dma_buf_sync_put(a sync object, a dmabuf);
> > dma_buf_sync_put_all(a sync object);
> >
> > The described steps may be summarized as:
> > get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
> >
> > This framework includes the following two features.
> > 1. read (shared) and write (exclusive) locks - A task is required to
> declare
> > the access type when the task tries to register a dmabuf;
> > READ, WRITE, READ DMA, or WRITE DMA.
> >
> > The below is example codes,
> > struct dmabuf_sync *sync;
> >
> > sync = dmabuf_sync_init(NULL, "test sync");
> >
> > dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> > ...
> >
> > And the below can be used as access types:
> > DMA_BUF_ACCESS_READ,
> > - CPU will access a buffer for read.
> > DMA_BUF_ACCESS_WRITE,
> > - CPU will access a buffer for read or write.
> > DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
> > - DMA will access a buffer for read
> > DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
> > - DMA will access a buffer for read or write.
> >
> > 2. Mandatory resource releasing - a task cannot hold a lock
> indefinitely.
> > A task may never try to unlock a buffer after taking a lock to the
> buffer.
> > In this case, a timer handler to the corresponding sync object is
> called
> > in five (default) seconds and then the timed-out buffer is unlocked
> by work
> > queue handler to avoid lockups and to enforce resources of the
buffer.
> >
> > The below is how to use:
> > 1. Allocate and Initialize a sync object:
> > struct dmabuf_sync *sync;
> >
> > sync = dmabuf_sync_init(NULL, "test sync");
> > ...
> >
> > 2. Add a dmabuf to the sync object when setting up dma buffer
> relevant
> > registers:
> > dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> > ...
> >
> > 3. Lock all dmabufs of the sync object before DMA or CPU accesses
> > the dmabufs:
> > dmabuf_sync_lock(sync);
> > ...
> >
> > 4. Now CPU or DMA can access all dmabufs locked in step 3.
> >
> > 5. Unlock all dmabufs added in a sync object after DMA or CPU
> access
> > to these dmabufs is completed:
> > dmabuf_sync_unlock(sync);
> >
> > And call the following functions to release all resources,
> > dmabuf_sync_put_all(sync);
> > dmabuf_sync_fini(sync);
> >
> > You can refer to actual example codes:
> > https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-
> exynos.git/
> > commit/?h=dmabuf-
> sync&id@30bdee9bab5841ad32faade528d04cc0c5fc94
> >
> > https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-
> exynos.git/
> > commit/?h=dmabuf-
> sync&idla548e9ea9e865592719ef6b1cde58366af9f5c
> >
> > The framework performs cache operation based on the previous and current
> access
> > types to the dmabufs after the locks to all dmabufs are taken:
> > Call dma_buf_begin_cpu_access() to invalidate cache if,
> > previous access type is DMA_BUF_ACCESS_WRITE | DMA and
> > current access type is DMA_BUF_ACCESS_READ
> >
> > Call dma_buf_end_cpu_access() to clean cache if,
> > previous access type is DMA_BUF_ACCESS_WRITE and
> > current access type is DMA_BUF_ACCESS_READ | DMA
> >
> > Such cache operations are invoked via dma-buf interfaces so the dma buf
> exporter
> > should implement dmabuf->ops->begin_cpu_access/end_cpu_access callbacks.
> >
> > [1] http://lwn.net/Articles/470339/
> > [2] http://lwn.net/Articles/532616/
> > [3] https://patchwork-mail1.kernel.org/patch/2625321/
> >
> > Signed-off-by: Inki Dae <inki.dae@samsung.com>
> > ---
> > Documentation/dma-buf-sync.txt | 246 ++++++++++++++++++
> > drivers/base/Kconfig | 7 +
> > drivers/base/Makefile | 1 +
> > drivers/base/dmabuf-sync.c | 555
> ++++++++++++++++++++++++++++++++++++++++
> > include/linux/dma-buf.h | 5 +
> > include/linux/dmabuf-sync.h | 115 +++++++++
> > include/linux/reservation.h | 7 +
> > 7 files changed, 936 insertions(+), 0 deletions(-)
> > create mode 100644 Documentation/dma-buf-sync.txt
> > create mode 100644 drivers/base/dmabuf-sync.c
> > create mode 100644 include/linux/dmabuf-sync.h
> >
> > diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-
> sync.txt
> > new file mode 100644
> > index 0000000..e71b6f4
> > --- /dev/null
> > +++ b/Documentation/dma-buf-sync.txt
> > @@ -0,0 +1,246 @@
> > + DMA Buffer Synchronization Framework
> > + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > +
> > + Inki Dae
> > + <inki dot dae at samsung dot com>
> > + <daeinki at gmail dot com>
> > +
> > +This document is a guide for device-driver writers describing the DMA
> buffer
> > +synchronization API. This document also describes how to use the API to
> > +use buffer synchronization between CPU and CPU, CPU and DMA, and DMA
> and DMA.
> > +
> > +The DMA Buffer synchronization API provides buffer synchronization
> mechanism;
> > +i.e., buffer access control to CPU and DMA, cache operations, and easy-
> to-use
> > +interfaces for device drivers and potentially user application
> > +(not implemented for user applications, yet). And this API can be used
> for all
> > +dma devices using system memory as dma buffer, especially for most ARM
> based
> > +SoCs.
> > +
> > +
> > +Motivation
> > +----------
> > +
> > +Sharing a buffer, a device cannot be aware of when the other device
> will access
> > +the shared buffer: a device may access a buffer containing wrong data
> if
> > +the device accesses the shared buffer while another device is still
> accessing
> > +the shared buffer. Therefore, a user process should have waited for
> > +the completion of DMA access by another device before a device tries to
> access
> > +the shared buffer.
> > +
> > +Besides, there is the same issue when CPU and DMA are sharing a buffer;
> i.e.,
> > +a user process should consider that when the user process have to send
> a buffer
> > +to a device driver for the device driver to access the buffer as input.
> > +This means that a user process needs to understand how the device
> driver is
> > +worked. Hence, the conventional mechanism not only makes user
> application
> > +complicated but also incurs performance overhead because the
> conventional
> > +mechanism cannot control devices precisely without additional and
> complex
> > +implemantations.
> > +
> > +In addition, in case of ARM based SoCs, most devices have no hardware
> cache
> > +consistency mechanisms between CPU and DMA devices because they do not
> use ACP
> > +(Accelerator Coherency Port). ACP can be connected to DMA engine or
> similar
> > +devices in order to keep cache coherency between CPU cache and DMA
> device.
> > +Thus, we need additional cache operations to have the devices operate
> properly;
> > +i.e., user applications should request cache operations to kernel
> before DMA
> > +accesses the buffer and after the completion of buffer access by CPU,
> or vise
> > +versa.
> > +
> > + buffer access by CPU -> cache clean -> buffer access by DMA
> > +
> > +Or,
> > + buffer access by DMA -> cache invalidate -> buffer access by CPU
> > +
> > +The below shows why cache operations should be requested by user
> > +process,
> > + (Presume that CPU and DMA share a buffer and the buffer is mapped
> > + with user space as cachable)
> > +
> > + handle = drm_gem_alloc(size);
> > + ...
> > + va1 = drm_gem_mmap(handle1);
> > + va2 = malloc(size);
> > + ...
> > +
> > + while(conditions) {
> > + memcpy(va1, some data, size);
> > + ...
> > + drm_xxx_set_dma_buffer(handle, ...);
> > + ...
> > +
> > + /* user need to request cache clean at here. */
> > +
> > + /* blocked until dma operation is completed. */
> > + drm_xxx_start_dma(...);
> > + ...
> > +
> > + /* user need to request cache invalidate at here. */
> > +
> > + memcpy(va2, va1, size);
> > + }
> > +
> > +The issue arises: user processes may incur cache operations: user
> processes may
> > +request unnecessary cache operations to kernel. Besides, kernel cannot
> prevent
> > +user processes from requesting such cache operations. Therefore, we
> need to
> > +prevent such excessive and unnecessary cache operations from user
> processes.
> > +
> > +
> > +Basic concept
> > +-------------
> > +
> > +The mechanism of this framework has the following steps,
> > + 1. Register dmabufs to a sync object - A task gets a new sync
object
> and
> > + can add one or more dmabufs that the task wants to access.
> > + This registering should be performed when a device context or an
> event
> > + context such as a page flip event is created or before CPU accesses
> a shared
> > + buffer.
> > +
> > + dma_buf_sync_get(a sync object, a dmabuf);
> > +
> > + 2. Lock a sync object - A task tries to lock all dmabufs added in
> its own
> > + sync object. Basically, the lock mechanism uses ww-mutex[1] to
avoid
> dead
> > + lock issue and for race condition between CPU and CPU, CPU and DMA,
> and DMA
> > + and DMA. Taking a lock means that others cannot access all locked
> dmabufs
> > + until the task that locked the corresponding dmabufs, unlocks all
> the locked
> > + dmabufs.
> > + This locking should be performed before DMA or CPU accesses these
> dmabufs.
> > +
> > + dma_buf_sync_lock(a sync object);
> > +
> > + 3. Unlock a sync object - The task unlocks all dmabufs added in its
> own sync
> > + object. The unlock means that the DMA or CPU accesses to the
dmabufs
> have
> > + been completed so that others may access them.
> > + This unlocking should be performed after DMA or CPU has completed
> accesses
> > + to the dmabufs.
> > +
> > + dma_buf_sync_unlock(a sync object);
> > +
> > + 4. Unregister one or all dmabufs from a sync object - A task
> unregisters
> > + the given dmabufs from the sync object. This means that the task
> dosen't
> > + want to lock the dmabufs.
> > + The unregistering should be performed after DMA or CPU has
completed
> > + accesses to the dmabufs or when dma_buf_sync_lock() is failed.
> > +
> > + dma_buf_sync_put(a sync object, a dmabuf);
> > + dma_buf_sync_put_all(a sync object);
> > +
> > + The described steps may be summarized as:
> > + get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
> > +
> > +This framework includes the following two features.
> > + 1. read (shared) and write (exclusive) locks - A task is required
to
> declare
> > + the access type when the task tries to register a dmabuf;
> > + READ, WRITE, READ DMA, or WRITE DMA.
> > +
> > + The below is example codes,
> > + struct dmabuf_sync *sync;
> > +
> > + sync = dmabuf_sync_init(NULL, "test sync");
> > +
> > + dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> > + ...
> > +
> > + 2. Mandatory resource releasing - a task cannot hold a lock
> indefinitely.
> > + A task may never try to unlock a buffer after taking a lock to the
> buffer.
> > + In this case, a timer handler to the corresponding sync object is
> called
> > + in five (default) seconds and then the timed-out buffer is unlocked
> by work
> > + queue handler to avoid lockups and to enforce resources of the
> buffer.
> > +
> > +
> > +Access types
> > +------------
> > +
> > +DMA_BUF_ACCESS_READ - CPU will access a buffer for read.
> > +DMA_BUF_ACCESS_WRITE - CPU will access a buffer for read or write.
> > +DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA - DMA will access a buffer for
> read
> > +DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA - DMA will access a buffer
> for read
> > + or write.
> > +
> > +
> > +API set
> > +-------
> > +
> > +bool is_dmabuf_sync_supported(void)
> > + - Check if dmabuf sync is supported or not.
> > +
> > +struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
> > + - Allocate and initialize a new sync object. The caller can get a
> new
> > + sync object for buffer synchronization. priv is used to set
> caller's
> > + private data and name is the name of sync object.
> > +
> > +void dmabuf_sync_fini(struct dmabuf_sync *sync)
> > + - Release all resources to the sync object.
> > +
> > +int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
> > + unsigned int type)
> > + - Add a dmabuf to a sync object. The caller can group multiple
> dmabufs
> > + by calling this function several times. Internally, this function
> also
> > + takes a reference to a dmabuf.
> > +
> > +void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
> > + - Remove a given dmabuf from a sync object. Internally, this
> function
> > + also release every reference to the given dmabuf.
> > +
> > +void dmabuf_sync_put_all(struct dmabuf_sync *sync)
> > + - Remove all dmabufs added in a sync object. Internally, this
> function
> > + also release every reference to the dmabufs of the sync object.
> > +
> > +int dmabuf_sync_lock(struct dmabuf_sync *sync)
> > + - Lock all dmabufs added in a sync object. The caller should call
> this
> > + function prior to CPU or DMA access to the dmabufs so that others
> can
> > + not access the dmabufs. Internally, this function avoids dead lock
> > + issue with ww-mutex.
> > +
> > +int dmabuf_sync_unlock(struct dmabuf_sync *sync)
> > + - Unlock all dmabufs added in a sync object. The caller should call
> > + this function after CPU or DMA access to the dmabufs is completed
> so
> > + that others can access the dmabufs.
> > +
> > +
> > +Tutorial
> > +--------
> > +
> > +1. Allocate and Initialize a sync object:
> > + struct dmabuf_sync *sync;
> > +
> > + sync = dmabuf_sync_init(NULL, "test sync");
> > + ...
> > +
> > +2. Add a dmabuf to the sync object when setting up dma buffer relevant
> registers:
> > + dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> > + ...
> > +
> > +3. Lock all dmabufs of the sync object before DMA or CPU accesses the
> dmabufs:
> > + dmabuf_sync_lock(sync);
> > + ...
> > +
> > +4. Now CPU or DMA can access all dmabufs locked in step 3.
> > +
> > +5. Unlock all dmabufs added in a sync object after DMA or CPU access to
> these
> > + dmabufs is completed:
> > + dmabuf_sync_unlock(sync);
> > +
> > + And call the following functions to release all resources,
> > + dmabuf_sync_put_all(sync);
> > + dmabuf_sync_fini(sync);
> > +
> > +
> > +Cache operation
> > +---------------
> > +
> > +The framework performs cache operation based on the previous and
> current access
> > +types to the dmabufs after the locks to all dmabufs are taken:
> > + Call dma_buf_begin_cpu_access() to invalidate cache if,
> > + previous access type is DMA_BUF_ACCESS_WRITE | DMA and
> > + current access type is DMA_BUF_ACCESS_READ
> > +
> > + Call dma_buf_end_cpu_access() to clean cache if,
> > + previous access type is DMA_BUF_ACCESS_WRITE and
> > + current access type is DMA_BUF_ACCESS_READ | DMA
> > +
> > +Such cache operations are invoked via dma-buf interfaces. Thus, the dma
> buf
> > +exporter should implement dmabuf->ops->begin_cpu_access and
> end_cpu_access
> > +callbacks.
> > +
> > +
> > +References:
> > +[1] https://patchwork-mail1.kernel.org/patch/2625321/
> > diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
> > index 5ccf182..54a1d5a 100644
> > --- a/drivers/base/Kconfig
> > +++ b/drivers/base/Kconfig
> > @@ -212,6 +212,13 @@ config FENCE_TRACE
> > lockup related problems for dma-buffers shared across multiple
> > devices.
> >
> > +config DMABUF_SYNC
> > + bool "DMABUF Synchronization Framework"
> > + depends on DMA_SHARED_BUFFER
> > + help
> > + This option enables dmabuf sync framework for buffer
> synchronization between
> > + DMA and DMA, CPU and DMA, and CPU and CPU.
> > +
> > config CMA
> > bool "Contiguous Memory Allocator"
> > depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK
> > diff --git a/drivers/base/Makefile b/drivers/base/Makefile
> > index 8a55cb9..599f6c90 100644
> > --- a/drivers/base/Makefile
> > +++ b/drivers/base/Makefile
> > @@ -11,6 +11,7 @@ obj-y += power/
> > obj-$(CONFIG_HAS_DMA) += dma-mapping.o
> > obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
> > obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o fence.o reservation.o
> > +obj-$(CONFIG_DMABUF_SYNC) += dmabuf-sync.o
> > obj-$(CONFIG_ISA) += isa.o
> > obj-$(CONFIG_FW_LOADER) += firmware_class.o
> > obj-$(CONFIG_NUMA) += node.o
> > diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
> > new file mode 100644
> > index 0000000..c8723a5
> > --- /dev/null
> > +++ b/drivers/base/dmabuf-sync.c
> > @@ -0,0 +1,555 @@
> > +/*
> > + * Copyright (C) 2013 Samsung Electronics Co.Ltd
> > + * Authors:
> > + * Inki Dae <inki.dae@samsung.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
> modify it
> > + * under the terms of the GNU General Public License as published by
> the
> > + * Free Software Foundation; either version 2 of the License, or (at
> your
> > + * option) any later version.
> > + *
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/slab.h>
> > +#include <linux/debugfs.h>
> > +#include <linux/uaccess.h>
> > +
> > +#include <linux/dmabuf-sync.h>
> > +
> > +#define MAX_SYNC_TIMEOUT 5 /* Second. */
> > +
> > +#define NEED_BEGIN_CPU_ACCESS(old, new) \
> > + (old->accessed_type = (DMA_BUF_ACCESS_WRITE | \
> > + DMA_BUF_ACCESS_DMA) && \
> > + (new->access_type = DMA_BUF_ACCESS_READ))
> > +
> > +#define NEED_END_CPU_ACCESS(old, new) \
> > + (old->accessed_type = DMA_BUF_ACCESS_WRITE && \
> > + ((new->access_type = (DMA_BUF_ACCESS_READ | \
> > + DMA_BUF_ACCESS_DMA)) || \
> > + (new->access_type = (DMA_BUF_ACCESS_WRITE | \
> > + DMA_BUF_ACCESS_DMA))))
> > +
> > +int dmabuf_sync_enabled = 1;
> > +
> > +MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
> > +module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
> > +
> > +static void dmabuf_sync_timeout_worker(struct work_struct *work)
> > +{
> > + struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync,
> work);
> > + struct dmabuf_sync_object *sobj;
> > +
> > + mutex_lock(&sync->lock);
> > +
> > + list_for_each_entry(sobj, &sync->syncs, head) {
> > + if (WARN_ON(!sobj->robj))
> > + continue;
> > +
> > + printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
> > + "refcnt = %d, locked = %d]\n",
> > + sync->name, (u32)sobj->dmabuf,
> > + sobj->access_type,
> > +
atomic_read(&sobj->robj->shared_cnt),
> > + sobj->robj->locked);
> > +
> > + /* unlock only valid sync object. */
> > + if (!sobj->robj->locked)
> > + continue;
> > +
> > + if (sobj->robj->shared &&
> > + atomic_read(&sobj->robj->shared_cnt) > 1) {
> > + atomic_dec(&sobj->robj->shared_cnt);
>
> So, in my long standing complaints about atomic_t, this one really takes
> the biscuit. What makes you think that this is somehow safe?
>
> What happens if:
>
> shared_cnt = 2
> CPU0 CPU1
> atomic_read(&shared_cnt)
> atomic_read(&shared_cnt)
> atomic_dec(&shared_cnt)
> atomic_dec(&shared_cnt)
>
> Now, it's zero. That's not what the above code intends. You probably
> think that because it's called "atomic_*" it has some magical properties
> which saves you from stuff like this. I'm afraid it doesn't.
>
> sync->lock may save you from that, but if that's the case, why use
> atomic_t's anyway here because you're already in a protected region.
> But maybe not, because I see other uses of shared_cnt without this
> lock below.
It seems that you say dmabuf_sync_lock_objs function. Right, this function
doesn't use sync->lock. However, ww_mutex_lock would be used instead of it
there. So I think there also is in a protected region.
>
> I think you need to revisit this and think more carefully about how
> to deal with this counting. If you wish to continue using the
> atomic_* API, please take time to get familiar with it, and most
> importantly realise that virtually any sequence of:
>
> if some-condition-based-on atomic_read(&something)
> do something with atomic_*(&something)
>
> is a bug. Maybe take a look at atomic_add_unless() which can be used
> with negative values to decrement.
Thanks for your advice. Anyway, it's likely to better to use
atomic_add_unless even though protected.
Thanks,
Inki Dae
^ permalink raw reply
* Re: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
From: Russell King - ARM Linux @ 2013-06-13 17:26 UTC (permalink / raw)
To: Inki Dae
Cc: maarten.lankhorst, daniel, robdclark, linux-fbdev, dri-devel,
kyungmin.park, myungjoo.ham, yj44.cho, linux-arm-kernel,
linux-media
In-Reply-To: <1371112088-15310-1-git-send-email-inki.dae@samsung.com>
On Thu, Jun 13, 2013 at 05:28:08PM +0900, Inki Dae wrote:
> This patch adds a buffer synchronization framework based on DMA BUF[1]
> and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
> for lock mechanism.
>
> The purpose of this framework is not only to couple cache operations,
> and buffer access control to CPU and DMA but also to provide easy-to-use
> interfaces for device drivers and potentially user application
> (not implemented for user applications, yet). And this framework can be
> used for all dma devices using system memory as dma buffer, especially
> for most ARM based SoCs.
>
> The mechanism of this framework has the following steps,
> 1. Register dmabufs to a sync object - A task gets a new sync object and
> can add one or more dmabufs that the task wants to access.
> This registering should be performed when a device context or an event
> context such as a page flip event is created or before CPU accesses a shared
> buffer.
>
> dma_buf_sync_get(a sync object, a dmabuf);
>
> 2. Lock a sync object - A task tries to lock all dmabufs added in its own
> sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
> lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
> and DMA. Taking a lock means that others cannot access all locked dmabufs
> until the task that locked the corresponding dmabufs, unlocks all the locked
> dmabufs.
> This locking should be performed before DMA or CPU accesses these dmabufs.
>
> dma_buf_sync_lock(a sync object);
>
> 3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
> object. The unlock means that the DMA or CPU accesses to the dmabufs have
> been completed so that others may access them.
> This unlocking should be performed after DMA or CPU has completed accesses
> to the dmabufs.
>
> dma_buf_sync_unlock(a sync object);
>
> 4. Unregister one or all dmabufs from a sync object - A task unregisters
> the given dmabufs from the sync object. This means that the task dosen't
> want to lock the dmabufs.
> The unregistering should be performed after DMA or CPU has completed
> accesses to the dmabufs or when dma_buf_sync_lock() is failed.
>
> dma_buf_sync_put(a sync object, a dmabuf);
> dma_buf_sync_put_all(a sync object);
>
> The described steps may be summarized as:
> get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
>
> This framework includes the following two features.
> 1. read (shared) and write (exclusive) locks - A task is required to declare
> the access type when the task tries to register a dmabuf;
> READ, WRITE, READ DMA, or WRITE DMA.
>
> The below is example codes,
> struct dmabuf_sync *sync;
>
> sync = dmabuf_sync_init(NULL, "test sync");
>
> dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> ...
>
> And the below can be used as access types:
> DMA_BUF_ACCESS_READ,
> - CPU will access a buffer for read.
> DMA_BUF_ACCESS_WRITE,
> - CPU will access a buffer for read or write.
> DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
> - DMA will access a buffer for read
> DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
> - DMA will access a buffer for read or write.
>
> 2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
> A task may never try to unlock a buffer after taking a lock to the buffer.
> In this case, a timer handler to the corresponding sync object is called
> in five (default) seconds and then the timed-out buffer is unlocked by work
> queue handler to avoid lockups and to enforce resources of the buffer.
>
> The below is how to use:
> 1. Allocate and Initialize a sync object:
> struct dmabuf_sync *sync;
>
> sync = dmabuf_sync_init(NULL, "test sync");
> ...
>
> 2. Add a dmabuf to the sync object when setting up dma buffer relevant
> registers:
> dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> ...
>
> 3. Lock all dmabufs of the sync object before DMA or CPU accesses
> the dmabufs:
> dmabuf_sync_lock(sync);
> ...
>
> 4. Now CPU or DMA can access all dmabufs locked in step 3.
>
> 5. Unlock all dmabufs added in a sync object after DMA or CPU access
> to these dmabufs is completed:
> dmabuf_sync_unlock(sync);
>
> And call the following functions to release all resources,
> dmabuf_sync_put_all(sync);
> dmabuf_sync_fini(sync);
>
> You can refer to actual example codes:
> https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/
> commit/?h=dmabuf-sync&id@30bdee9bab5841ad32faade528d04cc0c5fc94
>
> https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/
> commit/?h=dmabuf-sync&idla548e9ea9e865592719ef6b1cde58366af9f5c
>
> The framework performs cache operation based on the previous and current access
> types to the dmabufs after the locks to all dmabufs are taken:
> Call dma_buf_begin_cpu_access() to invalidate cache if,
> previous access type is DMA_BUF_ACCESS_WRITE | DMA and
> current access type is DMA_BUF_ACCESS_READ
>
> Call dma_buf_end_cpu_access() to clean cache if,
> previous access type is DMA_BUF_ACCESS_WRITE and
> current access type is DMA_BUF_ACCESS_READ | DMA
>
> Such cache operations are invoked via dma-buf interfaces so the dma buf exporter
> should implement dmabuf->ops->begin_cpu_access/end_cpu_access callbacks.
>
> [1] http://lwn.net/Articles/470339/
> [2] http://lwn.net/Articles/532616/
> [3] https://patchwork-mail1.kernel.org/patch/2625321/
>
> Signed-off-by: Inki Dae <inki.dae@samsung.com>
> ---
> Documentation/dma-buf-sync.txt | 246 ++++++++++++++++++
> drivers/base/Kconfig | 7 +
> drivers/base/Makefile | 1 +
> drivers/base/dmabuf-sync.c | 555 ++++++++++++++++++++++++++++++++++++++++
> include/linux/dma-buf.h | 5 +
> include/linux/dmabuf-sync.h | 115 +++++++++
> include/linux/reservation.h | 7 +
> 7 files changed, 936 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/dma-buf-sync.txt
> create mode 100644 drivers/base/dmabuf-sync.c
> create mode 100644 include/linux/dmabuf-sync.h
>
> diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-sync.txt
> new file mode 100644
> index 0000000..e71b6f4
> --- /dev/null
> +++ b/Documentation/dma-buf-sync.txt
> @@ -0,0 +1,246 @@
> + DMA Buffer Synchronization Framework
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> + Inki Dae
> + <inki dot dae at samsung dot com>
> + <daeinki at gmail dot com>
> +
> +This document is a guide for device-driver writers describing the DMA buffer
> +synchronization API. This document also describes how to use the API to
> +use buffer synchronization between CPU and CPU, CPU and DMA, and DMA and DMA.
> +
> +The DMA Buffer synchronization API provides buffer synchronization mechanism;
> +i.e., buffer access control to CPU and DMA, cache operations, and easy-to-use
> +interfaces for device drivers and potentially user application
> +(not implemented for user applications, yet). And this API can be used for all
> +dma devices using system memory as dma buffer, especially for most ARM based
> +SoCs.
> +
> +
> +Motivation
> +----------
> +
> +Sharing a buffer, a device cannot be aware of when the other device will access
> +the shared buffer: a device may access a buffer containing wrong data if
> +the device accesses the shared buffer while another device is still accessing
> +the shared buffer. Therefore, a user process should have waited for
> +the completion of DMA access by another device before a device tries to access
> +the shared buffer.
> +
> +Besides, there is the same issue when CPU and DMA are sharing a buffer; i.e.,
> +a user process should consider that when the user process have to send a buffer
> +to a device driver for the device driver to access the buffer as input.
> +This means that a user process needs to understand how the device driver is
> +worked. Hence, the conventional mechanism not only makes user application
> +complicated but also incurs performance overhead because the conventional
> +mechanism cannot control devices precisely without additional and complex
> +implemantations.
> +
> +In addition, in case of ARM based SoCs, most devices have no hardware cache
> +consistency mechanisms between CPU and DMA devices because they do not use ACP
> +(Accelerator Coherency Port). ACP can be connected to DMA engine or similar
> +devices in order to keep cache coherency between CPU cache and DMA device.
> +Thus, we need additional cache operations to have the devices operate properly;
> +i.e., user applications should request cache operations to kernel before DMA
> +accesses the buffer and after the completion of buffer access by CPU, or vise
> +versa.
> +
> + buffer access by CPU -> cache clean -> buffer access by DMA
> +
> +Or,
> + buffer access by DMA -> cache invalidate -> buffer access by CPU
> +
> +The below shows why cache operations should be requested by user
> +process,
> + (Presume that CPU and DMA share a buffer and the buffer is mapped
> + with user space as cachable)
> +
> + handle = drm_gem_alloc(size);
> + ...
> + va1 = drm_gem_mmap(handle1);
> + va2 = malloc(size);
> + ...
> +
> + while(conditions) {
> + memcpy(va1, some data, size);
> + ...
> + drm_xxx_set_dma_buffer(handle, ...);
> + ...
> +
> + /* user need to request cache clean at here. */
> +
> + /* blocked until dma operation is completed. */
> + drm_xxx_start_dma(...);
> + ...
> +
> + /* user need to request cache invalidate at here. */
> +
> + memcpy(va2, va1, size);
> + }
> +
> +The issue arises: user processes may incur cache operations: user processes may
> +request unnecessary cache operations to kernel. Besides, kernel cannot prevent
> +user processes from requesting such cache operations. Therefore, we need to
> +prevent such excessive and unnecessary cache operations from user processes.
> +
> +
> +Basic concept
> +-------------
> +
> +The mechanism of this framework has the following steps,
> + 1. Register dmabufs to a sync object - A task gets a new sync object and
> + can add one or more dmabufs that the task wants to access.
> + This registering should be performed when a device context or an event
> + context such as a page flip event is created or before CPU accesses a shared
> + buffer.
> +
> + dma_buf_sync_get(a sync object, a dmabuf);
> +
> + 2. Lock a sync object - A task tries to lock all dmabufs added in its own
> + sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
> + lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
> + and DMA. Taking a lock means that others cannot access all locked dmabufs
> + until the task that locked the corresponding dmabufs, unlocks all the locked
> + dmabufs.
> + This locking should be performed before DMA or CPU accesses these dmabufs.
> +
> + dma_buf_sync_lock(a sync object);
> +
> + 3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
> + object. The unlock means that the DMA or CPU accesses to the dmabufs have
> + been completed so that others may access them.
> + This unlocking should be performed after DMA or CPU has completed accesses
> + to the dmabufs.
> +
> + dma_buf_sync_unlock(a sync object);
> +
> + 4. Unregister one or all dmabufs from a sync object - A task unregisters
> + the given dmabufs from the sync object. This means that the task dosen't
> + want to lock the dmabufs.
> + The unregistering should be performed after DMA or CPU has completed
> + accesses to the dmabufs or when dma_buf_sync_lock() is failed.
> +
> + dma_buf_sync_put(a sync object, a dmabuf);
> + dma_buf_sync_put_all(a sync object);
> +
> + The described steps may be summarized as:
> + get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
> +
> +This framework includes the following two features.
> + 1. read (shared) and write (exclusive) locks - A task is required to declare
> + the access type when the task tries to register a dmabuf;
> + READ, WRITE, READ DMA, or WRITE DMA.
> +
> + The below is example codes,
> + struct dmabuf_sync *sync;
> +
> + sync = dmabuf_sync_init(NULL, "test sync");
> +
> + dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> + ...
> +
> + 2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
> + A task may never try to unlock a buffer after taking a lock to the buffer.
> + In this case, a timer handler to the corresponding sync object is called
> + in five (default) seconds and then the timed-out buffer is unlocked by work
> + queue handler to avoid lockups and to enforce resources of the buffer.
> +
> +
> +Access types
> +------------
> +
> +DMA_BUF_ACCESS_READ - CPU will access a buffer for read.
> +DMA_BUF_ACCESS_WRITE - CPU will access a buffer for read or write.
> +DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA - DMA will access a buffer for read
> +DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA - DMA will access a buffer for read
> + or write.
> +
> +
> +API set
> +-------
> +
> +bool is_dmabuf_sync_supported(void)
> + - Check if dmabuf sync is supported or not.
> +
> +struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
> + - Allocate and initialize a new sync object. The caller can get a new
> + sync object for buffer synchronization. priv is used to set caller's
> + private data and name is the name of sync object.
> +
> +void dmabuf_sync_fini(struct dmabuf_sync *sync)
> + - Release all resources to the sync object.
> +
> +int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
> + unsigned int type)
> + - Add a dmabuf to a sync object. The caller can group multiple dmabufs
> + by calling this function several times. Internally, this function also
> + takes a reference to a dmabuf.
> +
> +void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
> + - Remove a given dmabuf from a sync object. Internally, this function
> + also release every reference to the given dmabuf.
> +
> +void dmabuf_sync_put_all(struct dmabuf_sync *sync)
> + - Remove all dmabufs added in a sync object. Internally, this function
> + also release every reference to the dmabufs of the sync object.
> +
> +int dmabuf_sync_lock(struct dmabuf_sync *sync)
> + - Lock all dmabufs added in a sync object. The caller should call this
> + function prior to CPU or DMA access to the dmabufs so that others can
> + not access the dmabufs. Internally, this function avoids dead lock
> + issue with ww-mutex.
> +
> +int dmabuf_sync_unlock(struct dmabuf_sync *sync)
> + - Unlock all dmabufs added in a sync object. The caller should call
> + this function after CPU or DMA access to the dmabufs is completed so
> + that others can access the dmabufs.
> +
> +
> +Tutorial
> +--------
> +
> +1. Allocate and Initialize a sync object:
> + struct dmabuf_sync *sync;
> +
> + sync = dmabuf_sync_init(NULL, "test sync");
> + ...
> +
> +2. Add a dmabuf to the sync object when setting up dma buffer relevant registers:
> + dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
> + ...
> +
> +3. Lock all dmabufs of the sync object before DMA or CPU accesses the dmabufs:
> + dmabuf_sync_lock(sync);
> + ...
> +
> +4. Now CPU or DMA can access all dmabufs locked in step 3.
> +
> +5. Unlock all dmabufs added in a sync object after DMA or CPU access to these
> + dmabufs is completed:
> + dmabuf_sync_unlock(sync);
> +
> + And call the following functions to release all resources,
> + dmabuf_sync_put_all(sync);
> + dmabuf_sync_fini(sync);
> +
> +
> +Cache operation
> +---------------
> +
> +The framework performs cache operation based on the previous and current access
> +types to the dmabufs after the locks to all dmabufs are taken:
> + Call dma_buf_begin_cpu_access() to invalidate cache if,
> + previous access type is DMA_BUF_ACCESS_WRITE | DMA and
> + current access type is DMA_BUF_ACCESS_READ
> +
> + Call dma_buf_end_cpu_access() to clean cache if,
> + previous access type is DMA_BUF_ACCESS_WRITE and
> + current access type is DMA_BUF_ACCESS_READ | DMA
> +
> +Such cache operations are invoked via dma-buf interfaces. Thus, the dma buf
> +exporter should implement dmabuf->ops->begin_cpu_access and end_cpu_access
> +callbacks.
> +
> +
> +References:
> +[1] https://patchwork-mail1.kernel.org/patch/2625321/
> diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
> index 5ccf182..54a1d5a 100644
> --- a/drivers/base/Kconfig
> +++ b/drivers/base/Kconfig
> @@ -212,6 +212,13 @@ config FENCE_TRACE
> lockup related problems for dma-buffers shared across multiple
> devices.
>
> +config DMABUF_SYNC
> + bool "DMABUF Synchronization Framework"
> + depends on DMA_SHARED_BUFFER
> + help
> + This option enables dmabuf sync framework for buffer synchronization between
> + DMA and DMA, CPU and DMA, and CPU and CPU.
> +
> config CMA
> bool "Contiguous Memory Allocator"
> depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK
> diff --git a/drivers/base/Makefile b/drivers/base/Makefile
> index 8a55cb9..599f6c90 100644
> --- a/drivers/base/Makefile
> +++ b/drivers/base/Makefile
> @@ -11,6 +11,7 @@ obj-y += power/
> obj-$(CONFIG_HAS_DMA) += dma-mapping.o
> obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
> obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o fence.o reservation.o
> +obj-$(CONFIG_DMABUF_SYNC) += dmabuf-sync.o
> obj-$(CONFIG_ISA) += isa.o
> obj-$(CONFIG_FW_LOADER) += firmware_class.o
> obj-$(CONFIG_NUMA) += node.o
> diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
> new file mode 100644
> index 0000000..c8723a5
> --- /dev/null
> +++ b/drivers/base/dmabuf-sync.c
> @@ -0,0 +1,555 @@
> +/*
> + * Copyright (C) 2013 Samsung Electronics Co.Ltd
> + * Authors:
> + * Inki Dae <inki.dae@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/debugfs.h>
> +#include <linux/uaccess.h>
> +
> +#include <linux/dmabuf-sync.h>
> +
> +#define MAX_SYNC_TIMEOUT 5 /* Second. */
> +
> +#define NEED_BEGIN_CPU_ACCESS(old, new) \
> + (old->accessed_type = (DMA_BUF_ACCESS_WRITE | \
> + DMA_BUF_ACCESS_DMA) && \
> + (new->access_type = DMA_BUF_ACCESS_READ))
> +
> +#define NEED_END_CPU_ACCESS(old, new) \
> + (old->accessed_type = DMA_BUF_ACCESS_WRITE && \
> + ((new->access_type = (DMA_BUF_ACCESS_READ | \
> + DMA_BUF_ACCESS_DMA)) || \
> + (new->access_type = (DMA_BUF_ACCESS_WRITE | \
> + DMA_BUF_ACCESS_DMA))))
> +
> +int dmabuf_sync_enabled = 1;
> +
> +MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
> +module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
> +
> +static void dmabuf_sync_timeout_worker(struct work_struct *work)
> +{
> + struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync, work);
> + struct dmabuf_sync_object *sobj;
> +
> + mutex_lock(&sync->lock);
> +
> + list_for_each_entry(sobj, &sync->syncs, head) {
> + if (WARN_ON(!sobj->robj))
> + continue;
> +
> + printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
> + "refcnt = %d, locked = %d]\n",
> + sync->name, (u32)sobj->dmabuf,
> + sobj->access_type,
> + atomic_read(&sobj->robj->shared_cnt),
> + sobj->robj->locked);
> +
> + /* unlock only valid sync object. */
> + if (!sobj->robj->locked)
> + continue;
> +
> + if (sobj->robj->shared &&
> + atomic_read(&sobj->robj->shared_cnt) > 1) {
> + atomic_dec(&sobj->robj->shared_cnt);
So, in my long standing complaints about atomic_t, this one really takes
the biscuit. What makes you think that this is somehow safe?
What happens if:
shared_cnt = 2
CPU0 CPU1
atomic_read(&shared_cnt)
atomic_read(&shared_cnt)
atomic_dec(&shared_cnt)
atomic_dec(&shared_cnt)
Now, it's zero. That's not what the above code intends. You probably
think that because it's called "atomic_*" it has some magical properties
which saves you from stuff like this. I'm afraid it doesn't.
sync->lock may save you from that, but if that's the case, why use
atomic_t's anyway here because you're already in a protected region.
But maybe not, because I see other uses of shared_cnt without this
lock below.
I think you need to revisit this and think more carefully about how
to deal with this counting. If you wish to continue using the
atomic_* API, please take time to get familiar with it, and most
importantly realise that virtually any sequence of:
if some-condition-based-on atomic_read(&something)
do something with atomic_*(&something)
is a bug. Maybe take a look at atomic_add_unless() which can be used
with negative values to decrement.
^ permalink raw reply
* RE: [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
From: Inki Dae @ 2013-06-13 11:25 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1371112088-15310-1-git-send-email-inki.dae@samsung.com>
> +static void dmabuf_sync_timeout_worker(struct work_struct *work)
> +{
> + struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync,
> work);
> + struct dmabuf_sync_object *sobj;
> +
> + mutex_lock(&sync->lock);
> +
> + list_for_each_entry(sobj, &sync->syncs, head) {
> + if (WARN_ON(!sobj->robj))
> + continue;
> +
> + printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
> + "refcnt = %d, locked = %d]\n",
> + sync->name, (u32)sobj->dmabuf,
> + sobj->access_type,
> +
atomic_read(&sobj->robj->shared_cnt),
> + sobj->robj->locked);
> +
> + /* unlock only valid sync object. */
> + if (!sobj->robj->locked)
> + continue;
> +
> + if (sobj->robj->shared &&
> + atomic_read(&sobj->robj->shared_cnt) > 1) {
> + atomic_dec(&sobj->robj->shared_cnt);
> + continue;
> + }
> +
> + ww_mutex_unlock(&sobj->robj->lock);
> +
> + if (sobj->access_type & DMA_BUF_ACCESS_READ)
> + printk(KERN_WARNING "%s: r-unlocked = 0x%x\n",
> + sync->name, (u32)sobj->dmabuf);
> + else
> + printk(KERN_WARNING "%s: w-unlocked = 0x%x\n",
> + sync->name, (u32)sobj->dmabuf);
> +
> +#if defined(CONFIG_DEBUG_FS)
> + sync_debugfs_timeout_cnt++;
> +#endif
Oops, unnecessary codes. will remove them.
^ permalink raw reply
* [RFC PATCH] dmabuf-sync: Introduce buffer synchronization framework
From: Inki Dae @ 2013-06-13 8:28 UTC (permalink / raw)
To: maarten.lankhorst, daniel, robdclark
Cc: linux-fbdev, dri-devel, linux-arm-kernel, linux-media,
kyungmin.park, myungjoo.ham, yj44.cho, Inki Dae
This patch adds a buffer synchronization framework based on DMA BUF[1]
and reservation[2] to use dma-buf resource, and based on ww-mutexes[3]
for lock mechanism.
The purpose of this framework is not only to couple cache operations,
and buffer access control to CPU and DMA but also to provide easy-to-use
interfaces for device drivers and potentially user application
(not implemented for user applications, yet). And this framework can be
used for all dma devices using system memory as dma buffer, especially
for most ARM based SoCs.
The mechanism of this framework has the following steps,
1. Register dmabufs to a sync object - A task gets a new sync object and
can add one or more dmabufs that the task wants to access.
This registering should be performed when a device context or an event
context such as a page flip event is created or before CPU accesses a shared
buffer.
dma_buf_sync_get(a sync object, a dmabuf);
2. Lock a sync object - A task tries to lock all dmabufs added in its own
sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
and DMA. Taking a lock means that others cannot access all locked dmabufs
until the task that locked the corresponding dmabufs, unlocks all the locked
dmabufs.
This locking should be performed before DMA or CPU accesses these dmabufs.
dma_buf_sync_lock(a sync object);
3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
object. The unlock means that the DMA or CPU accesses to the dmabufs have
been completed so that others may access them.
This unlocking should be performed after DMA or CPU has completed accesses
to the dmabufs.
dma_buf_sync_unlock(a sync object);
4. Unregister one or all dmabufs from a sync object - A task unregisters
the given dmabufs from the sync object. This means that the task dosen't
want to lock the dmabufs.
The unregistering should be performed after DMA or CPU has completed
accesses to the dmabufs or when dma_buf_sync_lock() is failed.
dma_buf_sync_put(a sync object, a dmabuf);
dma_buf_sync_put_all(a sync object);
The described steps may be summarized as:
get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
This framework includes the following two features.
1. read (shared) and write (exclusive) locks - A task is required to declare
the access type when the task tries to register a dmabuf;
READ, WRITE, READ DMA, or WRITE DMA.
The below is example codes,
struct dmabuf_sync *sync;
sync = dmabuf_sync_init(NULL, "test sync");
dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
...
And the below can be used as access types:
DMA_BUF_ACCESS_READ,
- CPU will access a buffer for read.
DMA_BUF_ACCESS_WRITE,
- CPU will access a buffer for read or write.
DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA,
- DMA will access a buffer for read
DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA,
- DMA will access a buffer for read or write.
2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
A task may never try to unlock a buffer after taking a lock to the buffer.
In this case, a timer handler to the corresponding sync object is called
in five (default) seconds and then the timed-out buffer is unlocked by work
queue handler to avoid lockups and to enforce resources of the buffer.
The below is how to use:
1. Allocate and Initialize a sync object:
struct dmabuf_sync *sync;
sync = dmabuf_sync_init(NULL, "test sync");
...
2. Add a dmabuf to the sync object when setting up dma buffer relevant
registers:
dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
...
3. Lock all dmabufs of the sync object before DMA or CPU accesses
the dmabufs:
dmabuf_sync_lock(sync);
...
4. Now CPU or DMA can access all dmabufs locked in step 3.
5. Unlock all dmabufs added in a sync object after DMA or CPU access
to these dmabufs is completed:
dmabuf_sync_unlock(sync);
And call the following functions to release all resources,
dmabuf_sync_put_all(sync);
dmabuf_sync_fini(sync);
You can refer to actual example codes:
https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/
commit/?h=dmabuf-sync&id@30bdee9bab5841ad32faade528d04cc0c5fc94
https://git.kernel.org/cgit/linux/kernel/git/daeinki/drm-exynos.git/
commit/?h=dmabuf-sync&idla548e9ea9e865592719ef6b1cde58366af9f5c
The framework performs cache operation based on the previous and current access
types to the dmabufs after the locks to all dmabufs are taken:
Call dma_buf_begin_cpu_access() to invalidate cache if,
previous access type is DMA_BUF_ACCESS_WRITE | DMA and
current access type is DMA_BUF_ACCESS_READ
Call dma_buf_end_cpu_access() to clean cache if,
previous access type is DMA_BUF_ACCESS_WRITE and
current access type is DMA_BUF_ACCESS_READ | DMA
Such cache operations are invoked via dma-buf interfaces so the dma buf exporter
should implement dmabuf->ops->begin_cpu_access/end_cpu_access callbacks.
[1] http://lwn.net/Articles/470339/
[2] http://lwn.net/Articles/532616/
[3] https://patchwork-mail1.kernel.org/patch/2625321/
Signed-off-by: Inki Dae <inki.dae@samsung.com>
---
Documentation/dma-buf-sync.txt | 246 ++++++++++++++++++
drivers/base/Kconfig | 7 +
drivers/base/Makefile | 1 +
drivers/base/dmabuf-sync.c | 555 ++++++++++++++++++++++++++++++++++++++++
include/linux/dma-buf.h | 5 +
include/linux/dmabuf-sync.h | 115 +++++++++
include/linux/reservation.h | 7 +
7 files changed, 936 insertions(+), 0 deletions(-)
create mode 100644 Documentation/dma-buf-sync.txt
create mode 100644 drivers/base/dmabuf-sync.c
create mode 100644 include/linux/dmabuf-sync.h
diff --git a/Documentation/dma-buf-sync.txt b/Documentation/dma-buf-sync.txt
new file mode 100644
index 0000000..e71b6f4
--- /dev/null
+++ b/Documentation/dma-buf-sync.txt
@@ -0,0 +1,246 @@
+ DMA Buffer Synchronization Framework
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Inki Dae
+ <inki dot dae at samsung dot com>
+ <daeinki at gmail dot com>
+
+This document is a guide for device-driver writers describing the DMA buffer
+synchronization API. This document also describes how to use the API to
+use buffer synchronization between CPU and CPU, CPU and DMA, and DMA and DMA.
+
+The DMA Buffer synchronization API provides buffer synchronization mechanism;
+i.e., buffer access control to CPU and DMA, cache operations, and easy-to-use
+interfaces for device drivers and potentially user application
+(not implemented for user applications, yet). And this API can be used for all
+dma devices using system memory as dma buffer, especially for most ARM based
+SoCs.
+
+
+Motivation
+----------
+
+Sharing a buffer, a device cannot be aware of when the other device will access
+the shared buffer: a device may access a buffer containing wrong data if
+the device accesses the shared buffer while another device is still accessing
+the shared buffer. Therefore, a user process should have waited for
+the completion of DMA access by another device before a device tries to access
+the shared buffer.
+
+Besides, there is the same issue when CPU and DMA are sharing a buffer; i.e.,
+a user process should consider that when the user process have to send a buffer
+to a device driver for the device driver to access the buffer as input.
+This means that a user process needs to understand how the device driver is
+worked. Hence, the conventional mechanism not only makes user application
+complicated but also incurs performance overhead because the conventional
+mechanism cannot control devices precisely without additional and complex
+implemantations.
+
+In addition, in case of ARM based SoCs, most devices have no hardware cache
+consistency mechanisms between CPU and DMA devices because they do not use ACP
+(Accelerator Coherency Port). ACP can be connected to DMA engine or similar
+devices in order to keep cache coherency between CPU cache and DMA device.
+Thus, we need additional cache operations to have the devices operate properly;
+i.e., user applications should request cache operations to kernel before DMA
+accesses the buffer and after the completion of buffer access by CPU, or vise
+versa.
+
+ buffer access by CPU -> cache clean -> buffer access by DMA
+
+Or,
+ buffer access by DMA -> cache invalidate -> buffer access by CPU
+
+The below shows why cache operations should be requested by user
+process,
+ (Presume that CPU and DMA share a buffer and the buffer is mapped
+ with user space as cachable)
+
+ handle = drm_gem_alloc(size);
+ ...
+ va1 = drm_gem_mmap(handle1);
+ va2 = malloc(size);
+ ...
+
+ while(conditions) {
+ memcpy(va1, some data, size);
+ ...
+ drm_xxx_set_dma_buffer(handle, ...);
+ ...
+
+ /* user need to request cache clean at here. */
+
+ /* blocked until dma operation is completed. */
+ drm_xxx_start_dma(...);
+ ...
+
+ /* user need to request cache invalidate at here. */
+
+ memcpy(va2, va1, size);
+ }
+
+The issue arises: user processes may incur cache operations: user processes may
+request unnecessary cache operations to kernel. Besides, kernel cannot prevent
+user processes from requesting such cache operations. Therefore, we need to
+prevent such excessive and unnecessary cache operations from user processes.
+
+
+Basic concept
+-------------
+
+The mechanism of this framework has the following steps,
+ 1. Register dmabufs to a sync object - A task gets a new sync object and
+ can add one or more dmabufs that the task wants to access.
+ This registering should be performed when a device context or an event
+ context such as a page flip event is created or before CPU accesses a shared
+ buffer.
+
+ dma_buf_sync_get(a sync object, a dmabuf);
+
+ 2. Lock a sync object - A task tries to lock all dmabufs added in its own
+ sync object. Basically, the lock mechanism uses ww-mutex[1] to avoid dead
+ lock issue and for race condition between CPU and CPU, CPU and DMA, and DMA
+ and DMA. Taking a lock means that others cannot access all locked dmabufs
+ until the task that locked the corresponding dmabufs, unlocks all the locked
+ dmabufs.
+ This locking should be performed before DMA or CPU accesses these dmabufs.
+
+ dma_buf_sync_lock(a sync object);
+
+ 3. Unlock a sync object - The task unlocks all dmabufs added in its own sync
+ object. The unlock means that the DMA or CPU accesses to the dmabufs have
+ been completed so that others may access them.
+ This unlocking should be performed after DMA or CPU has completed accesses
+ to the dmabufs.
+
+ dma_buf_sync_unlock(a sync object);
+
+ 4. Unregister one or all dmabufs from a sync object - A task unregisters
+ the given dmabufs from the sync object. This means that the task dosen't
+ want to lock the dmabufs.
+ The unregistering should be performed after DMA or CPU has completed
+ accesses to the dmabufs or when dma_buf_sync_lock() is failed.
+
+ dma_buf_sync_put(a sync object, a dmabuf);
+ dma_buf_sync_put_all(a sync object);
+
+ The described steps may be summarized as:
+ get -> lock -> CPU or DMA access to a buffer/s -> unlock -> put
+
+This framework includes the following two features.
+ 1. read (shared) and write (exclusive) locks - A task is required to declare
+ the access type when the task tries to register a dmabuf;
+ READ, WRITE, READ DMA, or WRITE DMA.
+
+ The below is example codes,
+ struct dmabuf_sync *sync;
+
+ sync = dmabuf_sync_init(NULL, "test sync");
+
+ dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
+ ...
+
+ 2. Mandatory resource releasing - a task cannot hold a lock indefinitely.
+ A task may never try to unlock a buffer after taking a lock to the buffer.
+ In this case, a timer handler to the corresponding sync object is called
+ in five (default) seconds and then the timed-out buffer is unlocked by work
+ queue handler to avoid lockups and to enforce resources of the buffer.
+
+
+Access types
+------------
+
+DMA_BUF_ACCESS_READ - CPU will access a buffer for read.
+DMA_BUF_ACCESS_WRITE - CPU will access a buffer for read or write.
+DMA_BUF_ACCESS_READ | DMA_BUF_ACCESS_DMA - DMA will access a buffer for read
+DMA_BUF_ACCESS_WRITE | DMA_BUF_ACCESS_DMA - DMA will access a buffer for read
+ or write.
+
+
+API set
+-------
+
+bool is_dmabuf_sync_supported(void)
+ - Check if dmabuf sync is supported or not.
+
+struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
+ - Allocate and initialize a new sync object. The caller can get a new
+ sync object for buffer synchronization. priv is used to set caller's
+ private data and name is the name of sync object.
+
+void dmabuf_sync_fini(struct dmabuf_sync *sync)
+ - Release all resources to the sync object.
+
+int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
+ unsigned int type)
+ - Add a dmabuf to a sync object. The caller can group multiple dmabufs
+ by calling this function several times. Internally, this function also
+ takes a reference to a dmabuf.
+
+void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
+ - Remove a given dmabuf from a sync object. Internally, this function
+ also release every reference to the given dmabuf.
+
+void dmabuf_sync_put_all(struct dmabuf_sync *sync)
+ - Remove all dmabufs added in a sync object. Internally, this function
+ also release every reference to the dmabufs of the sync object.
+
+int dmabuf_sync_lock(struct dmabuf_sync *sync)
+ - Lock all dmabufs added in a sync object. The caller should call this
+ function prior to CPU or DMA access to the dmabufs so that others can
+ not access the dmabufs. Internally, this function avoids dead lock
+ issue with ww-mutex.
+
+int dmabuf_sync_unlock(struct dmabuf_sync *sync)
+ - Unlock all dmabufs added in a sync object. The caller should call
+ this function after CPU or DMA access to the dmabufs is completed so
+ that others can access the dmabufs.
+
+
+Tutorial
+--------
+
+1. Allocate and Initialize a sync object:
+ struct dmabuf_sync *sync;
+
+ sync = dmabuf_sync_init(NULL, "test sync");
+ ...
+
+2. Add a dmabuf to the sync object when setting up dma buffer relevant registers:
+ dmabuf_sync_get(sync, dmabuf, DMA_BUF_ACCESS_READ);
+ ...
+
+3. Lock all dmabufs of the sync object before DMA or CPU accesses the dmabufs:
+ dmabuf_sync_lock(sync);
+ ...
+
+4. Now CPU or DMA can access all dmabufs locked in step 3.
+
+5. Unlock all dmabufs added in a sync object after DMA or CPU access to these
+ dmabufs is completed:
+ dmabuf_sync_unlock(sync);
+
+ And call the following functions to release all resources,
+ dmabuf_sync_put_all(sync);
+ dmabuf_sync_fini(sync);
+
+
+Cache operation
+---------------
+
+The framework performs cache operation based on the previous and current access
+types to the dmabufs after the locks to all dmabufs are taken:
+ Call dma_buf_begin_cpu_access() to invalidate cache if,
+ previous access type is DMA_BUF_ACCESS_WRITE | DMA and
+ current access type is DMA_BUF_ACCESS_READ
+
+ Call dma_buf_end_cpu_access() to clean cache if,
+ previous access type is DMA_BUF_ACCESS_WRITE and
+ current access type is DMA_BUF_ACCESS_READ | DMA
+
+Such cache operations are invoked via dma-buf interfaces. Thus, the dma buf
+exporter should implement dmabuf->ops->begin_cpu_access and end_cpu_access
+callbacks.
+
+
+References:
+[1] https://patchwork-mail1.kernel.org/patch/2625321/
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 5ccf182..54a1d5a 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -212,6 +212,13 @@ config FENCE_TRACE
lockup related problems for dma-buffers shared across multiple
devices.
+config DMABUF_SYNC
+ bool "DMABUF Synchronization Framework"
+ depends on DMA_SHARED_BUFFER
+ help
+ This option enables dmabuf sync framework for buffer synchronization between
+ DMA and DMA, CPU and DMA, and CPU and CPU.
+
config CMA
bool "Contiguous Memory Allocator"
depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 8a55cb9..599f6c90 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -11,6 +11,7 @@ obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o fence.o reservation.o
+obj-$(CONFIG_DMABUF_SYNC) += dmabuf-sync.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
diff --git a/drivers/base/dmabuf-sync.c b/drivers/base/dmabuf-sync.c
new file mode 100644
index 0000000..c8723a5
--- /dev/null
+++ b/drivers/base/dmabuf-sync.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co.Ltd
+ * Authors:
+ * Inki Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <linux/dmabuf-sync.h>
+
+#define MAX_SYNC_TIMEOUT 5 /* Second. */
+
+#define NEED_BEGIN_CPU_ACCESS(old, new) \
+ (old->accessed_type = (DMA_BUF_ACCESS_WRITE | \
+ DMA_BUF_ACCESS_DMA) && \
+ (new->access_type = DMA_BUF_ACCESS_READ))
+
+#define NEED_END_CPU_ACCESS(old, new) \
+ (old->accessed_type = DMA_BUF_ACCESS_WRITE && \
+ ((new->access_type = (DMA_BUF_ACCESS_READ | \
+ DMA_BUF_ACCESS_DMA)) || \
+ (new->access_type = (DMA_BUF_ACCESS_WRITE | \
+ DMA_BUF_ACCESS_DMA))))
+
+int dmabuf_sync_enabled = 1;
+
+MODULE_PARM_DESC(enabled, "Check if dmabuf sync is supported or not");
+module_param_named(enabled, dmabuf_sync_enabled, int, 0444);
+
+static void dmabuf_sync_timeout_worker(struct work_struct *work)
+{
+ struct dmabuf_sync *sync = container_of(work, struct dmabuf_sync, work);
+ struct dmabuf_sync_object *sobj;
+
+ mutex_lock(&sync->lock);
+
+ list_for_each_entry(sobj, &sync->syncs, head) {
+ if (WARN_ON(!sobj->robj))
+ continue;
+
+ printk(KERN_WARNING "%s: timeout = 0x%x [type = %d, " \
+ "refcnt = %d, locked = %d]\n",
+ sync->name, (u32)sobj->dmabuf,
+ sobj->access_type,
+ atomic_read(&sobj->robj->shared_cnt),
+ sobj->robj->locked);
+
+ /* unlock only valid sync object. */
+ if (!sobj->robj->locked)
+ continue;
+
+ if (sobj->robj->shared &&
+ atomic_read(&sobj->robj->shared_cnt) > 1) {
+ atomic_dec(&sobj->robj->shared_cnt);
+ continue;
+ }
+
+ ww_mutex_unlock(&sobj->robj->lock);
+
+ if (sobj->access_type & DMA_BUF_ACCESS_READ)
+ printk(KERN_WARNING "%s: r-unlocked = 0x%x\n",
+ sync->name, (u32)sobj->dmabuf);
+ else
+ printk(KERN_WARNING "%s: w-unlocked = 0x%x\n",
+ sync->name, (u32)sobj->dmabuf);
+
+#if defined(CONFIG_DEBUG_FS)
+ sync_debugfs_timeout_cnt++;
+#endif
+ }
+
+ sync->status = 0;
+ mutex_unlock(&sync->lock);
+
+ dmabuf_sync_put_all(sync);
+ dmabuf_sync_fini(sync);
+}
+
+static void dmabuf_sync_cache_ops(struct dmabuf_sync *sync)
+{
+ struct dmabuf_sync_object *sobj;
+
+ mutex_lock(&sync->lock);
+
+ list_for_each_entry(sobj, &sync->syncs, head) {
+ struct dma_buf *dmabuf;
+
+ dmabuf = sobj->dmabuf;
+ if (WARN_ON(!dmabuf || !sobj->robj))
+ continue;
+
+ /* first time access. */
+ if (!sobj->robj->accessed_type)
+ goto out;
+
+ if (NEED_END_CPU_ACCESS(sobj->robj, sobj))
+ /* cache clean */
+ dma_buf_end_cpu_access(dmabuf, 0, dmabuf->size,
+ DMA_TO_DEVICE);
+ else if (NEED_BEGIN_CPU_ACCESS(sobj->robj, sobj))
+ /* cache invalidate */
+ dma_buf_begin_cpu_access(dmabuf, 0, dmabuf->size,
+ DMA_FROM_DEVICE);
+
+out:
+ /* Update access type to new one. */
+ sobj->robj->accessed_type = sobj->access_type;
+ }
+
+ mutex_unlock(&sync->lock);
+}
+
+static void dmabuf_sync_lock_timeout(unsigned long arg)
+{
+ struct dmabuf_sync *sync = (struct dmabuf_sync *)arg;
+
+ schedule_work(&sync->work);
+}
+
+static int dmabuf_sync_lock_objs(struct dmabuf_sync *sync,
+ struct ww_acquire_ctx *ctx)
+{
+ struct dmabuf_sync_object *contended_sobj = NULL;
+ struct dmabuf_sync_object *res_sobj = NULL;
+ struct dmabuf_sync_object *sobj = NULL;
+ int ret;
+
+ if (ctx)
+ ww_acquire_init(ctx, &reservation_ww_class);
+
+retry:
+ list_for_each_entry(sobj, &sync->syncs, head) {
+ if (WARN_ON(!sobj->robj))
+ continue;
+
+ /* Don't lock in case of read and read. */
+ if (sobj->robj->accessed_type & DMA_BUF_ACCESS_READ &&
+ sobj->access_type & DMA_BUF_ACCESS_READ) {
+ atomic_inc(&sobj->robj->shared_cnt);
+ sobj->robj->shared = true;
+ continue;
+ }
+
+ if (sobj = res_sobj) {
+ res_sobj = NULL;
+ continue;
+ }
+
+ ret = ww_mutex_lock(&sobj->robj->lock, ctx);
+ if (ret < 0) {
+ contended_sobj = sobj;
+
+ if (ret = -EDEADLK)
+ printk(KERN_WARNING"%s: deadlock = 0x%x\n",
+ sync->name, (u32)sobj->dmabuf);
+ goto err;
+ }
+
+ sobj->robj->locked = true;
+ }
+
+ if (ctx)
+ ww_acquire_done(ctx);
+
+ init_timer(&sync->timer);
+
+ sync->timer.data = (unsigned long)sync;
+ sync->timer.function = dmabuf_sync_lock_timeout;
+ sync->timer.expires = jiffies + (HZ * MAX_SYNC_TIMEOUT);
+
+ add_timer(&sync->timer);
+
+ return 0;
+
+err:
+ list_for_each_entry_continue_reverse(sobj, &sync->syncs, head) {
+ /* Don't need to unlock in case of read and read. */
+ if (atomic_read(&sobj->robj->shared_cnt) > 1) {
+ atomic_dec(&sobj->robj->shared_cnt);
+ continue;
+ }
+
+ ww_mutex_unlock(&sobj->robj->lock);
+ sobj->robj->locked = false;
+ }
+
+ if (res_sobj) {
+ if (atomic_read(&res_sobj->robj->shared_cnt) > 1)
+ atomic_dec(&res_sobj->robj->shared_cnt);
+ else {
+ ww_mutex_unlock(&res_sobj->robj->lock);
+ res_sobj->robj->locked = false;
+ }
+ }
+
+ if (ret = -EDEADLK) {
+ ww_mutex_lock_slow(&contended_sobj->robj->lock, ctx);
+ res_sobj = contended_sobj;
+
+ goto retry;
+ }
+
+ if (ctx)
+ ww_acquire_fini(ctx);
+
+ return ret;
+}
+
+static void dmabuf_sync_unlock_objs(struct dmabuf_sync *sync,
+ struct ww_acquire_ctx *ctx)
+{
+ struct dmabuf_sync_object *sobj;
+
+ if (list_empty(&sync->syncs))
+ return;
+
+ mutex_lock(&sync->lock);
+
+ list_for_each_entry(sobj, &sync->syncs, head) {
+ if (sobj->robj->shared) {
+ if (atomic_read(&sobj->robj->shared_cnt) > 1) {
+ atomic_dec(&sobj->robj->shared_cnt);
+ continue;
+ }
+
+ ww_mutex_unlock(&sobj->robj->lock);
+ sobj->robj->shared = false;
+ sobj->robj->locked = false;
+ } else {
+ ww_mutex_unlock(&sobj->robj->lock);
+ sobj->robj->locked = false;
+ }
+ }
+
+ mutex_unlock(&sync->lock);
+
+ if (ctx)
+ ww_acquire_fini(ctx);
+
+ del_timer(&sync->timer);
+}
+
+/**
+ * is_dmabuf_sync_supported - Check if dmabuf sync is supported or not.
+ */
+bool is_dmabuf_sync_supported(void)
+{
+ return dmabuf_sync_enabled = 1;
+}
+EXPORT_SYMBOL(is_dmabuf_sync_supported);
+
+/**
+ * dmabuf_sync_init - Allocate and initialize a dmabuf sync.
+ *
+ * @priv: A device private data.
+ * @name: A sync object name.
+ *
+ * This function should be called when a device context or an event
+ * context such as a page flip event is created. And the created
+ * dmabuf_sync object should be set to the context.
+ * The caller can get a new sync object for buffer synchronization
+ * through this function.
+ */
+struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name)
+{
+ struct dmabuf_sync *sync;
+
+ sync = kzalloc(sizeof(*sync), GFP_KERNEL);
+ if (!sync)
+ return ERR_PTR(-ENOMEM);
+
+ strncpy(sync->name, name, ARRAY_SIZE(sync->name) - 1);
+
+ sync->priv = priv;
+ INIT_LIST_HEAD(&sync->syncs);
+ mutex_init(&sync->lock);
+ INIT_WORK(&sync->work, dmabuf_sync_timeout_worker);
+
+ return sync;
+}
+EXPORT_SYMBOL(dmabuf_sync_init);
+
+/**
+ * dmabuf_sync_fini - Release a given dmabuf sync.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * This function should be called if some operation is failed after
+ * dmabuf_sync_init call to release relevant resources, and after
+ * dmabuf_sync_unlock function is called.
+ */
+void dmabuf_sync_fini(struct dmabuf_sync *sync)
+{
+ if (WARN_ON(!sync))
+ return;
+
+ kfree(sync);
+}
+EXPORT_SYMBOL(dmabuf_sync_fini);
+
+/*
+ * dmabuf_sync_get_obj - Add a given object to syncs list.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ * @dmabuf: An object to dma_buf structure.
+ * @type: A access type to a dma buf.
+ * The DMA_BUF_ACCESS_READ means that this dmabuf could be accessed by
+ * others for read access. On the other hand, the DMA_BUF_ACCESS_WRITE
+ * means that this dmabuf couldn't be accessed by others but would be
+ * accessed by caller's dma exclusively. And the DMA_BUF_ACCESS_DMA can be
+ * combined.
+ *
+ * This function creates and initializes a new dmabuf sync object and it adds
+ * the dmabuf sync object to syncs list to track and manage all dmabufs.
+ */
+static int dmabuf_sync_get_obj(struct dmabuf_sync *sync, struct dma_buf *dmabuf,
+ unsigned int type)
+{
+ struct dmabuf_sync_object *sobj;
+
+ if (!dmabuf->resv) {
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ sobj = kzalloc(sizeof(*sobj), GFP_KERNEL);
+ if (!sobj) {
+ WARN_ON(1);
+ return -ENOMEM;
+ }
+
+ sobj->dmabuf = dmabuf;
+ sobj->robj = dmabuf->resv;
+
+ mutex_lock(&sync->lock);
+ list_add_tail(&sobj->head, &sync->syncs);
+ mutex_unlock(&sync->lock);
+
+ get_dma_buf(dmabuf);
+
+ sobj->access_type = type;
+
+ return 0;
+}
+
+/*
+ * dmabuf_sync_put_obj - Release a given sync object.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * This function should be called if some operation is failed after
+ * dmabuf_sync_get_obj call to release a given sync object.
+ */
+static void dmabuf_sync_put_obj(struct dmabuf_sync *sync,
+ struct dma_buf *dmabuf)
+{
+ struct dmabuf_sync_object *sobj;
+
+ mutex_lock(&sync->lock);
+
+ list_for_each_entry(sobj, &sync->syncs, head) {
+ if (sobj->dmabuf != dmabuf)
+ continue;
+
+ dma_buf_put(sobj->dmabuf);
+
+ list_del_init(&sobj->head);
+ kfree(sobj);
+ break;
+ }
+
+ if (list_empty(&sync->syncs))
+ sync->status = 0;
+
+ mutex_unlock(&sync->lock);
+}
+
+/*
+ * dmabuf_sync_put_objs - Release all sync objects of dmabuf_sync.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * This function should be called if some operation is failed after
+ * dmabuf_sync_get_obj call to release all sync objects.
+ */
+static void dmabuf_sync_put_objs(struct dmabuf_sync *sync)
+{
+ struct dmabuf_sync_object *sobj, *next;
+
+ mutex_lock(&sync->lock);
+
+ list_for_each_entry_safe(sobj, next, &sync->syncs, head) {
+ dma_buf_put(sobj->dmabuf);
+
+ list_del_init(&sobj->head);
+ kfree(sobj);
+ }
+
+ mutex_unlock(&sync->lock);
+
+ sync->status = 0;
+}
+
+/**
+ * dmabuf_sync_lock - lock all dmabufs added to syncs list.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * The caller should call this function prior to CPU or DMA access to
+ * the dmabufs so that others can not access the dmabufs.
+ * Internally, this function avoids dead lock issue with ww-mutex.
+ */
+int dmabuf_sync_lock(struct dmabuf_sync *sync)
+{
+ int ret;
+
+ if (!sync) {
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ if (list_empty(&sync->syncs))
+ return -EINVAL;
+
+ if (sync->status != DMABUF_SYNC_GOT)
+ return -EINVAL;
+
+ ret = dmabuf_sync_lock_objs(sync, &sync->ctx);
+ if (ret < 0) {
+ WARN_ON(1);
+ return ret;
+ }
+
+ sync->status = DMABUF_SYNC_LOCKED;
+
+ dmabuf_sync_cache_ops(sync);
+
+ return ret;
+}
+EXPORT_SYMBOL(dmabuf_sync_lock);
+
+/**
+ * dmabuf_sync_unlock - unlock all objects added to syncs list.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * The caller should call this function after CPU or DMA access to
+ * the dmabufs is completed so that others can access the dmabufs.
+ */
+int dmabuf_sync_unlock(struct dmabuf_sync *sync)
+{
+ if (!sync) {
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ /* If current dmabuf sync object wasn't reserved then just return. */
+ if (sync->status != DMABUF_SYNC_LOCKED)
+ return -EAGAIN;
+
+ dmabuf_sync_unlock_objs(sync, &sync->ctx);
+
+ return 0;
+}
+EXPORT_SYMBOL(dmabuf_sync_unlock);
+
+/**
+ * dmabuf_sync_get - initialize reservation entry and update
+ * dmabuf sync.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ * @sync_buf: A dma_buf object pointer that we want to be synchronized
+ * with others.
+ *
+ * This function should be called after dmabuf_sync_init function is called.
+ * The caller can group multiple dmabufs by calling this function several
+ * times. Internally, this function also takes a reference to a dmabuf.
+ */
+int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf, unsigned int type)
+{
+ int ret;
+
+ if (!sync || !sync_buf) {
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ ret = dmabuf_sync_get_obj(sync, sync_buf, type);
+ if (ret < 0) {
+ WARN_ON(1);
+ return ret;
+ }
+
+ sync->status = DMABUF_SYNC_GOT;
+
+ return 0;
+}
+EXPORT_SYMBOL(dmabuf_sync_get);
+
+/**
+ * dmabuf_sync_put - Release a given dmabuf.
+ *
+ * @sync: An object to dmabuf_sync structure.
+ * @dmabuf: An object to dma_buf structure.
+ *
+ * This function should be called if some operation is failed after
+ * dmabuf_sync_get function is called to release the dmabuf, or
+ * dmabuf_sync_unlock function is called.
+ */
+void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf)
+{
+ if (!sync || !dmabuf) {
+ WARN_ON(1);
+ return;
+ }
+
+ if (list_empty(&sync->syncs))
+ return;
+
+ dmabuf_sync_put_obj(sync, dmabuf);
+}
+EXPORT_SYMBOL(dmabuf_sync_put);
+
+/**
+ * dmabuf_sync_put_all - Release all sync objects
+ *
+ * @sync: An object to dmabuf_sync structure.
+ *
+ * This function should be called if some operation is failed after
+ * dmabuf_sync_get function is called to release all sync objects, or
+ * dmabuf_sync_unlock function is called.
+ */
+void dmabuf_sync_put_all(struct dmabuf_sync *sync)
+{
+ if (!sync) {
+ WARN_ON(1);
+ return;
+ }
+
+ if (list_empty(&sync->syncs))
+ return;
+
+ dmabuf_sync_put_objs(sync);
+}
+EXPORT_SYMBOL(dmabuf_sync_put_all);
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 34cfbac..f320c8e 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -150,6 +150,11 @@ struct dma_buf_attachment {
void *priv;
};
+#define DMA_BUF_ACCESS_READ 0x1
+#define DMA_BUF_ACCESS_WRITE 0x2
+#define DMA_BUF_ACCESS_DMA 0x4
+#define DMA_BUF_ACCESS_MAX 0x8
+
/**
* get_dma_buf - convenience wrapper for get_file.
* @dmabuf: [in] pointer to dma_buf
diff --git a/include/linux/dmabuf-sync.h b/include/linux/dmabuf-sync.h
new file mode 100644
index 0000000..44c37de
--- /dev/null
+++ b/include/linux/dmabuf-sync.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co.Ltd
+ * Authors:
+ * Inki Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/dma-buf.h>
+#include <linux/reservation.h>
+
+enum dmabuf_sync_status {
+ DMABUF_SYNC_GOT = 1,
+ DMABUF_SYNC_LOCKED,
+};
+
+/*
+ * A structure for dmabuf_sync_object.
+ *
+ * @head: A list head to be added to syncs list.
+ * @robj: A reservation_object object.
+ * @dma_buf: A dma_buf object.
+ * @access_type: Indicate how a current task tries to access
+ * a given buffer.
+ */
+struct dmabuf_sync_object {
+ struct list_head head;
+ struct reservation_object *robj;
+ struct dma_buf *dmabuf;
+ unsigned int access_type;
+};
+
+/*
+ * A structure for dmabuf_sync.
+ *
+ * @syncs: A list head to sync object and this is global to system.
+ * @list: A list entry used as committed list node
+ * @lock: A mutex lock to current sync object.
+ * @ctx: A current context for ww mutex.
+ * @work: A work struct to release resources at timeout.
+ * @priv: A private data.
+ * @name: A string to dmabuf sync owner.
+ * @timer: A timer list to avoid lockup and release resources.
+ * @status: Indicate current status (DMABUF_SYNC_GOT or DMABUF_SYNC_LOCKED).
+ */
+struct dmabuf_sync {
+ struct list_head syncs;
+ struct list_head list;
+ struct mutex lock;
+ struct ww_acquire_ctx ctx;
+ struct work_struct work;
+ void *priv;
+ char name[64];
+ struct timer_list timer;
+ unsigned int status;
+};
+
+#ifdef CONFIG_DMABUF_SYNC
+extern bool is_dmabuf_sync_supported(void);
+
+extern struct dmabuf_sync *dmabuf_sync_init(void *priv, const char *name);
+
+extern void dmabuf_sync_fini(struct dmabuf_sync *sync);
+
+extern int dmabuf_sync_lock(struct dmabuf_sync *sync);
+
+extern int dmabuf_sync_unlock(struct dmabuf_sync *sync);
+
+extern int dmabuf_sync_get(struct dmabuf_sync *sync, void *sync_buf,
+ unsigned int type);
+
+extern void dmabuf_sync_put(struct dmabuf_sync *sync, struct dma_buf *dmabuf);
+
+extern void dmabuf_sync_put_all(struct dmabuf_sync *sync);
+
+#else
+static inline bool is_dmabuf_sync_supported(void) { return false; }
+
+static inline struct dmabuf_sync *dmabuf_sync_init(void *priv,
+ const char *names)
+{
+ return ERR_PTR(0);
+}
+
+static inline void dmabuf_sync_fini(struct dmabuf_sync *sync) { }
+
+static inline int dmabuf_sync_lock(struct dmabuf_sync *sync)
+{
+ return 0;
+}
+
+static inline int dmabuf_sync_unlock(struct dmabuf_sync *sync)
+{
+ return 0;
+}
+
+static inline int dmabuf_sync_get(struct dmabuf_sync *sync,
+ void *sync_buf,
+ unsigned int type)
+{
+ return 0;
+}
+
+static inline void dmabuf_sync_put(struct dmabuf_sync *sync,
+ struct dma_buf *dmabuf) { }
+
+static inline void dmabuf_sync_put_all(struct dmabuf_sync *sync) { }
+
+#endif
diff --git a/include/linux/reservation.h b/include/linux/reservation.h
index 80050e2..4310192 100644
--- a/include/linux/reservation.h
+++ b/include/linux/reservation.h
@@ -50,6 +50,11 @@ struct reservation_object {
struct fence *fence_excl;
struct fence **fence_shared;
u32 fence_shared_count, fence_shared_max;
+
+ atomic_t shared_cnt;
+ unsigned int accessed_type;
+ unsigned int shared;
+ unsigned int locked;
};
static inline void
@@ -60,6 +65,8 @@ reservation_object_init(struct reservation_object *obj)
obj->fence_shared_count = obj->fence_shared_max = 0;
obj->fence_shared = NULL;
obj->fence_excl = NULL;
+
+ atomic_set(&obj->shared_cnt, 1);
}
static inline void
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH] backlight: add CONFIG_PM_SLEEP to suspend/resume functions
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-12 12:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Arnd Bergmann, Jingoo Han, 'Shuah Khan', linux-fbdev,
linux-kernel, shuahkhan, rpurdie, FlorianSchandinat,
tomi.valkeinen, rafael.j.wysocki
In-Reply-To: <20130610163134.1c4124abba64c5f7099cb4ff@linux-foundation.org>
On 16:31 Mon 10 Jun , Andrew Morton wrote:
> On Fri, 07 Jun 2013 12:02:31 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
>
> > On Friday 07 June 2013 10:39:20 Jingoo Han wrote:
> > > Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following
> > > build warning when CONFIG_PM_SLEEP is not selected. This is because
> > > sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when
> > > the CONFIG_PM_SLEEP is enabled.
> > >
> > > drivers/video/backlight/backlight.c:211:12: warning: 'backlight_suspend' defined but not used [-Wunused-function]
> > > drivers/video/backlight/backlight.c:225:12: warning: 'backlight_resume' defined but not used [-Wunused-function]
> > >
> > > Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> > > ---
> > > drivers/video/backlight/backlight.c | 2 ++
> > > 1 file changed, 2 insertions(+)
> >
> > Your patch looks ok, but I find it extremely annoying to have new warnings
> > like this one come up every single day in linux-next. It really shouldn't
> > be this hard to use a macro called SIMPLE_DEV_PM_OPS() correctly.
> >
> > Below is an implementation of SIMPLE_DEV_PM_OPS and UNIVERSAL_DEV_PM_OPS
> > that avoids this issue by introducing an unused reference to the suspend
> > and resume functions. gcc is smart enough to leave out that unused code
> > by itself, and it would actually improve compile-time coverage to have
> > something like this, besides being harder to misuse.
> >
> > This would be a better approach if we didn't already have all the "#ifdef
> > CONFIG_PM_SLEEP" in place that hide the functions now. Unfortunately we
> > already have over 300 uses of SIMPLE_DEV_PM_OPS/UNIVERSAL_DEV_PM_OPS
> > in the kernel today, so removing all the #ifdef atomically without
> > creating more build errors is rather hard to do.
> >
> > Maybe someone has an idea how to extend my approach so it works with
> > and without the #ifdef, to let us transition to a situation that no
> > longer needs them.
>
> You could create new macros, and add a checkpatch rule to remind people
> to not use the old ones. Then people can migrate over from the old
> macros at a leisurely pace.
>
> The problem will be in thinking up decent names for the new macros.
Agreed
Best Regards,
J.
^ permalink raw reply
* Re: [V2 3/7] video: mmp: fix graphics/video layer enable/mask swap issue
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-12 12:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370879552-11290-1-git-send-email-jtzhou@marvell.com>
On 23:52 Mon 10 Jun , Jett.Zhou wrote:
> From: Jing Xiang <jxiang@marvell.com>
>
> There is bug when switch dma of graphic layer and video layer, it
> configured opposite bit, fix it.
>
> Signed-off-by: Jing Xiang <jxiang@marvell.com>
> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
do you need those 2 fixes for 3.10 or it can wait for 3.11?
Best Regards,
J.
> ---
> drivers/video/mmp/hw/mmp_ctrl.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
> index 3a8c2a3..8836053 100644
> --- a/drivers/video/mmp/hw/mmp_ctrl.c
> +++ b/drivers/video/mmp/hw/mmp_ctrl.c
> @@ -160,9 +160,9 @@ static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)
>
> static void dmafetch_onoff(struct mmp_overlay *overlay, int on)
> {
> - u32 mask = overlay_is_vid(overlay) ? CFG_GRA_ENA_MASK :
> - CFG_DMA_ENA_MASK;
> - u32 enable = overlay_is_vid(overlay) ? CFG_GRA_ENA(1) : CFG_DMA_ENA(1);
> + u32 mask = overlay_is_vid(overlay) ? CFG_DMA_ENA_MASK :
> + CFG_GRA_ENA_MASK;
> + u32 enable = overlay_is_vid(overlay) ? CFG_DMA_ENA(1) : CFG_GRA_ENA(1);
> u32 tmp;
> struct mmp_path *path = overlay->path;
>
> --
> 1.7.0.4
>
^ permalink raw reply
* [PATCH] OMAPDSS: DPI: Fix wrong pixel clock limit
From: Tomi Valkeinen @ 2013-06-12 6:44 UTC (permalink / raw)
To: linux-fbdev
DPI is supposed to skip odd dividers in the clock path when the pixel
clock is higher than 100MHz. The code, however, defines the pixel clock
limit as 1MHz. This causes the driver to skip valid clock dividers,
possibly making the pixel clock to be further away from the requested
one than necessary.
Fix the clock limit to 100MHz.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: NeilBrown <neilb@suse.de>
---
This is for 3.10.
drivers/video/omap2/dss/dpi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 757b57f..0bdcd41 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -129,7 +129,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
*/
- if (ctx->pck_min >= 1000000) {
+ if (ctx->pck_min >= 100000000) {
if (lckd > 1 && lckd % 2 != 0)
return false;
@@ -156,7 +156,7 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
*/
- if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 1000000)
+ if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000)
return false;
ctx->dsi_cinfo.regm_dispc = regm_dispc;
--
1.8.1.2
^ permalink raw reply related
* Re: [V2 0/7] Enhanced mmp fb driver and bugfix
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-11 17:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370879521-10962-1-git-send-email-jtzhou@marvell.com>
HI,
you must reply to the this e-mail with patch otherwise I will lost
them in my mailboxes
this I link them by mutt next you must do so
Best Regargs,
J.
On 23:52 Mon 10 Jun , Jett.Zhou wrote:
> 1 Enhanced some api/register operation routine
> 2 Fix some bugs like memcpy and graphics/video layer enable/mask swap;
> 3 Add pitch info and video layer set win/addr operations support
>
> Guoqing Li (2):
> video: mmp: rb swap setting update for new LCD driver
> video: mmp: optimize some register setting code
>
> Jing Xiang (5):
> video: mmp: fix graphics/video layer enable/mask swap issue
> video: mmp: fix memcpy wrong size for mmp_addr issue
> video: mmp: add pitch info in mmp_win structure
> video: mmp: calculate pitch value when fb set win
> video: mmp: add video layer set win/addr operations support
>
> drivers/video/mmp/fb/mmpfb.c | 34 +++++++++++------
> drivers/video/mmp/hw/mmp_ctrl.c | 75 ++++++++++++++++++++++-----------------
> drivers/video/mmp/hw/mmp_ctrl.h | 4 ++
> include/video/mmp_disp.h | 3 ++
> 4 files changed, 71 insertions(+), 45 deletions(-)
>
^ permalink raw reply
* Re: [PATCH] backlight: add CONFIG_PM_SLEEP to suspend/resume functions
From: Andrew Morton @ 2013-06-10 23:31 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Jingoo Han, 'Shuah Khan', linux-fbdev, linux-kernel,
shuahkhan, rpurdie, FlorianSchandinat, plagnioj, tomi.valkeinen,
rafael.j.wysocki
In-Reply-To: <1944274.r5ID26zhWd@wuerfel>
On Fri, 07 Jun 2013 12:02:31 +0200 Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 07 June 2013 10:39:20 Jingoo Han wrote:
> > Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following
> > build warning when CONFIG_PM_SLEEP is not selected. This is because
> > sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when
> > the CONFIG_PM_SLEEP is enabled.
> >
> > drivers/video/backlight/backlight.c:211:12: warning: 'backlight_suspend' defined but not used [-Wunused-function]
> > drivers/video/backlight/backlight.c:225:12: warning: 'backlight_resume' defined but not used [-Wunused-function]
> >
> > Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> > ---
> > drivers/video/backlight/backlight.c | 2 ++
> > 1 file changed, 2 insertions(+)
>
> Your patch looks ok, but I find it extremely annoying to have new warnings
> like this one come up every single day in linux-next. It really shouldn't
> be this hard to use a macro called SIMPLE_DEV_PM_OPS() correctly.
>
> Below is an implementation of SIMPLE_DEV_PM_OPS and UNIVERSAL_DEV_PM_OPS
> that avoids this issue by introducing an unused reference to the suspend
> and resume functions. gcc is smart enough to leave out that unused code
> by itself, and it would actually improve compile-time coverage to have
> something like this, besides being harder to misuse.
>
> This would be a better approach if we didn't already have all the "#ifdef
> CONFIG_PM_SLEEP" in place that hide the functions now. Unfortunately we
> already have over 300 uses of SIMPLE_DEV_PM_OPS/UNIVERSAL_DEV_PM_OPS
> in the kernel today, so removing all the #ifdef atomically without
> creating more build errors is rather hard to do.
>
> Maybe someone has an idea how to extend my approach so it works with
> and without the #ifdef, to let us transition to a situation that no
> longer needs them.
You could create new macros, and add a checkpatch rule to remind people
to not use the old ones. Then people can migrate over from the old
macros at a leisurely pace.
The problem will be in thinking up decent names for the new macros.
^ permalink raw reply
* Re: [PATCH] backlight: add CONFIG_PM_SLEEP to suspend/resume functions
From: Shuah Khan @ 2013-06-10 15:34 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Jingoo Han, 'Andrew Morton', linux-fbdev@vger.kernel.org,
linux-kernel@vger.kernel.org, shuahkhan@gmail.com,
rpurdie@rpsys.net, FlorianSchandinat@gmx.de,
plagnioj@jcrosoft.com, tomi.valkeinen@ti.com,
rafael.j.wysocki@intel.com
In-Reply-To: <2386569.59VQ9D5dv5@wuerfel>
On 06/07/2013 04:25 AM, Arnd Bergmann wrote:
> On Friday 07 June 2013 10:39:20 Jingoo Han wrote:
>> Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following
>> build warning when CONFIG_PM_SLEEP is not selected. This is because
>> sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when
>> the CONFIG_PM_SLEEP is enabled.
>>
>> drivers/video/backlight/backlight.c:211:12: warning: 'backlight_suspend' defined but not used [-Wunused-function]
>> drivers/video/backlight/backlight.c:225:12: warning: 'backlight_resume' defined but not used [-Wunused-function]
>>
>> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
>
> I forgot:
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
Jingoo Han, and Arnd,
Sorry I was on vacation all of last week. Thanks for fixing the problem.
My apologies for introducing the warnings. I had CONFIG_PM and
CONFIG_PM_SLEEP both enabled and didn't see this warning. I will be
careful with subsequent patches in this area.
-- Shuah
Shuah Khan, Linux Kernel Developer - Open Source Group Samsung Research
America (Silicon Valley) shuah.kh@samsung.com | (970) 672-0658
^ permalink raw reply
* Re: [PATCH 3/4] fb: Make fb_get_options() 'name' parameter const
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-10 14:22 UTC (permalink / raw)
To: ville.syrjala; +Cc: intel-gfx, Tomi Valkeinen, linux-fbdev, dri-devel
In-Reply-To: <1370619787-15341-3-git-send-email-ville.syrjala@linux.intel.com>
On 18:43 Fri 07 Jun , ville.syrjala@linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> The string isn't modified so make it const.
>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Applied
Best Regards,
J.
> ---
> drivers/video/fbmem.c | 2 +-
> include/linux/fb.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
> index 098bfc6..d8d5779 100644
> --- a/drivers/video/fbmem.c
> +++ b/drivers/video/fbmem.c
> @@ -1881,7 +1881,7 @@ static int ofonly __read_mostly;
> *
> * NOTE: Needed to maintain backwards compatibility
> */
> -int fb_get_options(char *name, char **option)
> +int fb_get_options(const char *name, char **option)
> {
> char *opt, *options = NULL;
> int retval = 0;
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index d49c60f..ffac70a 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -624,7 +624,7 @@ extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u3
> extern void fb_set_suspend(struct fb_info *info, int state);
> extern int fb_get_color_depth(struct fb_var_screeninfo *var,
> struct fb_fix_screeninfo *fix);
> -extern int fb_get_options(char *name, char **option);
> +extern int fb_get_options(const char *name, char **option);
> extern int fb_new_modelist(struct fb_info *info);
>
> extern struct fb_info *registered_fb[FB_MAX];
> --
> 1.8.1.5
>
^ permalink raw reply
* Re: [V2 5/7] video: mmp: add pitch info in mmp_win structure
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-10 13:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370780950-21746-1-git-send-email-jtzhou@marvell.com>
On 20:29 Sun 09 Jun , Jett.Zhou wrote:
> From: Jing Xiang <jxiang@marvell.com>
>
this is impossible to follow
resend the patch series fully with a PATCH 0
as I just go back from vacation I'll not read this series until then
Best Regards,
J.
> Add pitch length info of graphics/video layer for mmp_win, if it is
> YUV format of video layer, u/v pitch will non-zero.
>
> Signed-off-by: Jing Xiang <jxiang@marvell.com>
> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
> ---
> include/video/mmp_disp.h | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
> index b9dd1fb..462e3bd 100644
> --- a/include/video/mmp_disp.h
> +++ b/include/video/mmp_disp.h
> @@ -91,6 +91,11 @@ struct mmp_win {
> u16 up_crop;
> u16 bottom_crop;
> int pix_fmt;
> + /*
> + * pitch[0]: graphics/video layer line length or y pitch
> + * pitch[1]/pitch[2]: video u/v pitch if non-zero
> + */
> + u32 pitch[3];
> };
>
> struct mmp_addr {
> --
> 1.7.0.4
>
^ permalink raw reply
* Re: [V1 5/7] video: mmp: add pitch info in mmp_win structure
From: Sergei Shtylyov @ 2013-06-09 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370767486-11729-1-git-send-email-jtzhou@marvell.com>
Hello.
On 09-06-2013 12:44, Jett.Zhou wrote:
> From: Jing Xiang <jxiang@marvell.com>
> Add pitch length info of graphics/video layer for mmp_win, if it is
> YUV format of video layer, u/v pitch will non-zero.
> Signed-off-by: Jing Xiang <jxiang@marvell.com>
> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
> ---
> include/video/mmp_disp.h | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
> diff --git a/include/video/mmp_disp.h b/include/video/mmp_disp.h
> index b9dd1fb..5708d26 100644
> --- a/include/video/mmp_disp.h
> +++ b/include/video/mmp_disp.h
> @@ -91,6 +91,9 @@ struct mmp_win {
> u16 up_crop;
> u16 bottom_crop;
> int pix_fmt;
> + /* pitch[0]: graphics/video layer line length or y pitch
> + * pitch[1]/pitch[2]: video u/v pitch if non-zero */
The preferred format for multi-line comments is this:
/*
* bla
* bla
*/
> + u32 pitch[3];
> };
WBR, Sergei
^ permalink raw reply
* Re: [V1 4/7] video: mmp: fix memcpy wrong size for mmp_addr issue
From: Sergei Shtylyov @ 2013-06-09 12:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370767470-11615-1-git-send-email-jtzhou@marvell.com>
Hello.
On 09-06-2013 12:44, Jett.Zhou wrote:
> From: Jing Xiang <jxiang@marvell.com>
> Memcpy used wrong struct of mmp_addr, fix it.
From the patch it follows that 'struct mmp_addr' is the right one. :-)
> Signed-off-by: Jing Xiang <jxiang@marvell.com>
> Signed-off-by: Jett.Zhou <jtzhou@marvell.com>
> ---
> drivers/video/mmp/hw/mmp_ctrl.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
> diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/mmp/hw/mmp_ctrl.c
> index 8836053..92a5f44 100644
> --- a/drivers/video/mmp/hw/mmp_ctrl.c
> +++ b/drivers/video/mmp/hw/mmp_ctrl.c
> @@ -233,7 +233,7 @@ static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)
> struct lcd_regs *regs = path_regs(overlay->path);
>
> /* FIXME: assert addr supported */
> - memcpy(&overlay->addr, addr, sizeof(struct mmp_win));
> + memcpy(&overlay->addr, addr, sizeof(struct mmp_addr));
> writel(addr->phys[0], ®s->g_0);
>
> return overlay->addr.phys[0];
WBR, Sergei
^ permalink raw reply
* Re: [RFC 00/50] ARM: at91: move to common clk framework
From: boris brezillon @ 2013-06-07 20:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <51B1B270.2090002@free-electrons.com>
On 07/06/2013 12:14, Gregory CLEMENT wrote:
> On 06/07/2013 11:32 AM, boris brezillon wrote:
>> On 07/06/2013 11:22, Nicolas Ferre wrote:
>>> On 07/06/2013 10:34, Boris BREZILLON :
>>>> Hello,
>>>>
>>>> This patch series is a proposal to move at91 clock implementation
>>>> to common clk framework.
>>> Before discussion begins I would like to give my kudos to you Boris!
>>> This is huge work and I thank you for it: It is so great!
>>>
>>> I am sure that Jean-Christophe will have his idea on that because he
>>> told me that he thought a little bit about that, but I am sure that we
>>> will come to a quick and seamlessly integration soon.
>>>
>>> (Hey, I know it is not technical email, but I am so exited to see this
>>> happen that the noise worth it! ;-))
>> I received several notifications about filtered mails.
>> Could you tell me if you received the whole series ?
> I have just received this email. But since few days (or weeks) I have observed
> a big latency on the LAKML. Sometime my emails were in the LAKML after 3 or 4
> hours.
>
>> And do you know why this could have been filtered ?
> There is a filter which prevent to "hijack" a thread by changing the topic.
> of course it is a problem for the patch set sent with git send-email. So for
> this there is an exception if you have the word PATCH in your topic. But
> it doesn't work with the work RFC. Maybe it is the word you have chosen. If
> you are in this case then you can use [PATCH RFC ]
Thanks for the tip. It did the trick.
Best Regards,
Boris
> Regards
>
>>
>>>> Most of the clock provided by the PMC (Power Management Controller) are
>>>> implemented :
>>>> - main clock (main oscillator)
>>>> - pll clocks
>>>> - master clock
>>>> - programmable clocks
>>>> - utmi clock
>>>> - peripheral clocks
>>>> - system clocks
>>>>
>>>> This implementation is compatible with device tree: the goal is
>>>> to define the whole clock tree in the device tree (all currently
>>>> available dt SoCs and boards are patched to support dt clocks).
>>>> Please feel free to comment the dt bindinds (I'm not sure about the
>>>> name I choose or the position of clock nodes: children of pmc node).
>>>>
>>>> I removed the register_clocks function in SoC supporting dt boards only:
>>>> - at91sam9x5 SoCs
>>>> - at91sam9n12 SoC
>>>> - sama5d3 SoCs
>>>>
>>>> This patch series also update at91 drivers calling clk_enable/disable
>>>> instead of the preferred clk_prepare_enable/disable_unprepare functions.
>>>>
>>>>
>>>> I know there are a lot of cleanup in progress for at91 arch, so
>>>> please tell
>>>> me if you think this transition to common clk framework should wait.
>>>>
>>>> This patch series has been tested on Kizbox (sam9g20 SoC) board using
>>>> device
>>>> tree. It compiles for other SoCs and both with and without dt
>>>> support, but it
>>>> has not been tested.
>>>>
>>>> The clocks rate/parent change has not been tested.
>>>>
>>>> Best Regards,
>>>> Boris
>>>>
>>>> Boris BREZILLON (50):
>>>> ARM: at91: move arch/arm/mach-at91/include/mach/at91_pmc.h to
>>>> include/linux/clk/at91.h
>>>> ARM: at91: add PMC main clock using common clk framework.
>>>> ARM: at91: add PMC pll clocks support using common clk framework.
>>>> ARM: at91: add PMC master clock support using common clk framework.
>>>> ARM: at91: add PMC system clocks support using common clk framework.
>>>> ARM: at91: add PMC peripheral clocks support using common clk
>>>> framework.
>>>> ARM: at91: add PMC programmable clocks support using common clk
>>>> framework.
>>>> ARM: at91: add PMC utmi clock support using common clk framework.
>>>> ARM: at91: add PMC usb clock support using common clk framework.
>>>> ARM: at91: add PMC smd clock support using common clk framework.
>>>> ARM: at91: add PMC clk device tree binding doc.
>>>> ARM: at91: move to common clk framework.
>>>> ARM: at91: move at91rm9200 SoC to common clk framework.
>>>> ARM: at91: move at91sam9260 SoC to common clk framework.
>>>> ARM: at91: move at91sam9263 SoC to common clk framework.
>>>> ARM: at91: move at91sam9263 SoC to common clk framework.
>>>> ARM: at91: move at91sam9g45 SoC to common clk framework.
>>>> ARM: at91: move at91sam9n12 SoC to common clk framework.
>>>> ARM: at91: move at91sam9rl SoC to common clk framework.
>>>> ARM: at91: move at91sam9x5 SoCs to common clk framework.
>>>> ARM: at91: move at91sam9 SoCs to common clk framework.
>>>> ARM: at91: move sama5d3 SoCs to common clk framework.
>>>> ARM: at91: move at91rm9200 non dt boards to common clk framework.
>>>> ARM: at91: move at91sam9 non dt boards to common clk framework.
>>>> ARM: at91: move pit timer to common clk framework.
>>>> ARM: at91/tc/clocksource: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> at_hdmac: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> ASoC: atmel-ssc: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> mmc: atmel-mci: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> pwm: atmel-tcb: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> tty: atmel_serial: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> usb: gadget: at91_udc: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> drivers/usb/host/ehci-atmel.c: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> USB: ohci-at91: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> ARM: at91/avr32/atmel_lcdfb: replace clk_enable/disable with
>>>> clk_prepare_enable/disable_unprepare.
>>>> ARM: at91/dt: move at91rm9200 SoC to clk framework.
>>>> ARM: at91/dt: move at91sam9260 SoC to common clk framework.
>>>> ARM: at91/dt: move at91sam9263 SoC to common clk framework.
>>>> ARM: at91/dt: move at91sam9g45 SoC to common clk framework.
>>>> ARM: at91/dt: move at91sam9n12 SoC to common clk framework.
>>>> ARM: at91/dt: move at91sam9x5 SoCs to common clk framework.
>>>> ARM: at91/dt: move at91sam9g20 SoC to common clk framework.
>>>> ARM: at91/dt: move sama5d3 SoCs to common clk framework.
>>>> ARM: at91/dt: move at91sam9260/sam9g20 boards to common clk
>>>> framework.
>>>> ARM: at91/dt: move at91rm9200 boards to common clk framework.
>>>> ARM: at91/dt: move at91sam9263 boards to common clk framework.
>>>> ARM: at91/dt: move at91sam9g45 boards to common clk framework.
>>>> ARM: at91/dt: move at91sam9n12 boards to common clk framework.
>>>> ARM: at91/dt: move at91sam9x5 boards to common clk framework.
>>>> ARM: at91/dt: move sama5d3 boards to common clk framework.
>>>>
>>>> .../devicetree/bindings/clock/at91-clock.txt | 247 +++++
>>>> arch/arm/boot/dts/animeo_ip.dts | 17 +-
>>>> arch/arm/boot/dts/at91-ariag25.dts | 17 +-
>>>> arch/arm/boot/dts/at91rm9200.dtsi | 133 +++
>>>> arch/arm/boot/dts/at91rm9200ek.dts | 17 +-
>>>> arch/arm/boot/dts/at91sam9260.dtsi | 144 ++-
>>>> arch/arm/boot/dts/at91sam9263.dtsi | 135 +++
>>>> arch/arm/boot/dts/at91sam9263ek.dts | 17 +-
>>>> arch/arm/boot/dts/at91sam9g15.dtsi | 11 +
>>>> arch/arm/boot/dts/at91sam9g20.dtsi | 37 +
>>>> arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 17 +-
>>>> arch/arm/boot/dts/at91sam9g25.dtsi | 3 +
>>>> arch/arm/boot/dts/at91sam9g35.dtsi | 23 +
>>>> arch/arm/boot/dts/at91sam9g45.dtsi | 157 ++++
>>>> arch/arm/boot/dts/at91sam9m10g45ek.dts | 17 +-
>>>> arch/arm/boot/dts/at91sam9n12.dtsi | 153 ++++
>>>> arch/arm/boot/dts/at91sam9n12ek.dts | 17 +-
>>>> arch/arm/boot/dts/at91sam9x25.dtsi | 25 +-
>>>> arch/arm/boot/dts/at91sam9x35.dtsi | 3 +
>>>> arch/arm/boot/dts/at91sam9x5.dtsi | 226 +++--
>>>> arch/arm/boot/dts/at91sam9x5_can.dtsi | 24 +
>>>> arch/arm/boot/dts/at91sam9x5_isi.dtsi | 24 +
>>>> arch/arm/boot/dts/at91sam9x5_lcdc.dtsi | 32 +
>>>> arch/arm/boot/dts/at91sam9x5_macb0.dtsi | 68 ++
>>>> arch/arm/boot/dts/at91sam9x5_macb1.dtsi | 56 ++
>>>> arch/arm/boot/dts/at91sam9x5_usart3.dtsi | 60 ++
>>>> arch/arm/boot/dts/ge863-pro3.dtsi | 16 +-
>>>> arch/arm/boot/dts/kizbox.dts | 5 +
>>>> arch/arm/boot/dts/mpa1600.dts | 16 +-
>>>> arch/arm/boot/dts/pm9g45.dts | 16 +-
>>>> arch/arm/boot/dts/sama5d3.dtsi | 358 ++++----
>>>> arch/arm/boot/dts/sama5d31ek.dts | 4 +
>>>> arch/arm/boot/dts/sama5d33ek.dts | 2 +
>>>> arch/arm/boot/dts/sama5d34ek.dts | 4 +
>>>> arch/arm/boot/dts/sama5d35ek.dts | 6 +
>>>> arch/arm/boot/dts/sama5d3_can.dtsi | 67 ++
>>>> arch/arm/boot/dts/sama5d3_emac.dtsi | 56 ++
>>>> arch/arm/boot/dts/sama5d3_gmac.dtsi | 89 ++
>>>> arch/arm/boot/dts/sama5d3_lcd.dtsi | 73 ++
>>>> arch/arm/boot/dts/sama5d3_mci2.dtsi | 59 ++
>>>> arch/arm/boot/dts/sama5d3_tcb1.dtsi | 39 +
>>>> arch/arm/boot/dts/sama5d3_uart.dtsi | 42 +
>>>> arch/arm/boot/dts/sama5d3xcm.dtsi | 17 +-
>>>> arch/arm/boot/dts/tny_a9260_common.dtsi | 17 +-
>>>> arch/arm/boot/dts/tny_a9263.dts | 17 +-
>>>> arch/arm/boot/dts/usb_a9260_common.dtsi | 17 +-
>>>> arch/arm/boot/dts/usb_a9263.dts | 17 +-
>>>> arch/arm/mach-at91/Kconfig | 26 +
>>>> arch/arm/mach-at91/Makefile | 2 +-
>>>> arch/arm/mach-at91/at91rm9200.c | 578 +++++++-----
>>>> arch/arm/mach-at91/at91sam9260.c | 694
>>>> +++++++++-----
>>>> arch/arm/mach-at91/at91sam9261.c | 581 ++++++++----
>>>> arch/arm/mach-at91/at91sam9263.c | 599 +++++++-----
>>>> arch/arm/mach-at91/at91sam926x_time.c | 21 +-
>>>> arch/arm/mach-at91/at91sam9g45.c | 705
>>>> ++++++++------
>>>> arch/arm/mach-at91/at91sam9g45_devices.c | 1 -
>>>> arch/arm/mach-at91/at91sam9n12.c | 196 +---
>>>> arch/arm/mach-at91/at91sam9rl.c | 514 +++++++----
>>>> arch/arm/mach-at91/at91sam9x5.c | 291 +-----
>>>> arch/arm/mach-at91/board-1arm.c | 12 +-
>>>> arch/arm/mach-at91/board-afeb-9260v1.c | 11 +-
>>>> arch/arm/mach-at91/board-cam60.c | 13 +-
>>>> arch/arm/mach-at91/board-carmeva.c | 13 +-
>>>> arch/arm/mach-at91/board-cpu9krea.c | 12 +-
>>>> arch/arm/mach-at91/board-cpuat91.c | 12 +-
>>>> arch/arm/mach-at91/board-csb337.c | 11 +-
>>>> arch/arm/mach-at91/board-csb637.c | 11 +-
>>>> arch/arm/mach-at91/board-dt-rm9200.c | 9 +-
>>>> arch/arm/mach-at91/board-dt-sam9.c | 9 +-
>>>> arch/arm/mach-at91/board-dt-sama5.c | 9 +-
>>>> arch/arm/mach-at91/board-eb9200.c | 11 +-
>>>> arch/arm/mach-at91/board-ecbat91.c | 12 +-
>>>> arch/arm/mach-at91/board-eco920.c | 13 +-
>>>> arch/arm/mach-at91/board-flexibity.c | 12 +-
>>>> arch/arm/mach-at91/board-foxg20.c | 12 +-
>>>> arch/arm/mach-at91/board-gsia18s.c | 8 +-
>>>> arch/arm/mach-at91/board-kafa.c | 12 +-
>>>> arch/arm/mach-at91/board-kb9202.c | 12 +-
>>>> arch/arm/mach-at91/board-pcontrol-g20.c | 9 +-
>>>> arch/arm/mach-at91/board-picotux200.c | 11 +-
>>>> arch/arm/mach-at91/board-qil-a9260.c | 11 +-
>>>> arch/arm/mach-at91/board-rm9200dk.c | 11 +-
>>>> arch/arm/mach-at91/board-rm9200ek.c | 11 +-
>>>> arch/arm/mach-at91/board-rsi-ews.c | 12 +-
>>>> arch/arm/mach-at91/board-sam9-l9260.c | 11 +-
>>>> arch/arm/mach-at91/board-sam9260ek.c | 11 +-
>>>> arch/arm/mach-at91/board-sam9261ek.c | 15 +-
>>>> arch/arm/mach-at91/board-sam9263ek.c | 11 +-
>>>> arch/arm/mach-at91/board-sam9g20ek.c | 15 +-
>>>> arch/arm/mach-at91/board-sam9m10g45ek.c | 11 +-
>>>> arch/arm/mach-at91/board-sam9rlek.c | 11 +-
>>>> arch/arm/mach-at91/board-snapper9260.c | 12 +-
>>>> arch/arm/mach-at91/board-stamp9g20.c | 15 +-
>>>> arch/arm/mach-at91/board-yl-9200.c | 12 +-
>>>> arch/arm/mach-at91/clock.c | 961
>>>> --------------------
>>>> arch/arm/mach-at91/clock.h | 49 -
>>>> arch/arm/mach-at91/generic.h | 10 +-
>>>> arch/arm/mach-at91/pm.c | 2 +-
>>>> arch/arm/mach-at91/pm_slowclock.S | 2 +-
>>>> arch/arm/mach-at91/pmc.c | 58 ++
>>>> arch/arm/mach-at91/sama5d3.c | 344 +------
>>>> arch/arm/mach-at91/setup.c | 38 +-
>>>> arch/arm/mach-at91/stamp9g20.h | 2 +-
>>>> drivers/clk/Makefile | 1 +
>>>> drivers/clk/at91/Makefile | 11 +
>>>> drivers/clk/at91/clk-main.c | 106 +++
>>>> drivers/clk/at91/clk-master.c | 317 +++++++
>>>> drivers/clk/at91/clk-peripheral.c | 376 ++++++++
>>>> drivers/clk/at91/clk-pll.c | 438 +++++++++
>>>> drivers/clk/at91/clk-plldiv.c | 125 +++
>>>> drivers/clk/at91/clk-programmable.c | 370 ++++++++
>>>> drivers/clk/at91/clk-smd.c | 157 ++++
>>>> drivers/clk/at91/clk-system.c | 189 ++++
>>>> drivers/clk/at91/clk-usb.c | 303 ++++++
>>>> drivers/clk/at91/clk-utmi.c | 114 +++
>>>> drivers/clocksource/tcb_clksrc.c | 10 +-
>>>> drivers/dma/at_hdmac.c | 12 +-
>>>> drivers/misc/atmel-ssc.c | 8 +-
>>>> drivers/mmc/host/atmel-mci.c | 16 +-
>>>> drivers/pwm/pwm-atmel-tcb.c | 4 +-
>>>> drivers/tty/serial/atmel_serial.c | 35 +-
>>>> drivers/usb/gadget/at91_udc.c | 12 +-
>>>> drivers/usb/gadget/atmel_usba_udc.c | 2 +-
>>>> drivers/usb/host/ehci-atmel.c | 8 +-
>>>> drivers/usb/host/ohci-at91.c | 12 +-
>>>> drivers/video/atmel_lcdfb.c | 8 +-
>>>> .../mach/at91_pmc.h => include/linux/clk/at91.h | 122 ++-
>>>> 127 files changed, 7588 insertions(+), 3862 deletions(-)
>>>> create mode 100644
>>>> Documentation/devicetree/bindings/clock/at91-clock.txt
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_can.dtsi
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_isi.dtsi
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_lcdc.dtsi
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_macb0.dtsi
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_macb1.dtsi
>>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_usart3.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_can.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_emac.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_gmac.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_lcd.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_mci2.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_tcb1.dtsi
>>>> create mode 100644 arch/arm/boot/dts/sama5d3_uart.dtsi
>>>> delete mode 100644 arch/arm/mach-at91/clock.c
>>>> delete mode 100644 arch/arm/mach-at91/clock.h
>>>> create mode 100644 arch/arm/mach-at91/pmc.c
>>>> create mode 100644 drivers/clk/at91/Makefile
>>>> create mode 100644 drivers/clk/at91/clk-main.c
>>>> create mode 100644 drivers/clk/at91/clk-master.c
>>>> create mode 100644 drivers/clk/at91/clk-peripheral.c
>>>> create mode 100644 drivers/clk/at91/clk-pll.c
>>>> create mode 100644 drivers/clk/at91/clk-plldiv.c
>>>> create mode 100644 drivers/clk/at91/clk-programmable.c
>>>> create mode 100644 drivers/clk/at91/clk-smd.c
>>>> create mode 100644 drivers/clk/at91/clk-system.c
>>>> create mode 100644 drivers/clk/at91/clk-usb.c
>>>> create mode 100644 drivers/clk/at91/clk-utmi.c
>>>> rename arch/arm/mach-at91/include/mach/at91_pmc.h =>
>>>> include/linux/clk/at91.h (76%)
>>>>
>>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
^ permalink raw reply
* [RFC PATCH 35/50] at91/avr32/atmel_lcdfb: prepare clk before calling enable
From: Boris BREZILLON @ 2013-06-07 18:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1370615115-16979-1-git-send-email-b.brezillon@overkiz.com>
Replace clk_enable/disable with clk_prepare_enable/disable_unprepare to
avoid common clk framework warnings.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
drivers/video/atmel_lcdfb.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 540909d..8525457 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -893,14 +893,14 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo)
{
- clk_enable(sinfo->bus_clk);
- clk_enable(sinfo->lcdc_clk);
+ clk_prepare_enable(sinfo->bus_clk);
+ clk_prepare_enable(sinfo->lcdc_clk);
}
static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
{
- clk_disable(sinfo->bus_clk);
- clk_disable(sinfo->lcdc_clk);
+ clk_disable_unprepare(sinfo->bus_clk);
+ clk_disable_unprepare(sinfo->lcdc_clk);
}
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v3] simplefb: add support for a8b8g8r8 pixel format
From: Stephen Warren @ 2013-06-07 16:24 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Olof Johansson,
gnurou, linux-kernel, linux-fbdev
In-Reply-To: <1370590290-13467-1-git-send-email-acourbot@nvidia.com>
On 06/07/2013 01:31 AM, Alexandre Courbot wrote:
> A framebuffer of this format is set up by SHIELD's bootloader.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> Acked-by: Olof Johansson <olof@lixom.net>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
^ permalink raw reply
* [PATCH 3/4] fb: Make fb_get_options() 'name' parameter const
From: ville.syrjala @ 2013-06-07 15:43 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
linux-fbdev
In-Reply-To: <1370619787-15341-1-git-send-email-ville.syrjala@linux.intel.com>
From: Ville Syrj채l채 <ville.syrjala@linux.intel.com>
The string isn't modified so make it const.
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Ville Syrj채l채 <ville.syrjala@linux.intel.com>
---
drivers/video/fbmem.c | 2 +-
include/linux/fb.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 098bfc6..d8d5779 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1881,7 +1881,7 @@ static int ofonly __read_mostly;
*
* NOTE: Needed to maintain backwards compatibility
*/
-int fb_get_options(char *name, char **option)
+int fb_get_options(const char *name, char **option)
{
char *opt, *options = NULL;
int retval = 0;
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d49c60f..ffac70a 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -624,7 +624,7 @@ extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u3
extern void fb_set_suspend(struct fb_info *info, int state);
extern int fb_get_color_depth(struct fb_var_screeninfo *var,
struct fb_fix_screeninfo *fix);
-extern int fb_get_options(char *name, char **option);
+extern int fb_get_options(const char *name, char **option);
extern int fb_new_modelist(struct fb_info *info);
extern struct fb_info *registered_fb[FB_MAX];
--
1.8.1.5
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [RESEND RFC PATCH 00/50] ARM: at91: move to common clk framework
From: Boris BREZILLON @ 2013-06-07 14:24 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
Sorry for the noise, the first submission has been filtered.
This patch series is a proposal to move at91 clock implementation
to common clk framework.
Most of the clock provided by the PMC (Power Management Controller) are
implemented :
- main clock (main oscillator)
- pll clocks
- master clock
- programmable clocks
- utmi clock
- peripheral clocks
- system clocks
This implementation is compatible with device tree: the goal is
to define the whole clock tree in the device tree (all currently
available dt SoCs and boards are patched to support dt clocks).
Please feel free to comment the dt bindinds (I'm not sure about the
name I choose or the position of clock nodes: children of pmc node).
I removed the register_clocks function in SoC supporting dt boards only:
- at91sam9x5 SoCs
- at91sam9n12 SoC
- sama5d3 SoCs
This patch series also update at91 drivers calling clk_enable/disable
instead of the preferred clk_prepare_enable/disable_unprepare functions.
I know there are a lot of cleanup in progress for at91 arch, so please tell
me if you think this transition to common clk framework should wait.
This patch series has been tested on Kizbox (sam9g20 SoC) board using device
tree. It compiles for other SoCs and both with and without dt support, but it
has not been tested.
The clocks rate/parent change has not been tested.
Best Regards,
Boris
Boris BREZILLON (50):
ARM: at91: move at91_pmc.h to include/linux/clk/at91.h
ARM: at91: add PMC main clock
ARM: at91: add PMC pll clocks
ARM: at91: add PMC master clock
ARM: at91: add PMC system clocks
ARM: at91: add PMC peripheral clocks
ARM: at91: add PMC programmable clocks
ARM: at91: add PMC utmi clock support
ARM: at91: add PMC usb clock support
ARM: at91: add PMC smd clock support
ARM: at91: add PMC clk device tree binding doc
ARM: at91: move to common clk framework
ARM: at91: move at91rm9200 SoC to new at91 clk implem
ARM: at91: move at91sam9260 SoC to new at91 clk implem
ARM: at91: move at91sam9263 SoC to new at91 clk implem
ARM: at91: move at91sam9263 SoC to new at91 clk implem
ARM: at91: move at91sam9g45 SoC to new at91 clk implem
ARM: at91: move at91sam9n12 SoC to new at91 clk implem
ARM: at91: move at91sam9rl SoC to new at91 clk implem
ARM: at91: move at91sam9x5 SoCs to new at91 clk implem
ARM: at91: move at91sam9 SoCs to new at91 clk implem
ARM: at91: move sama5d3 SoCs to new at91 clk implem
ARM: at91: move at91rm9200 boards to new at91 clk implem
ARM: at91: move at91sam9 boards to new at91 clk implem
ARM: at91: move pit timer to common clk framework
ARM: at91/tc/clocksource: prepare clk before calling enable
at_hdmac: prepare clk before calling enable
ASoC: atmel-ssc: prepare clk before calling enable
mmc: atmel-mci: prepare clk before calling enable
pwm: atmel-tcb: prepare clk before calling enable
tty: atmel_serial: prepare clk before calling enable
usb: gadget: at91_udc: prepare clk before calling enable
ehci-atmel.c: prepare clk before calling enable
USB: ohci-at91: prepare clk before calling enable
at91/avr32/atmel_lcdfb: prepare clk before calling enable
ARM: at91/dt: move at91rm9200 SoC to new at91 clk implem
ARM: at91/dt: move at91sam9260 SoC to new at91 clk implem
ARM: at91/dt: move at91sam9263 SoC to new at91 clk implem
ARM: at91/dt: move at91sam9g45 SoC to new at91 clk implem
ARM: at91/dt: move at91sam9n12 SoC to new at91 clk implem
ARM: at91/dt: move at91sam9x5 SoCs to new at91 clk implem
ARM: at91/dt: move at91sam9g20 SoC to new at91 clk implem
ARM: at91/dt: move sama5d3 SoCs to to new at91 clk implem
ARM: at91/dt: move sam9260/sam9g20 boards to new at91 clk implem
ARM: at91/dt: move rm9200 boards to new at91 clk implem
ARM: at91/dt: move sam9263 boards to new at91 clk implem
ARM: at91/dt: move sam9g45 boards to new at91 clk implem
ARM: at91/dt: move sam9n12 boards to new at91 clk implem
ARM: at91/dt: move sam9x5 boards to new at91 clk implem
ARM: at91/dt: move sama5d3 boards to new at91 clk implem
.../devicetree/bindings/clock/at91-clock.txt | 247 +++++
arch/arm/boot/dts/animeo_ip.dts | 17 +-
arch/arm/boot/dts/at91-ariag25.dts | 17 +-
arch/arm/boot/dts/at91rm9200.dtsi | 133 +++
arch/arm/boot/dts/at91rm9200ek.dts | 17 +-
arch/arm/boot/dts/at91sam9260.dtsi | 144 ++-
arch/arm/boot/dts/at91sam9263.dtsi | 135 +++
arch/arm/boot/dts/at91sam9263ek.dts | 17 +-
arch/arm/boot/dts/at91sam9g15.dtsi | 11 +
arch/arm/boot/dts/at91sam9g20.dtsi | 37 +
arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 17 +-
arch/arm/boot/dts/at91sam9g25.dtsi | 3 +
arch/arm/boot/dts/at91sam9g35.dtsi | 23 +
arch/arm/boot/dts/at91sam9g45.dtsi | 157 ++++
arch/arm/boot/dts/at91sam9m10g45ek.dts | 17 +-
arch/arm/boot/dts/at91sam9n12.dtsi | 153 ++++
arch/arm/boot/dts/at91sam9n12ek.dts | 17 +-
arch/arm/boot/dts/at91sam9x25.dtsi | 25 +-
arch/arm/boot/dts/at91sam9x35.dtsi | 3 +
arch/arm/boot/dts/at91sam9x5.dtsi | 226 +++--
arch/arm/boot/dts/at91sam9x5_can.dtsi | 24 +
arch/arm/boot/dts/at91sam9x5_isi.dtsi | 24 +
arch/arm/boot/dts/at91sam9x5_lcdc.dtsi | 32 +
arch/arm/boot/dts/at91sam9x5_macb0.dtsi | 68 ++
arch/arm/boot/dts/at91sam9x5_macb1.dtsi | 56 ++
arch/arm/boot/dts/at91sam9x5_usart3.dtsi | 60 ++
arch/arm/boot/dts/ge863-pro3.dtsi | 16 +-
arch/arm/boot/dts/kizbox.dts | 5 +
arch/arm/boot/dts/mpa1600.dts | 16 +-
arch/arm/boot/dts/pm9g45.dts | 16 +-
arch/arm/boot/dts/sama5d3.dtsi | 358 ++++----
arch/arm/boot/dts/sama5d31ek.dts | 4 +
arch/arm/boot/dts/sama5d33ek.dts | 2 +
arch/arm/boot/dts/sama5d34ek.dts | 4 +
arch/arm/boot/dts/sama5d35ek.dts | 6 +
arch/arm/boot/dts/sama5d3_can.dtsi | 67 ++
arch/arm/boot/dts/sama5d3_emac.dtsi | 56 ++
arch/arm/boot/dts/sama5d3_gmac.dtsi | 89 ++
arch/arm/boot/dts/sama5d3_lcd.dtsi | 73 ++
arch/arm/boot/dts/sama5d3_mci2.dtsi | 59 ++
arch/arm/boot/dts/sama5d3_tcb1.dtsi | 39 +
arch/arm/boot/dts/sama5d3_uart.dtsi | 42 +
arch/arm/boot/dts/sama5d3xcm.dtsi | 17 +-
arch/arm/boot/dts/tny_a9260_common.dtsi | 17 +-
arch/arm/boot/dts/tny_a9263.dts | 17 +-
arch/arm/boot/dts/usb_a9260_common.dtsi | 17 +-
arch/arm/boot/dts/usb_a9263.dts | 17 +-
arch/arm/mach-at91/Kconfig | 26 +
arch/arm/mach-at91/Makefile | 2 +-
arch/arm/mach-at91/at91rm9200.c | 578 +++++++-----
arch/arm/mach-at91/at91sam9260.c | 694 +++++++++-----
arch/arm/mach-at91/at91sam9261.c | 581 ++++++++----
arch/arm/mach-at91/at91sam9263.c | 599 +++++++-----
arch/arm/mach-at91/at91sam926x_time.c | 21 +-
arch/arm/mach-at91/at91sam9g45.c | 705 ++++++++------
arch/arm/mach-at91/at91sam9g45_devices.c | 1 -
arch/arm/mach-at91/at91sam9n12.c | 196 +---
arch/arm/mach-at91/at91sam9rl.c | 514 +++++++----
arch/arm/mach-at91/at91sam9x5.c | 291 +-----
arch/arm/mach-at91/board-1arm.c | 12 +-
arch/arm/mach-at91/board-afeb-9260v1.c | 11 +-
arch/arm/mach-at91/board-cam60.c | 13 +-
arch/arm/mach-at91/board-carmeva.c | 13 +-
arch/arm/mach-at91/board-cpu9krea.c | 12 +-
arch/arm/mach-at91/board-cpuat91.c | 12 +-
arch/arm/mach-at91/board-csb337.c | 11 +-
arch/arm/mach-at91/board-csb637.c | 11 +-
arch/arm/mach-at91/board-dt-rm9200.c | 9 +-
arch/arm/mach-at91/board-dt-sam9.c | 9 +-
arch/arm/mach-at91/board-dt-sama5.c | 9 +-
arch/arm/mach-at91/board-eb9200.c | 11 +-
arch/arm/mach-at91/board-ecbat91.c | 12 +-
arch/arm/mach-at91/board-eco920.c | 13 +-
arch/arm/mach-at91/board-flexibity.c | 12 +-
arch/arm/mach-at91/board-foxg20.c | 12 +-
arch/arm/mach-at91/board-gsia18s.c | 8 +-
arch/arm/mach-at91/board-kafa.c | 12 +-
arch/arm/mach-at91/board-kb9202.c | 12 +-
arch/arm/mach-at91/board-pcontrol-g20.c | 9 +-
arch/arm/mach-at91/board-picotux200.c | 11 +-
arch/arm/mach-at91/board-qil-a9260.c | 11 +-
arch/arm/mach-at91/board-rm9200dk.c | 11 +-
arch/arm/mach-at91/board-rm9200ek.c | 11 +-
arch/arm/mach-at91/board-rsi-ews.c | 12 +-
arch/arm/mach-at91/board-sam9-l9260.c | 11 +-
arch/arm/mach-at91/board-sam9260ek.c | 11 +-
arch/arm/mach-at91/board-sam9261ek.c | 15 +-
arch/arm/mach-at91/board-sam9263ek.c | 11 +-
arch/arm/mach-at91/board-sam9g20ek.c | 15 +-
arch/arm/mach-at91/board-sam9m10g45ek.c | 11 +-
arch/arm/mach-at91/board-sam9rlek.c | 11 +-
arch/arm/mach-at91/board-snapper9260.c | 12 +-
arch/arm/mach-at91/board-stamp9g20.c | 15 +-
arch/arm/mach-at91/board-yl-9200.c | 12 +-
arch/arm/mach-at91/clock.c | 961 --------------------
arch/arm/mach-at91/clock.h | 49 -
arch/arm/mach-at91/generic.h | 10 +-
arch/arm/mach-at91/pm.c | 2 +-
arch/arm/mach-at91/pm_slowclock.S | 2 +-
arch/arm/mach-at91/pmc.c | 58 ++
arch/arm/mach-at91/sama5d3.c | 344 +------
arch/arm/mach-at91/setup.c | 38 +-
arch/arm/mach-at91/stamp9g20.h | 2 +-
drivers/clk/Makefile | 1 +
drivers/clk/at91/Makefile | 11 +
drivers/clk/at91/clk-main.c | 106 +++
drivers/clk/at91/clk-master.c | 317 +++++++
drivers/clk/at91/clk-peripheral.c | 376 ++++++++
drivers/clk/at91/clk-pll.c | 438 +++++++++
drivers/clk/at91/clk-plldiv.c | 125 +++
drivers/clk/at91/clk-programmable.c | 370 ++++++++
drivers/clk/at91/clk-smd.c | 157 ++++
drivers/clk/at91/clk-system.c | 189 ++++
drivers/clk/at91/clk-usb.c | 303 ++++++
drivers/clk/at91/clk-utmi.c | 114 +++
drivers/clocksource/tcb_clksrc.c | 10 +-
drivers/dma/at_hdmac.c | 12 +-
drivers/misc/atmel-ssc.c | 8 +-
drivers/mmc/host/atmel-mci.c | 16 +-
drivers/pwm/pwm-atmel-tcb.c | 4 +-
drivers/tty/serial/atmel_serial.c | 35 +-
drivers/usb/gadget/at91_udc.c | 12 +-
drivers/usb/gadget/atmel_usba_udc.c | 2 +-
drivers/usb/host/ehci-atmel.c | 8 +-
drivers/usb/host/ohci-at91.c | 12 +-
drivers/video/atmel_lcdfb.c | 8 +-
.../mach/at91_pmc.h => include/linux/clk/at91.h | 122 ++-
127 files changed, 7588 insertions(+), 3862 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/at91-clock.txt
create mode 100644 arch/arm/boot/dts/at91sam9x5_can.dtsi
create mode 100644 arch/arm/boot/dts/at91sam9x5_isi.dtsi
create mode 100644 arch/arm/boot/dts/at91sam9x5_lcdc.dtsi
create mode 100644 arch/arm/boot/dts/at91sam9x5_macb0.dtsi
create mode 100644 arch/arm/boot/dts/at91sam9x5_macb1.dtsi
create mode 100644 arch/arm/boot/dts/at91sam9x5_usart3.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_can.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_emac.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_gmac.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_lcd.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_mci2.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_tcb1.dtsi
create mode 100644 arch/arm/boot/dts/sama5d3_uart.dtsi
delete mode 100644 arch/arm/mach-at91/clock.c
delete mode 100644 arch/arm/mach-at91/clock.h
create mode 100644 arch/arm/mach-at91/pmc.c
create mode 100644 drivers/clk/at91/Makefile
create mode 100644 drivers/clk/at91/clk-main.c
create mode 100644 drivers/clk/at91/clk-master.c
create mode 100644 drivers/clk/at91/clk-peripheral.c
create mode 100644 drivers/clk/at91/clk-pll.c
create mode 100644 drivers/clk/at91/clk-plldiv.c
create mode 100644 drivers/clk/at91/clk-programmable.c
create mode 100644 drivers/clk/at91/clk-smd.c
create mode 100644 drivers/clk/at91/clk-system.c
create mode 100644 drivers/clk/at91/clk-usb.c
create mode 100644 drivers/clk/at91/clk-utmi.c
rename arch/arm/mach-at91/include/mach/at91_pmc.h => include/linux/clk/at91.h (76%)
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH] backlight: add CONFIG_PM_SLEEP to suspend/resume functions
From: Arnd Bergmann @ 2013-06-07 10:22 UTC (permalink / raw)
To: Jingoo Han
Cc: 'Andrew Morton', 'Shuah Khan', linux-fbdev,
linux-kernel, shuahkhan, rpurdie, FlorianSchandinat, plagnioj,
tomi.valkeinen, rafael.j.wysocki
In-Reply-To: <000201ce631f$d4ad0d50$7e0727f0$@samsung.com>
On Friday 07 June 2013 10:39:20 Jingoo Han wrote:
> Add CONFIG_PM_SLEEP to suspend/resume functions to fix the following
> build warning when CONFIG_PM_SLEEP is not selected. This is because
> sleep PM callbacks defined by SIMPLE_DEV_PM_OPS are only used when
> the CONFIG_PM_SLEEP is enabled.
>
> drivers/video/backlight/backlight.c:211:12: warning: 'backlight_suspend' defined but not used [-Wunused-function]
> drivers/video/backlight/backlight.c:225:12: warning: 'backlight_resume' defined but not used [-Wunused-function]
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
I forgot:
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [RFC 00/50] ARM: at91: move to common clk framework
From: Gregory CLEMENT @ 2013-06-07 10:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <51B1A894.80205@overkiz.com>
On 06/07/2013 11:32 AM, boris brezillon wrote:
> On 07/06/2013 11:22, Nicolas Ferre wrote:
>> On 07/06/2013 10:34, Boris BREZILLON :
>>> Hello,
>>>
>>> This patch series is a proposal to move at91 clock implementation
>>> to common clk framework.
>>
>> Before discussion begins I would like to give my kudos to you Boris!
>> This is huge work and I thank you for it: It is so great!
>>
>> I am sure that Jean-Christophe will have his idea on that because he
>> told me that he thought a little bit about that, but I am sure that we
>> will come to a quick and seamlessly integration soon.
>>
>> (Hey, I know it is not technical email, but I am so exited to see this
>> happen that the noise worth it! ;-))
> I received several notifications about filtered mails.
> Could you tell me if you received the whole series ?
I have just received this email. But since few days (or weeks) I have observed
a big latency on the LAKML. Sometime my emails were in the LAKML after 3 or 4
hours.
> And do you know why this could have been filtered ?
There is a filter which prevent to "hijack" a thread by changing the topic.
of course it is a problem for the patch set sent with git send-email. So for
this there is an exception if you have the word PATCH in your topic. But
it doesn't work with the work RFC. Maybe it is the word you have chosen. If
you are in this case then you can use [PATCH RFC ]
Regards
>
>
>>
>>> Most of the clock provided by the PMC (Power Management Controller) are
>>> implemented :
>>> - main clock (main oscillator)
>>> - pll clocks
>>> - master clock
>>> - programmable clocks
>>> - utmi clock
>>> - peripheral clocks
>>> - system clocks
>>>
>>> This implementation is compatible with device tree: the goal is
>>> to define the whole clock tree in the device tree (all currently
>>> available dt SoCs and boards are patched to support dt clocks).
>>> Please feel free to comment the dt bindinds (I'm not sure about the
>>> name I choose or the position of clock nodes: children of pmc node).
>>>
>>> I removed the register_clocks function in SoC supporting dt boards only:
>>> - at91sam9x5 SoCs
>>> - at91sam9n12 SoC
>>> - sama5d3 SoCs
>>>
>>> This patch series also update at91 drivers calling clk_enable/disable
>>> instead of the preferred clk_prepare_enable/disable_unprepare functions.
>>>
>>>
>>> I know there are a lot of cleanup in progress for at91 arch, so
>>> please tell
>>> me if you think this transition to common clk framework should wait.
>>>
>>> This patch series has been tested on Kizbox (sam9g20 SoC) board using
>>> device
>>> tree. It compiles for other SoCs and both with and without dt
>>> support, but it
>>> has not been tested.
>>>
>>> The clocks rate/parent change has not been tested.
>>>
>>> Best Regards,
>>> Boris
>>>
>>> Boris BREZILLON (50):
>>> ARM: at91: move arch/arm/mach-at91/include/mach/at91_pmc.h to
>>> include/linux/clk/at91.h
>>> ARM: at91: add PMC main clock using common clk framework.
>>> ARM: at91: add PMC pll clocks support using common clk framework.
>>> ARM: at91: add PMC master clock support using common clk framework.
>>> ARM: at91: add PMC system clocks support using common clk framework.
>>> ARM: at91: add PMC peripheral clocks support using common clk
>>> framework.
>>> ARM: at91: add PMC programmable clocks support using common clk
>>> framework.
>>> ARM: at91: add PMC utmi clock support using common clk framework.
>>> ARM: at91: add PMC usb clock support using common clk framework.
>>> ARM: at91: add PMC smd clock support using common clk framework.
>>> ARM: at91: add PMC clk device tree binding doc.
>>> ARM: at91: move to common clk framework.
>>> ARM: at91: move at91rm9200 SoC to common clk framework.
>>> ARM: at91: move at91sam9260 SoC to common clk framework.
>>> ARM: at91: move at91sam9263 SoC to common clk framework.
>>> ARM: at91: move at91sam9263 SoC to common clk framework.
>>> ARM: at91: move at91sam9g45 SoC to common clk framework.
>>> ARM: at91: move at91sam9n12 SoC to common clk framework.
>>> ARM: at91: move at91sam9rl SoC to common clk framework.
>>> ARM: at91: move at91sam9x5 SoCs to common clk framework.
>>> ARM: at91: move at91sam9 SoCs to common clk framework.
>>> ARM: at91: move sama5d3 SoCs to common clk framework.
>>> ARM: at91: move at91rm9200 non dt boards to common clk framework.
>>> ARM: at91: move at91sam9 non dt boards to common clk framework.
>>> ARM: at91: move pit timer to common clk framework.
>>> ARM: at91/tc/clocksource: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> at_hdmac: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> ASoC: atmel-ssc: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> mmc: atmel-mci: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> pwm: atmel-tcb: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> tty: atmel_serial: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> usb: gadget: at91_udc: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> drivers/usb/host/ehci-atmel.c: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> USB: ohci-at91: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> ARM: at91/avr32/atmel_lcdfb: replace clk_enable/disable with
>>> clk_prepare_enable/disable_unprepare.
>>> ARM: at91/dt: move at91rm9200 SoC to clk framework.
>>> ARM: at91/dt: move at91sam9260 SoC to common clk framework.
>>> ARM: at91/dt: move at91sam9263 SoC to common clk framework.
>>> ARM: at91/dt: move at91sam9g45 SoC to common clk framework.
>>> ARM: at91/dt: move at91sam9n12 SoC to common clk framework.
>>> ARM: at91/dt: move at91sam9x5 SoCs to common clk framework.
>>> ARM: at91/dt: move at91sam9g20 SoC to common clk framework.
>>> ARM: at91/dt: move sama5d3 SoCs to common clk framework.
>>> ARM: at91/dt: move at91sam9260/sam9g20 boards to common clk
>>> framework.
>>> ARM: at91/dt: move at91rm9200 boards to common clk framework.
>>> ARM: at91/dt: move at91sam9263 boards to common clk framework.
>>> ARM: at91/dt: move at91sam9g45 boards to common clk framework.
>>> ARM: at91/dt: move at91sam9n12 boards to common clk framework.
>>> ARM: at91/dt: move at91sam9x5 boards to common clk framework.
>>> ARM: at91/dt: move sama5d3 boards to common clk framework.
>>>
>>> .../devicetree/bindings/clock/at91-clock.txt | 247 +++++
>>> arch/arm/boot/dts/animeo_ip.dts | 17 +-
>>> arch/arm/boot/dts/at91-ariag25.dts | 17 +-
>>> arch/arm/boot/dts/at91rm9200.dtsi | 133 +++
>>> arch/arm/boot/dts/at91rm9200ek.dts | 17 +-
>>> arch/arm/boot/dts/at91sam9260.dtsi | 144 ++-
>>> arch/arm/boot/dts/at91sam9263.dtsi | 135 +++
>>> arch/arm/boot/dts/at91sam9263ek.dts | 17 +-
>>> arch/arm/boot/dts/at91sam9g15.dtsi | 11 +
>>> arch/arm/boot/dts/at91sam9g20.dtsi | 37 +
>>> arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 17 +-
>>> arch/arm/boot/dts/at91sam9g25.dtsi | 3 +
>>> arch/arm/boot/dts/at91sam9g35.dtsi | 23 +
>>> arch/arm/boot/dts/at91sam9g45.dtsi | 157 ++++
>>> arch/arm/boot/dts/at91sam9m10g45ek.dts | 17 +-
>>> arch/arm/boot/dts/at91sam9n12.dtsi | 153 ++++
>>> arch/arm/boot/dts/at91sam9n12ek.dts | 17 +-
>>> arch/arm/boot/dts/at91sam9x25.dtsi | 25 +-
>>> arch/arm/boot/dts/at91sam9x35.dtsi | 3 +
>>> arch/arm/boot/dts/at91sam9x5.dtsi | 226 +++--
>>> arch/arm/boot/dts/at91sam9x5_can.dtsi | 24 +
>>> arch/arm/boot/dts/at91sam9x5_isi.dtsi | 24 +
>>> arch/arm/boot/dts/at91sam9x5_lcdc.dtsi | 32 +
>>> arch/arm/boot/dts/at91sam9x5_macb0.dtsi | 68 ++
>>> arch/arm/boot/dts/at91sam9x5_macb1.dtsi | 56 ++
>>> arch/arm/boot/dts/at91sam9x5_usart3.dtsi | 60 ++
>>> arch/arm/boot/dts/ge863-pro3.dtsi | 16 +-
>>> arch/arm/boot/dts/kizbox.dts | 5 +
>>> arch/arm/boot/dts/mpa1600.dts | 16 +-
>>> arch/arm/boot/dts/pm9g45.dts | 16 +-
>>> arch/arm/boot/dts/sama5d3.dtsi | 358 ++++----
>>> arch/arm/boot/dts/sama5d31ek.dts | 4 +
>>> arch/arm/boot/dts/sama5d33ek.dts | 2 +
>>> arch/arm/boot/dts/sama5d34ek.dts | 4 +
>>> arch/arm/boot/dts/sama5d35ek.dts | 6 +
>>> arch/arm/boot/dts/sama5d3_can.dtsi | 67 ++
>>> arch/arm/boot/dts/sama5d3_emac.dtsi | 56 ++
>>> arch/arm/boot/dts/sama5d3_gmac.dtsi | 89 ++
>>> arch/arm/boot/dts/sama5d3_lcd.dtsi | 73 ++
>>> arch/arm/boot/dts/sama5d3_mci2.dtsi | 59 ++
>>> arch/arm/boot/dts/sama5d3_tcb1.dtsi | 39 +
>>> arch/arm/boot/dts/sama5d3_uart.dtsi | 42 +
>>> arch/arm/boot/dts/sama5d3xcm.dtsi | 17 +-
>>> arch/arm/boot/dts/tny_a9260_common.dtsi | 17 +-
>>> arch/arm/boot/dts/tny_a9263.dts | 17 +-
>>> arch/arm/boot/dts/usb_a9260_common.dtsi | 17 +-
>>> arch/arm/boot/dts/usb_a9263.dts | 17 +-
>>> arch/arm/mach-at91/Kconfig | 26 +
>>> arch/arm/mach-at91/Makefile | 2 +-
>>> arch/arm/mach-at91/at91rm9200.c | 578 +++++++-----
>>> arch/arm/mach-at91/at91sam9260.c | 694
>>> +++++++++-----
>>> arch/arm/mach-at91/at91sam9261.c | 581 ++++++++----
>>> arch/arm/mach-at91/at91sam9263.c | 599 +++++++-----
>>> arch/arm/mach-at91/at91sam926x_time.c | 21 +-
>>> arch/arm/mach-at91/at91sam9g45.c | 705
>>> ++++++++------
>>> arch/arm/mach-at91/at91sam9g45_devices.c | 1 -
>>> arch/arm/mach-at91/at91sam9n12.c | 196 +---
>>> arch/arm/mach-at91/at91sam9rl.c | 514 +++++++----
>>> arch/arm/mach-at91/at91sam9x5.c | 291 +-----
>>> arch/arm/mach-at91/board-1arm.c | 12 +-
>>> arch/arm/mach-at91/board-afeb-9260v1.c | 11 +-
>>> arch/arm/mach-at91/board-cam60.c | 13 +-
>>> arch/arm/mach-at91/board-carmeva.c | 13 +-
>>> arch/arm/mach-at91/board-cpu9krea.c | 12 +-
>>> arch/arm/mach-at91/board-cpuat91.c | 12 +-
>>> arch/arm/mach-at91/board-csb337.c | 11 +-
>>> arch/arm/mach-at91/board-csb637.c | 11 +-
>>> arch/arm/mach-at91/board-dt-rm9200.c | 9 +-
>>> arch/arm/mach-at91/board-dt-sam9.c | 9 +-
>>> arch/arm/mach-at91/board-dt-sama5.c | 9 +-
>>> arch/arm/mach-at91/board-eb9200.c | 11 +-
>>> arch/arm/mach-at91/board-ecbat91.c | 12 +-
>>> arch/arm/mach-at91/board-eco920.c | 13 +-
>>> arch/arm/mach-at91/board-flexibity.c | 12 +-
>>> arch/arm/mach-at91/board-foxg20.c | 12 +-
>>> arch/arm/mach-at91/board-gsia18s.c | 8 +-
>>> arch/arm/mach-at91/board-kafa.c | 12 +-
>>> arch/arm/mach-at91/board-kb9202.c | 12 +-
>>> arch/arm/mach-at91/board-pcontrol-g20.c | 9 +-
>>> arch/arm/mach-at91/board-picotux200.c | 11 +-
>>> arch/arm/mach-at91/board-qil-a9260.c | 11 +-
>>> arch/arm/mach-at91/board-rm9200dk.c | 11 +-
>>> arch/arm/mach-at91/board-rm9200ek.c | 11 +-
>>> arch/arm/mach-at91/board-rsi-ews.c | 12 +-
>>> arch/arm/mach-at91/board-sam9-l9260.c | 11 +-
>>> arch/arm/mach-at91/board-sam9260ek.c | 11 +-
>>> arch/arm/mach-at91/board-sam9261ek.c | 15 +-
>>> arch/arm/mach-at91/board-sam9263ek.c | 11 +-
>>> arch/arm/mach-at91/board-sam9g20ek.c | 15 +-
>>> arch/arm/mach-at91/board-sam9m10g45ek.c | 11 +-
>>> arch/arm/mach-at91/board-sam9rlek.c | 11 +-
>>> arch/arm/mach-at91/board-snapper9260.c | 12 +-
>>> arch/arm/mach-at91/board-stamp9g20.c | 15 +-
>>> arch/arm/mach-at91/board-yl-9200.c | 12 +-
>>> arch/arm/mach-at91/clock.c | 961
>>> --------------------
>>> arch/arm/mach-at91/clock.h | 49 -
>>> arch/arm/mach-at91/generic.h | 10 +-
>>> arch/arm/mach-at91/pm.c | 2 +-
>>> arch/arm/mach-at91/pm_slowclock.S | 2 +-
>>> arch/arm/mach-at91/pmc.c | 58 ++
>>> arch/arm/mach-at91/sama5d3.c | 344 +------
>>> arch/arm/mach-at91/setup.c | 38 +-
>>> arch/arm/mach-at91/stamp9g20.h | 2 +-
>>> drivers/clk/Makefile | 1 +
>>> drivers/clk/at91/Makefile | 11 +
>>> drivers/clk/at91/clk-main.c | 106 +++
>>> drivers/clk/at91/clk-master.c | 317 +++++++
>>> drivers/clk/at91/clk-peripheral.c | 376 ++++++++
>>> drivers/clk/at91/clk-pll.c | 438 +++++++++
>>> drivers/clk/at91/clk-plldiv.c | 125 +++
>>> drivers/clk/at91/clk-programmable.c | 370 ++++++++
>>> drivers/clk/at91/clk-smd.c | 157 ++++
>>> drivers/clk/at91/clk-system.c | 189 ++++
>>> drivers/clk/at91/clk-usb.c | 303 ++++++
>>> drivers/clk/at91/clk-utmi.c | 114 +++
>>> drivers/clocksource/tcb_clksrc.c | 10 +-
>>> drivers/dma/at_hdmac.c | 12 +-
>>> drivers/misc/atmel-ssc.c | 8 +-
>>> drivers/mmc/host/atmel-mci.c | 16 +-
>>> drivers/pwm/pwm-atmel-tcb.c | 4 +-
>>> drivers/tty/serial/atmel_serial.c | 35 +-
>>> drivers/usb/gadget/at91_udc.c | 12 +-
>>> drivers/usb/gadget/atmel_usba_udc.c | 2 +-
>>> drivers/usb/host/ehci-atmel.c | 8 +-
>>> drivers/usb/host/ohci-at91.c | 12 +-
>>> drivers/video/atmel_lcdfb.c | 8 +-
>>> .../mach/at91_pmc.h => include/linux/clk/at91.h | 122 ++-
>>> 127 files changed, 7588 insertions(+), 3862 deletions(-)
>>> create mode 100644
>>> Documentation/devicetree/bindings/clock/at91-clock.txt
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_can.dtsi
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_isi.dtsi
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_lcdc.dtsi
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_macb0.dtsi
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_macb1.dtsi
>>> create mode 100644 arch/arm/boot/dts/at91sam9x5_usart3.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_can.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_emac.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_gmac.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_lcd.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_mci2.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_tcb1.dtsi
>>> create mode 100644 arch/arm/boot/dts/sama5d3_uart.dtsi
>>> delete mode 100644 arch/arm/mach-at91/clock.c
>>> delete mode 100644 arch/arm/mach-at91/clock.h
>>> create mode 100644 arch/arm/mach-at91/pmc.c
>>> create mode 100644 drivers/clk/at91/Makefile
>>> create mode 100644 drivers/clk/at91/clk-main.c
>>> create mode 100644 drivers/clk/at91/clk-master.c
>>> create mode 100644 drivers/clk/at91/clk-peripheral.c
>>> create mode 100644 drivers/clk/at91/clk-pll.c
>>> create mode 100644 drivers/clk/at91/clk-plldiv.c
>>> create mode 100644 drivers/clk/at91/clk-programmable.c
>>> create mode 100644 drivers/clk/at91/clk-smd.c
>>> create mode 100644 drivers/clk/at91/clk-system.c
>>> create mode 100644 drivers/clk/at91/clk-usb.c
>>> create mode 100644 drivers/clk/at91/clk-utmi.c
>>> rename arch/arm/mach-at91/include/mach/at91_pmc.h =>
>>> include/linux/clk/at91.h (76%)
>>>
>>
>>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox