* [PATCH] [ARM] Use AT() in the linker script to create correct program headers
From: Dave Martin @ 2012-10-08 10:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121005084500.GI4625@n2100.arm.linux.org.uk>
On Fri, Oct 05, 2012 at 09:45:00AM +0100, Russell King - ARM Linux wrote:
> On Mon, Oct 01, 2012 at 10:06:39AM -0600, Jason Gunthorpe wrote:
> > On Mon, Oct 01, 2012 at 04:39:53PM +0100, Dave Martin wrote:
> > > > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
> > > > LOAD 0x008000 0xc0008000 0x00008000 0x372244 0x3a4310 RWE 0x8000
> > >
> > > Not related directly to your patch, but I wonder why we don't we see
> > > separate r-x and rw- segments?
> >
> > I think this is because the sections are not aligned when the
> > protections change, and the sections are not sorted by protection
> > type.
>
> They aren't sorted by protection type, they're ordered according to what's
> required for the kernel - which is to have the init sections together as
> one complete block so that it can be freed, and to place all of the kernel
> text as close to the beginning of the image as possible.
Ah, right.
Partly this came from some side speculation about whether we could do
things like privileged read-only permissions on newer CPUs, for preventing
unintended or undesired writes to the kernel's code or read-only data.
There would be various things to solve in order to make that work, so I
guess there's no great urgency for it right now.
Cheers
---Dave
^ permalink raw reply
* [PATCH] ARM: tegra: rename the file of "sleep-tXX" to "sleep-tegraXX"
From: Joseph Lo @ 2012-10-08 10:23 UTC (permalink / raw)
To: linux-arm-kernel
For the naming consistency under the mach-tegra, we re-name the file of
"sleep-tXX" to "sleep-tegraXX" (e.g., sleep-t30 to sleep-tegra30).
Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
arch/arm/mach-tegra/Makefile | 4 ++--
.../mach-tegra/{sleep-t20.S => sleep-tegra20.S} | 0
.../mach-tegra/{sleep-t30.S => sleep-tegra30.S} | 0
3 files changed, 2 insertions(+), 2 deletions(-)
rename arch/arm/mach-tegra/{sleep-t20.S => sleep-tegra20.S} (100%)
rename arch/arm/mach-tegra/{sleep-t30.S => sleep-tegra30.S} (100%)
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 9aa653b..e6929c6 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -13,10 +13,10 @@ obj-$(CONFIG_CPU_IDLE) += sleep.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_clocks_data.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-t20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += sleep-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30_clocks_data.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-t30.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += sleep-tegra30.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_SMP) += reset.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-tegra/sleep-t20.S b/arch/arm/mach-tegra/sleep-tegra20.S
similarity index 100%
rename from arch/arm/mach-tegra/sleep-t20.S
rename to arch/arm/mach-tegra/sleep-tegra20.S
diff --git a/arch/arm/mach-tegra/sleep-t30.S b/arch/arm/mach-tegra/sleep-tegra30.S
similarity index 100%
rename from arch/arm/mach-tegra/sleep-t30.S
rename to arch/arm/mach-tegra/sleep-tegra30.S
--
1.7.0.4
^ permalink raw reply related
* Mismatched aliases with DMA mappings?
From: Dave Martin @ 2012-10-08 10:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5071290A.6030902@samsung.com>
On Sun, Oct 07, 2012 at 09:02:34AM +0200, Marek Szyprowski wrote:
> Hello,
>
> I'm sorry for very late response but I was busy with other urgent
> items after getting back from holidays.
>
> On 9/24/2012 11:52 AM, Dave Martin wrote:
> >On Sat, Sep 22, 2012 at 02:22:07PM +0900, Kyungmin Park wrote:
>
> >>I just show how CMA addresses mismatched aliases codes.
> >>
> >>In reserve function, it declares the require memory size with base
> >>address. At that time it calles 'dma_contiguous_early_fixup()'. it
> >>just registered address and size.
> >>
> >>void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long
> >>size)
> >>{
> >> dma_mmu_remap[dma_mmu_remap_num].base = base;
> >> dma_mmu_remap[dma_mmu_remap_num].size = size;
> >> dma_mmu_remap_num++;
> >>}
> >>
> >>These registerd base and size will be remap at dma_contiguous_remap
> >>function at paging_init.
> >>
> >>void __init dma_contiguous_remap(void)
> >>{
> >> int i;
> >> for (i = 0; i < dma_mmu_remap_num; i++) {
> >> phys_addr_t start = dma_mmu_remap[i].base;
> >> phys_addr_t end = start + dma_mmu_remap[i].size;
> >> struct map_desc map;
> >> unsigned long addr;
> >>
> >> if (end > arm_lowmem_limit)
> >> end = arm_lowmem_limit;
> >> if (start >= end)
> >> continue;
> >>
> >> map.pfn = __phys_to_pfn(start);
> >> map.virtual = __phys_to_virt(start);
> >> map.length = end - start;
> >> map.type = MT_MEMORY_DMA_READY;
> >>
> >> /*
> >> * Clear previous low-memory mapping
> >> */
> >> for (addr = __phys_to_virt(start); addr <
> >>__phys_to_virt(end);
> >> addr += PMD_SIZE)
> >> pmd_clear(pmd_off_k(addr));
> >>
> >> iotable_init(&map, 1);
> >> }
> >>}
> >
> >OK, so it looks like this is done early and can't happen after the
> >kernel has booted (?)
>
> Right, the changes in the linear mapping for CMA areas are done very
> early to make sure that the proper mapping will be available for all
> processes in the system (CMA changes the size of the pages used for
> holding low memory linear mappings from 1MiB/2MiB 1-level sections
> to 4KiB pages which require 2 levels of pte). Once the kernel has
> fully started it is not (easily) possible to alter the linear
> mappings.
>
> >Do you know whether the linear alias for DMA memory is removed when
> >not using CMA?
>
> Nope, when standard page_alloc() implementation of dma mapping is
> used there exist 2 mappings for each allocated buffer: one in linear
> low memory kernel mapping (cache'able) and the second created by the
> dma-mapping subsystem (non-cache'able or writecombined). Right now
> no one observed any issues caused by such situation assuming that no
> process is accessing linear cache'able lowmem mappings when dma
> non-cache'able mapping exist.
Thanks, that clarifies my understanding.
Eventually, I decided it was not worth attempting to allocate non-
cacheable memory for my case, and I use normal memory with explicit
maintenance instead. This is a little more cumbersome, but so far
it appears to work.
Cheers
---Dave
^ permalink raw reply
* [PATCH 2/2] [media]: mx2_camera: Fix regression caused by clock conversion
From: Gaëtan Carlier @ 2012-10-08 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349473981-15084-1-git-send-email-fabio.estevam@freescale.com>
Hi,
On 10/05/2012 11:53 PM, Fabio Estevam wrote:
> Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
> to acquire the csi clock is to get csi_ahb and csi_per clocks separately.
>
> By not doing so the camera sensor does not probe correctly:
>
> soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0
> mx2-camera mx2-camera.0: Camera driver attached to camera 0
> ov2640 0-0030: Product ID error fb:fb
> mx2-camera mx2-camera.0: Camera driver detached from camera 0
> mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000
>
> Adapt the mx2_camera driver to the new clock framework and make it functional
> again.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> drivers/media/platform/soc_camera/mx2_camera.c | 42 ++++++++++++++++--------
> 1 file changed, 29 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
> index 0c0dd74..2c67969 100644
> --- a/drivers/media/platform/soc_camera/mx2_camera.c
> +++ b/drivers/media/platform/soc_camera/mx2_camera.c
> @@ -272,8 +272,9 @@ struct mx2_camera_dev {
> struct device *dev;
> struct soc_camera_host soc_host;
> struct soc_camera_device *icd;
> - struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
> -
> + struct clk *clk_emma_ahb, *clk_emma_ipg;
> + struct clk *clk_csi_ahb, *clk_csi_per;
> +
> unsigned int irq_csi, irq_emma;
> void __iomem *base_csi, *base_emma;
> unsigned long base_dma;
> @@ -435,7 +436,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
> {
> unsigned long flags;
>
> - clk_disable_unprepare(pcdev->clk_csi);
> + clk_disable_unprepare(pcdev->clk_csi_ahb);
> + clk_disable_unprepare(pcdev->clk_csi_per);
> writel(0, pcdev->base_csi + CSICR1);
> if (cpu_is_mx27()) {
> writel(0, pcdev->base_emma + PRP_CNTL);
> @@ -463,7 +465,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
> if (pcdev->icd)
> return -EBUSY;
>
> - ret = clk_prepare_enable(pcdev->clk_csi);
> + ret = clk_prepare_enable(pcdev->clk_csi_ahb);
> + if (ret < 0)
> + return ret;
> +
> + ret = clk_prepare_enable(pcdev->clk_csi_per);
> if (ret < 0)
> return ret;
>
> @@ -1736,13 +1742,21 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
> goto exit;
> }
>
> - pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
> - if (IS_ERR(pcdev->clk_csi)) {
> - dev_err(&pdev->dev, "Could not get csi clock\n");
> - err = PTR_ERR(pcdev->clk_csi);
> + pcdev->clk_csi_ahb = clk_get(&pdev->dev, "ahb");
> + if (IS_ERR(pcdev->clk_csi_ahb)) {
> + dev_err(&pdev->dev, "Could not get csi ahb clock\n");
> + err = PTR_ERR(pcdev->clk_csi_ahb);
> goto exit_kfree;
> }
>
> + pcdev->clk_csi_per = clk_get(&pdev->dev, "per");
> + if (IS_ERR(pcdev->clk_csi_per)) {
> + dev_err(&pdev->dev, "Could not get csi per clock\n");
> + err = PTR_ERR(pcdev->clk_csi_per);
> + goto exit_kfree;
> + }
> +
> +
> pcdev->res_csi = res_csi;
> pcdev->pdata = pdev->dev.platform_data;
> if (pcdev->pdata) {
> @@ -1750,12 +1764,12 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
>
> pcdev->platform_flags = pcdev->pdata->flags;
>
> - rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
> + rate = clk_round_rate(pcdev->clk_csi_per, pcdev->pdata->clk * 2);
> if (rate <= 0) {
> err = -ENODEV;
> goto exit_dma_free;
> }
> - err = clk_set_rate(pcdev->clk_csi, rate);
> + err = clk_set_rate(pcdev->clk_csi_per, rate);
> if (err < 0)
> goto exit_dma_free;
> }
> @@ -1827,7 +1841,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
> goto exit_free_emma;
>
> dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
> - clk_get_rate(pcdev->clk_csi));
> + clk_get_rate(pcdev->clk_csi_per));
>
> return 0;
>
> @@ -1851,7 +1865,8 @@ exit_iounmap:
> exit_release:
> release_mem_region(res_csi->start, resource_size(res_csi));
> exit_dma_free:
> - clk_put(pcdev->clk_csi);
> + clk_put(pcdev->clk_csi_per);
> + clk_put(pcdev->clk_csi_ahb);
> exit_kfree:
> kfree(pcdev);
> exit:
> @@ -1865,7 +1880,8 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
> struct mx2_camera_dev, soc_host);
> struct resource *res;
>
> - clk_put(pcdev->clk_csi);
> + clk_put(pcdev->clk_csi_per);
> + clk_put(pcdev->clk_csi_ahb);
> if (cpu_is_mx25())
> free_irq(pcdev->irq_csi, pcdev);
> if (cpu_is_mx27())
>
This patch does not apply on linux-next-20121008. I suppose that
linux-media development branch is needed. How can I put linux-media
branch on top of linux-next using git ?
Is the linux-media branch is always compatible with linux-next ?
Thanks a lot,
Ga?tan Carlier.
^ permalink raw reply
* [PATCH 14/15] KVM: ARM: Handle I/O aborts
From: Dave Martin @ 2012-10-08 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121005090025.GK4625@n2100.arm.linux.org.uk>
On Fri, Oct 05, 2012 at 10:00:25AM +0100, Russell King - ARM Linux wrote:
> On Mon, Oct 01, 2012 at 01:53:26PM +0100, Dave Martin wrote:
> > A good starting point would be load/store emulation as this seems to be a
> > common theme, and we would need a credible deployment for any new
> > framework so that we know it's fit for purpose.
>
> Probably not actually, that code is written to be fast, because things
> like IP stack throughput depend on it - particularly when your network
> card can only DMA packets to 32-bit aligned addresses (resulting in
> virtually all network data being misaligned.)
A fair point, but surely it would still be worth a try?
We might decide that a few particular cases of instruction decode
should not use the generic framework for performance reaons, but in
most cases being critically dependent on fault-driven software
emulation for performance would be a serious mistake in the first place
(discussions about the network code notwithstanding).
This is not an argument for being slower just for the sake of it, but
it can make sense to factor code on paths where performance is not an
issue.
Cheers
---Dave
^ permalink raw reply
* [PATCH 1/3] i2c: omap: Do not enable the irq always
From: Russell King - ARM Linux @ 2012-10-08 9:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349687116-14463-1-git-send-email-shubhrajyoti@ti.com>
On Mon, Oct 08, 2012 at 02:35:14PM +0530, Shubhrajyoti D wrote:
> Enable the irq in the transfer and disable it after the
> transfer is done.
This description is missing the most vital bits of information. In years
to come, someone will wonder "why has this changed" and there's no reason
given in the commit log.
Commit logs which are just mere translations from patch to English are
evil. Instead, good commit logs briefly state what is being done and
then go on to describe _why_ the change is necessary.
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> drivers/i2c/busses/i2c-omap.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index b6c6b95..ce41596 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -625,6 +625,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
> if (IS_ERR_VALUE(r))
> goto out;
>
> + enable_irq(dev->irq);
> r = omap_i2c_wait_for_bb(dev);
> if (r < 0)
> goto out;
> @@ -654,6 +655,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>
> omap_i2c_wait_for_bb(dev);
> out:
> + disable_irq(dev->irq);
> pm_runtime_mark_last_busy(dev->dev);
> pm_runtime_put_autosuspend(dev->dev);
> return r;
> @@ -1179,6 +1181,7 @@ omap_i2c_probe(struct platform_device *pdev)
> goto err_unuse_clocks;
> }
>
> + disable_irq(dev->irq);
> adap = &dev->adapter;
> i2c_set_adapdata(adap, dev);
> adap->owner = THIS_MODULE;
> --
> 1.7.5.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2] ARM: imx_v6_v7_defconfig: Enable CONFIG_GPIO_MC9S08DZ60
From: Sascha Hauer @ 2012-10-08 9:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1347647145-23798-1-git-send-email-fabio.estevam@freescale.com>
On Fri, Sep 14, 2012 at 03:25:45PM -0300, Fabio Estevam wrote:
> On mx35pdk board there is an 8-bit microcontroller that controls several IOs, such
> as backlight enable pin, USB host VBUS, etc.
>
> Let it build by default.
>
> mx35pdk also needs CONFIG_LCD_PLATFORM to be selected to activate the display,
> so also make this the default.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Applied, thanks
Sascha
> ---
> Changes since v1:
> - Also select CONFIG_LCD_PLATFORM
> arch/arm/configs/imx_v6_v7_defconfig | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
> index 565132d..8cfd747 100644
> --- a/arch/arm/configs/imx_v6_v7_defconfig
> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> @@ -140,6 +140,7 @@ CONFIG_I2C_IMX=y
> CONFIG_SPI=y
> CONFIG_SPI_IMX=y
> CONFIG_GPIO_SYSFS=y
> +CONFIG_GPIO_MC9S08DZ60=y
> # CONFIG_HWMON is not set
> CONFIG_WATCHDOG=y
> CONFIG_IMX2_WDT=y
> @@ -156,6 +157,7 @@ CONFIG_SOC_CAMERA=y
> CONFIG_SOC_CAMERA_OV2640=y
> CONFIG_VIDEO_MX3=y
> CONFIG_FB=y
> +CONFIG_LCD_PLATFORM=y
> CONFIG_BACKLIGHT_LCD_SUPPORT=y
> CONFIG_LCD_CLASS_DEVICE=y
> CONFIG_LCD_L4F00242T03=y
> --
> 1.7.9.5
>
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 3/3] ARM: imx_v6_v7_defconfig: Add DA9052 regulator support
From: Sascha Hauer @ 2012-10-08 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1348702057-2351-3-git-send-email-festevam@gmail.com>
On Wed, Sep 26, 2012 at 08:27:37PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> Add DA9052 regulator support.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Applied, thanks
Sascha
> ---
> arch/arm/configs/imx_v6_v7_defconfig | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
> index 66aa7a6..67620d6 100644
> --- a/arch/arm/configs/imx_v6_v7_defconfig
> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> @@ -142,10 +142,12 @@ CONFIG_GPIO_SYSFS=y
> # CONFIG_HWMON is not set
> CONFIG_WATCHDOG=y
> CONFIG_IMX2_WDT=y
> +CONFIG_MFD_DA9052_I2C=y
> CONFIG_MFD_MC13XXX_SPI=y
> CONFIG_MFD_MC13XXX_I2C=y
> CONFIG_REGULATOR=y
> CONFIG_REGULATOR_FIXED_VOLTAGE=y
> +CONFIG_REGULATOR_DA9052=y
> CONFIG_REGULATOR_MC13783=y
> CONFIG_REGULATOR_MC13892=y
> CONFIG_MEDIA_SUPPORT=y
> --
> 1.7.9.5
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH] ARM: imx: fix return value check in imx3_init_l2x0()
From: Sascha Hauer @ 2012-10-08 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAPgLHd8Rma5fSWPtjvLr18TEmmC=8kOjmSJtneO0Ecd1bvOrcg@mail.gmail.com>
On Thu, Sep 27, 2012 at 01:54:01PM +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
>
> In case of error, the function ioremap() returns NULL
> not ERR_PTR(). The IS_ERR() test in the return value
> check should be replaced with NULL test.
>
> dpatch engine is used to auto generate this patch.
> (https://github.com/weiyj/dpatch)
>
> Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Appied, thanks
Sascha
> ---
> arch/arm/mach-imx/mm-imx3.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
> index 9d2c843..b5deb05 100644
> --- a/arch/arm/mach-imx/mm-imx3.c
> +++ b/arch/arm/mach-imx/mm-imx3.c
> @@ -108,9 +108,8 @@ void __init imx3_init_l2x0(void)
> }
>
> l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
> - if (IS_ERR(l2x0_base)) {
> - printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
> - PTR_ERR(l2x0_base));
> + if (!l2x0_base) {
> + printk(KERN_ERR "remapping L2 cache area failed\n");
> return;
> }
>
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH V4] MXS: Implement DMA support into mxs-i2c
From: Wolfram Sang @ 2012-10-08 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1345779871-7677-1-git-send-email-marex@denx.de>
On Fri, Aug 24, 2012 at 05:44:31AM +0200, Marek Vasut wrote:
> This patch implements DMA support into mxs-i2c. DMA transfers are now enabled
> via DT. The DMA operation is enabled by default.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
Thanks, applied to -next.
I am meanwhile thinking the driver needs massive changes, probably
dropping PIOQUEUE entirely. This is probably best done via incremental
patches to this one. I have sketches which were sadly not ready for this
merge-window :(
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121008/2e129d13/attachment.sig>
^ permalink raw reply
* [PATCH 00/16] More omap plat header cleanup for v3.8 merge window
From: Santosh Shilimkar @ 2012-10-08 9:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50729461.8090504@ti.com>
On Monday 08 October 2012 02:22 PM, Santosh Shilimkar wrote:
> Tony,
>
> On Friday 05 October 2012 03:34 AM, Tony Lindgren wrote:
>> Hi all,
>>
>> Here are some more patches for early merging after -rc1 for v3.8
>> merge window to remove more plat includes for the ARM common
>> zImage support. These are based on top of current linux next +
>> kevin's cpufreq fixes.
>>
> Have scanned the series and movement looks fine. For the SRAM movement,
> I just wanted to to check if the builds are fine with errata WA enabled
> for OMAP4. Do you have a branch where you are stacking up these patches?
>
Found the branch 'tmp-testing-header-cleanup' which had these patches.
Did few build test along with the errata related build. No issues seen.
Feel free to add my ack for the series.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
^ permalink raw reply
* [PATCH 2/2] [media]: mx2_camera: Fix regression caused by clock conversion
From: javier Martin @ 2012-10-08 9:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.64.1210081108130.12203@axis700.grange>
On 8 October 2012 11:09, Guennadi Liakhovetski <g.liakhovetski@gmx.de> wrote:
> Hi Fabio
>
> On Fri, 5 Oct 2012, Fabio Estevam wrote:
>
>> Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
>> to acquire the csi clock is to get csi_ahb and csi_per clocks separately.
>>
>> By not doing so the camera sensor does not probe correctly:
>>
>> soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0
>> mx2-camera mx2-camera.0: Camera driver attached to camera 0
>> ov2640 0-0030: Product ID error fb:fb
>> mx2-camera mx2-camera.0: Camera driver detached from camera 0
>> mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000
>>
>> Adapt the mx2_camera driver to the new clock framework and make it functional
>> again.
>
> Do I understand it right, that since the driver is currently broken, it
> doesn't matter any more in which order these two patches get applied, so,
> we can push them via different trees - ARM and media?
>
> Thanks
> Guennadi
>
Please,
hold on a couple of days before merging this one.
This driver is currently working in our Visstrim M10 platform without
this patch and I need to test it to confirm whether it breaks
something or not.
Regards.
--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
^ permalink raw reply
* [PATCH 2/2] [media]: mx2_camera: Fix regression caused by clock conversion
From: Guennadi Liakhovetski @ 2012-10-08 9:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349473981-15084-1-git-send-email-fabio.estevam@freescale.com>
Hi Fabio
On Fri, 5 Oct 2012, Fabio Estevam wrote:
> Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
> to acquire the csi clock is to get csi_ahb and csi_per clocks separately.
>
> By not doing so the camera sensor does not probe correctly:
>
> soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0
> mx2-camera mx2-camera.0: Camera driver attached to camera 0
> ov2640 0-0030: Product ID error fb:fb
> mx2-camera mx2-camera.0: Camera driver detached from camera 0
> mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000
>
> Adapt the mx2_camera driver to the new clock framework and make it functional
> again.
Do I understand it right, that since the driver is currently broken, it
doesn't matter any more in which order these two patches get applied, so,
we can push them via different trees - ARM and media?
Thanks
Guennadi
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> drivers/media/platform/soc_camera/mx2_camera.c | 42 ++++++++++++++++--------
> 1 file changed, 29 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
> index 0c0dd74..2c67969 100644
> --- a/drivers/media/platform/soc_camera/mx2_camera.c
> +++ b/drivers/media/platform/soc_camera/mx2_camera.c
> @@ -272,8 +272,9 @@ struct mx2_camera_dev {
> struct device *dev;
> struct soc_camera_host soc_host;
> struct soc_camera_device *icd;
> - struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
> -
> + struct clk *clk_emma_ahb, *clk_emma_ipg;
> + struct clk *clk_csi_ahb, *clk_csi_per;
> +
> unsigned int irq_csi, irq_emma;
> void __iomem *base_csi, *base_emma;
> unsigned long base_dma;
> @@ -435,7 +436,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
> {
> unsigned long flags;
>
> - clk_disable_unprepare(pcdev->clk_csi);
> + clk_disable_unprepare(pcdev->clk_csi_ahb);
> + clk_disable_unprepare(pcdev->clk_csi_per);
> writel(0, pcdev->base_csi + CSICR1);
> if (cpu_is_mx27()) {
> writel(0, pcdev->base_emma + PRP_CNTL);
> @@ -463,7 +465,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
> if (pcdev->icd)
> return -EBUSY;
>
> - ret = clk_prepare_enable(pcdev->clk_csi);
> + ret = clk_prepare_enable(pcdev->clk_csi_ahb);
> + if (ret < 0)
> + return ret;
> +
> + ret = clk_prepare_enable(pcdev->clk_csi_per);
> if (ret < 0)
> return ret;
>
> @@ -1736,13 +1742,21 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
> goto exit;
> }
>
> - pcdev->clk_csi = clk_get(&pdev->dev, "ahb");
> - if (IS_ERR(pcdev->clk_csi)) {
> - dev_err(&pdev->dev, "Could not get csi clock\n");
> - err = PTR_ERR(pcdev->clk_csi);
> + pcdev->clk_csi_ahb = clk_get(&pdev->dev, "ahb");
> + if (IS_ERR(pcdev->clk_csi_ahb)) {
> + dev_err(&pdev->dev, "Could not get csi ahb clock\n");
> + err = PTR_ERR(pcdev->clk_csi_ahb);
> goto exit_kfree;
> }
>
> + pcdev->clk_csi_per = clk_get(&pdev->dev, "per");
> + if (IS_ERR(pcdev->clk_csi_per)) {
> + dev_err(&pdev->dev, "Could not get csi per clock\n");
> + err = PTR_ERR(pcdev->clk_csi_per);
> + goto exit_kfree;
> + }
> +
> +
> pcdev->res_csi = res_csi;
> pcdev->pdata = pdev->dev.platform_data;
> if (pcdev->pdata) {
> @@ -1750,12 +1764,12 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
>
> pcdev->platform_flags = pcdev->pdata->flags;
>
> - rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
> + rate = clk_round_rate(pcdev->clk_csi_per, pcdev->pdata->clk * 2);
> if (rate <= 0) {
> err = -ENODEV;
> goto exit_dma_free;
> }
> - err = clk_set_rate(pcdev->clk_csi, rate);
> + err = clk_set_rate(pcdev->clk_csi_per, rate);
> if (err < 0)
> goto exit_dma_free;
> }
> @@ -1827,7 +1841,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
> goto exit_free_emma;
>
> dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
> - clk_get_rate(pcdev->clk_csi));
> + clk_get_rate(pcdev->clk_csi_per));
>
> return 0;
>
> @@ -1851,7 +1865,8 @@ exit_iounmap:
> exit_release:
> release_mem_region(res_csi->start, resource_size(res_csi));
> exit_dma_free:
> - clk_put(pcdev->clk_csi);
> + clk_put(pcdev->clk_csi_per);
> + clk_put(pcdev->clk_csi_ahb);
> exit_kfree:
> kfree(pcdev);
> exit:
> @@ -1865,7 +1880,8 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
> struct mx2_camera_dev, soc_host);
> struct resource *res;
>
> - clk_put(pcdev->clk_csi);
> + clk_put(pcdev->clk_csi_per);
> + clk_put(pcdev->clk_csi_ahb);
> if (cpu_is_mx25())
> free_irq(pcdev->irq_csi, pcdev);
> if (cpu_is_mx27())
> --
> 1.7.9.5
>
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* [PATCH] ARM: picoxcell: remove unnecessary header common.h
From: Jamie Iles @ 2012-10-08 9:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349432246-21795-1-git-send-email-tklauser@distanz.ch>
Looks good, thanks Tobias!
On Fri, Oct 05, 2012 at 12:17:26PM +0200, Tobias Klauser wrote:
> Since commit 66314223 ("ARM: socfpga: initial support for Altera's
> SOCFPGA platform") struct sys_timer dw_apb_timer is an extern in
> <linux/dw_apb_timer.h>, so there is no need for common.h anymore,
> instead directly #include <asm/mach/time.h> in common.c
>
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Acked-by: Jamie Iles <jamie@jamieiles.com>
^ permalink raw reply
* [PATCH 3/3] i2c: omap: Remove Address as slave wakeup
From: Shubhrajyoti D @ 2012-10-08 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349687116-14463-1-git-send-email-shubhrajyoti@ti.com>
Currently the slave support is not there in the current i2c.
Lets remove the Address as slave wakeup from the Wakeup enable
register.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index db0b272..c7b0a2c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -128,6 +128,11 @@ enum {
OMAP_I2C_WE_DRDY_WE | OMAP_I2C_WE_ARDY_WE | \
OMAP_I2C_WE_NACK_WE | OMAP_I2C_WE_AL_WE)
+#define OMAP_I2C_WE_ENABLED (OMAP_I2C_WE_XDR_WE | OMAP_I2C_WE_RDR_WE | \
+ OMAP_I2C_WE_BF_WE | \
+ OMAP_I2C_WE_STC_WE | OMAP_I2C_WE_GC_WE | \
+ OMAP_I2C_WE_DRDY_WE | OMAP_I2C_WE_ARDY_WE | \
+ OMAP_I2C_WE_NACK_WE | OMAP_I2C_WE_AL_WE)
/* I2C Buffer Configuration Register (OMAP_I2C_BUF): */
#define OMAP_I2C_BUF_RDMA_EN (1 << 15) /* RX DMA channel enable */
#define OMAP_I2C_BUF_RXFIF_CLR (1 << 14) /* RX FIFO Clear */
@@ -326,7 +331,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* WFI instruction.
* REVISIT: Some wkup sources might not be needed.
*/
- dev->westate = OMAP_I2C_WE_ALL;
+ dev->westate = OMAP_I2C_WE_ENABLED;
omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
dev->westate);
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/3] i2c: omap: Remove the redundant fifo clear
From: Shubhrajyoti D @ 2012-10-08 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349687116-14463-1-git-send-email-shubhrajyoti@ti.com>
The omap_i2c_resize_fifo already takes care of the fifo clearing so,
remove the (re)clearing of the fifo.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ce41596..db0b272 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -524,11 +524,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
- /* Clear the FIFO Buffers */
- w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
- w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
-
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 1/3] i2c: omap: Do not enable the irq always
From: Shubhrajyoti D @ 2012-10-08 9:05 UTC (permalink / raw)
To: linux-arm-kernel
Enable the irq in the transfer and disable it after the
transfer is done.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b6c6b95..ce41596 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -625,6 +625,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (IS_ERR_VALUE(r))
goto out;
+ enable_irq(dev->irq);
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
goto out;
@@ -654,6 +655,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
omap_i2c_wait_for_bb(dev);
out:
+ disable_irq(dev->irq);
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
return r;
@@ -1179,6 +1181,7 @@ omap_i2c_probe(struct platform_device *pdev)
goto err_unuse_clocks;
}
+ disable_irq(dev->irq);
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
--
1.7.5.4
^ permalink raw reply related
* [PATCH] ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints
From: Jean Pihet @ 2012-10-08 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121006114614.GB10164@pengutronix.de>
On Sat, Oct 6, 2012 at 1:46 PM, Wolfram Sang <w.sang@pengutronix.de> wrote:
> On Thu, Sep 20, 2012 at 06:08:03PM +0200, Jean Pihet wrote:
>> Convert the driver from the outdated omap_pm_set_max_mpu_wakeup_lat
>> API to the new PM QoS API.
>> Since the constraint is on the MPU subsystem, use the PM_QOS_CPU_DMA_LATENCY
>> class of PM QoS. The resulting MPU constraints are used by cpuidle to
>> decide the next power state of the MPU subsystem.
>>
>> The I2C device latency timing is derived from the FIFO size and the
>> clock speed and so is applicable to all OMAP SoCs.
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> Applied to -next, thanks!
Thanks!
Jean
>
> --
> Pengutronix e.K. | Wolfram Sang |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 00/16] More omap plat header cleanup for v3.8 merge window
From: Santosh Shilimkar @ 2012-10-08 8:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121004213950.26676.21898.stgit@muffinssi.local>
Tony,
On Friday 05 October 2012 03:34 AM, Tony Lindgren wrote:
> Hi all,
>
> Here are some more patches for early merging after -rc1 for v3.8
> merge window to remove more plat includes for the ARM common
> zImage support. These are based on top of current linux next +
> kevin's cpufreq fixes.
>
Have scanned the series and movement looks fine. For the SRAM movement,
I just wanted to to check if the builds are fine with errata WA enabled
for OMAP4. Do you have a branch where you are stacking up these patches?
Regards
santosh
^ permalink raw reply
* [PATCH 1/1] ARM: OMAP: Add maintainer entry for IGEP machines
From: Javier Martinez Canillas @ 2012-10-08 8:47 UTC (permalink / raw)
To: linux-arm-kernel
Enric and I have been mantained this machine and while we
are moving to device trees, it is good that people cc us
when reporting bugs or regression on the board file until
we have proper DT support.
Signed-off-by: Javier Martinez Canillas <javier@dowhile0.org>
---
MAINTAINERS | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 63ce2a2..6b3c58d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -818,6 +818,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
F: arch/arm/mach-sa1100/jornada720.c
F: arch/arm/mach-sa1100/include/mach/jornada720.h
+ARM/IGEP MACHINE SUPPORT
+M: Enric Balletbo i Serra <eballetbo@gmail.com>
+M: Javier Martinez Canillas <javier@dowhile0.org>
+L: linux-omap at vger.kernel.org
+L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-omap2/board-igep0020.c
+
ARM/INCOME PXA270 SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
--
1.7.7.6
^ permalink raw reply related
* [PATCH 16/16] Documentation: Update samsung-pinctrl device tree bindings documentation
From: Tomasz Figa @ 2012-10-08 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349685556-23718-1-git-send-email-t.figa@samsung.com>
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
.../bindings/pinctrl/samsung-pinctrl.txt | 212 ++++++++++++++++++---
1 file changed, 187 insertions(+), 25 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 03dee50..6ebc946 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -13,8 +13,35 @@ Required Properties:
- reg: Base address of the pin controller hardware module and length of
the address space it occupies.
-- interrupts: interrupt specifier for the controller. The format and value of
- the interrupt specifier depends on the interrupt parent for the controller.
+- Pin bank types: Pin bank nodes reference pin bank types by their phandles to
+ determine low level bank parameters such as bit field availability and widths.
+ There is no restriction for placement of such nodes. A bank type node must
+ contain following properties:
+
+ - samsung,reg-names: names of registers specified in samsung,reg-params
+ property. Allowed register names are:
+ - "func" - function configuration register (GPxCON)
+ - "dat" - input/output value register (GPxDAT)
+ - "pud" - pull-up/-down control register (GPxPUD)
+ - "drv" - driver strength control register (GPxDRV)
+ - "conpdn" - power-down state control register (GPxCONPDN)
+ - "pudpdn" - power-down pull-up/-down control register (GPxPUDPDN)
+ - samsung,reg-params: register specifiers for registers named by
+ samsung,reg-names property. Each specifier contains two cells:
+ - first cell: offset in bytes from first register of the bank
+ - second cell: bits in register used for single pin.
+
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+ nodes of the controller node. Bank name is taken from name of the node. Each
+ bank node must contain following properties:
+
+ - gpio-controller: identifies the node as a gpio controller and pin bank.
+ - samsung,pctrl-offset: offset to pin control registers of the bank.
+ - samsung,pin-count: number of pins in the bank.
+ - samsung,bank-type: phandle to a node defining bank type.
+ - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+ binding is used, the amount of cells must be specified as 2. See generic
+ GPIO binding documentation for description of particular cells.
- Pin mux/config groups as child nodes: The pin mux (selecting pin function
mode) and pin config (pull up/down, driver strength) settings are represented
@@ -72,16 +99,30 @@ used as system wakeup events.
A. External GPIO Interrupts: For supporting external gpio interrupts, the
following properties should be specified in the pin-controller device node.
-- interrupt-controller: identifies the controller node as interrupt-parent.
-- #interrupt-cells: the value of this property should be 2.
- - First Cell: represents the external gpio interrupt number local to the
- external gpio interrupt space of the controller.
- - Second Cell: flags to identify the type of the interrupt
- - 1 = rising edge triggered
- - 2 = falling edge triggered
- - 3 = rising and falling edge triggered
- - 4 = high level triggered
- - 8 = low level triggered
+ - samsung,geint-con: offset of first EXT_INTxx_CON register.
+ - samsung,geint-mask: offset of first EXT_INTxx_MASK register.
+ - samsung,geint-pend: offset of first EXT_INTxx_PEND register.
+ - samsung,svc: offset of EXT_INT_SERVICE register.
+ - interrupt-parent: phandle of the interrupt parent to which the external
+ GPIO interrupts are forwarded to.
+ - interrupts: interrupt specifier for the controller. The format and value of
+ the interrupt specifier depends on the interrupt parent for the controller.
+
+ In addition, following properties must be present in node of every bank
+ of pins supporting GPIO interrupts:
+
+ - interrupt-controller: identifies the controller node as interrupt-parent.
+ - samsung,eint-offset: offset of register related to this bank from first
+ CON/MASK/PEND register.
+ - #interrupt-cells: the value of this property should be 2.
+ - First Cell: represents the external gpio interrupt number local to the
+ external gpio interrupt space of the controller.
+ - Second Cell: flags to identify the type of the interrupt
+ - 1 = rising edge triggered
+ - 2 = falling edge triggered
+ - 3 = rising and falling edge triggered
+ - 4 = high level triggered
+ - 8 = low level triggered
B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
child node representing the external wakeup interrupt controller should be
@@ -94,7 +135,18 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
found on Samsung Exynos4210 SoC.
- interrupt-parent: phandle of the interrupt parent to which the external
wakeup interrupts are forwarded to.
+ - interrupts: interrupt used by multiplexed wakeup interrupts.
+ - samsung,weint-con: offset of first wake-up EXT_INTxx_CON register.
+ - samsung,weint-mask: offset of first wake-up EXT_INTxx_MASK register.
+ - samsung,weint-pend: offset of first wake-up EXT_INTxx_PEND register.
+
+ In addition, following properties must be present in node of every bank
+ of pins supporting wake-up interrupts:
+
- interrupt-controller: identifies the node as interrupt-parent.
+ - samsung,wkup-eint: marks the bank as supporting wake-up interrupts.
+ - samsung,eint-offset: offset of register related to this bank from first
+ wake-up CON/MASK/PEND register.
- #interrupt-cells: the value of this property should be 2
- First Cell: represents the external wakeup interrupt number local to
the external wakeup interrupt space of the controller.
@@ -105,17 +157,125 @@ B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
- 4 = high level triggered
- 8 = low level triggered
+ Node of every bank of pins supporting direct wake-up interrupts (without
+ multiplexing) must contain following properties:
+
+ - interrupt-parent: phandle of the interrupt parent to which the external
+ wakeup interrupts are forwarded to.
+ - interrupts: interrupts of the interrupt parent which are used for external
+ wakeup interrupts from pins of the bank, must contain interrupts for all
+ pins of the bank.
+
Aliases:
All the pin controller nodes should be represented in the aliases node using
the following format 'pinctrl{n}' where n is a unique number for the alias.
+Example: Nodes for pin bank types:
+
+ pinctrl-bank-types {
+ bank_off: bank-off {
+ samsung,reg-names = "func", "dat", "pud",
+ "drv", "conpdn", "pudpdn";
+ samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+ <0x0C 2>, <0x10 2>, <0x14 2>;
+ };
+
+ bank_alive: bank-alive {
+ samsung,reg-names = "func", "dat", "pud",
+ "drv";
+ samsung,reg-params = <0x00 4>, <0x04 1>, <0x08 2>,
+ <0x0C 2>;
+ };
+ };
+
+Example: A pin-controller node with pin banks:
+
+ pinctrl_0: pinctrl at 11400000 {
+ compatible = "samsung,pinctrl-exynos4210";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 47 0>;
+ samsung,geint-con = <0x700>;
+ samsung,geint-mask = <0x900>;
+ samsung,geint-pend = <0xA00>;
+ samsung,svc = <0xB08>;
+
+ /* ... */
+
+ /* Pin bank without external interrupts */
+ gpy0: gpy0 {
+ gpio-controller;
+ samsung,pctl-offset = <0x120>;
+ samsung,pin-count = <6>;
+ samsung,bank-type = <&bank_off>;
+ #gpio-cells = <2>;
+ };
+
+ /* ... */
+
+ /* Pin bank with external GPIO interrupts */
+ gpj0: gpj0 {
+ gpio-controller;
+ samsung,pctl-offset = <0x000>;
+ samsung,pin-count = <8>;
+ samsung,bank-type = <&bank_off>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ samsung,eint-offset = <0x00>;
+ #interrupt-cells = <2>;
+ };
+
+ /* ... */
+
+ /* Pin bank with external direct wake-up interrupts */
+ gpx0: gpx0 {
+ gpio-controller;
+ samsung,pctl-offset = <0xC00>;
+ samsung,pin-count = <8>;
+ samsung,bank-type = <&bank_alive>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ samsung,wkup-eint;
+ interrupt-parent = <&gic>;
+ interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ samsung,eint-offset = <0x00>;
+ #interrupt-cells = <2>;
+ };
+
+ /* ... */
+
+ /* Pin bank with external multiplexed wake-up interrupts */
+ gpx2: gpx2 {
+ gpio-controller;
+ samsung,pctl-offset = <0xC40>;
+ samsung,pin-count = <8>;
+ samsung,bank-type = <&bank_alive>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ samsung,wkup-eint;
+ samsung,eint-offset = <0x08>;
+ #interrupt-cells = <2>;
+ };
+
+ /* ... */
+ };
+
Example 1: A pin-controller node with pin groups.
pinctrl_0: pinctrl at 11400000 {
compatible = "samsung,pinctrl-exynos4210";
reg = <0x11400000 0x1000>;
interrupts = <0 47 0>;
+ samsung,geint-con = <0x700>;
+ samsung,geint-mask = <0x900>;
+ samsung,geint-pend = <0xA00>;
+ samsung,svc = <0xB08>;
+
+ /* ... */
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
@@ -158,20 +318,21 @@ Example 2: A pin-controller node with external wakeup interrupt controller node.
pinctrl_1: pinctrl at 11000000 {
compatible = "samsung,pinctrl-exynos4210";
reg = <0x11000000 0x1000>;
- interrupts = <0 46 0>;
- interrupt-controller;
- #interrupt-cells = <2>;
+ interrupts = <0 46 0>
+ samsung,geint-con = <0x700>;
+ samsung,geint-mask = <0x900>;
+ samsung,geint-pend = <0xA00>;
+ samsung,svc = <0xB08>;
- wakup_eint: wakeup-interrupt-controller {
+ /* ... */
+
+ wakeup-interrupt-controller {
compatible = "samsung,exynos4210-wakeup-eint";
interrupt-parent = <&gic>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
- <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
- <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
- <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>,
- <0 32 0>;
+ interrupts = <0 32 0>;
+ samsung,weint-con = <0xE00>;
+ samsung,weint-mask = <0xF00>;
+ samsung,weint-pend = <0xF40>;
};
};
@@ -190,7 +351,8 @@ Example 4: Set up the default pin state for uart controller.
static int s3c24xx_serial_probe(struct platform_device *pdev) {
struct pinctrl *pinctrl;
- ...
- ...
+
+ /* ... */
+
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
}
--
1.7.12
^ permalink raw reply related
* [PATCH 15/16] pinctrl: samsung: Add GPIO to IRQ translation
From: Tomasz Figa @ 2012-10-08 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349685556-23718-1-git-send-email-t.figa@samsung.com>
Some drivers require a way to translate GPIO pins to their IRQ numbers.
This patch adds the .to_irq() gpiolib callback to pinctrl-samsung
driver, which creates (if not present yet) and returns an IRQ mapping
for given GPIO pin.
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
drivers/pinctrl/pinctrl-samsung.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 495b226..8172c1e 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/irqdomain.h>
#include "core.h"
#include "pinctrl-samsung.h"
@@ -528,6 +529,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
}
/*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+ struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
+ unsigned int virq;
+
+ if (!bank->irq_domain)
+ return -ENXIO;
+
+ virq = irq_create_mapping(bank->irq_domain, offset);
+
+ return (virq) ? : -ENXIO;
+}
+
+/*
* Parse the pin names listed in the 'samsung,pins' property and convert it
* into a list of gpio numbers are create a pin group from it.
*/
@@ -757,6 +775,7 @@ static const struct gpio_chip samsung_gpiolib_chip = {
.get = samsung_gpio_get,
.direction_input = samsung_gpio_direction_input,
.direction_output = samsung_gpio_direction_output,
+ .to_irq = samsung_gpio_to_irq,
.owner = THIS_MODULE,
};
--
1.7.12
^ permalink raw reply related
* [PATCH 14/16] pinctrl: samsung: Parse offsets of particular registers from DT
From: Tomasz Figa @ 2012-10-08 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349685556-23718-1-git-send-email-t.figa@samsung.com>
The order and availability of pin control registers vary with SoC.
This patch modifies the driver to parse register offsets from device
tree as a part of bank type definition.
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
drivers/pinctrl/pinctrl-exynos.c | 12 ++---
drivers/pinctrl/pinctrl-samsung.c | 93 +++++++++++++++++++++------------------
drivers/pinctrl/pinctrl-samsung.h | 38 +++++++++-------
3 files changed, 78 insertions(+), 65 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 8cc8018..f264d69 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -113,9 +113,9 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
con |= trig_type << shift;
writel(con, d->virt_base + reg_con);
- reg_con = bank->pctl_offset;
- shift = pin * bank->func_width;
- mask = (1 << bank->func_width) - 1;
+ reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+ shift = pin * bank->regs[REG_FUNC].width;
+ mask = (1 << bank->regs[REG_FUNC].width) - 1;
con = readl(d->virt_base + reg_con);
con &= ~(mask << shift);
@@ -290,9 +290,9 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
con |= trig_type << shift;
writel(con, d->virt_base + reg_con);
- reg_con = bank->pctl_offset;
- shift = pin * bank->func_width;
- mask = (1 << bank->func_width) - 1;
+ reg_con = bank->pctl_offset + bank->regs[REG_FUNC].offset;
+ shift = pin * bank->regs[REG_FUNC].width;
+ mask = (1 << bank->regs[REG_FUNC].width) - 1;
con = readl(d->virt_base + reg_con);
con &= ~(mask << shift);
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 215a7e5..495b226 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -273,10 +273,6 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,
*offset = pin - b->pin_base;
if (bank)
*bank = b;
-
- /* some banks have two config registers in a single bank */
- if (*offset * b->func_width > BITS_PER_LONG)
- *reg += 4;
}
/* enable or disable a pinmux function */
@@ -299,8 +295,9 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
®, &pin_offset, &bank);
- mask = (1 << bank->func_width) - 1;
- shift = pin_offset * bank->func_width;
+ mask = (1 << bank->regs[REG_FUNC].width) - 1;
+ shift = pin_offset * bank->regs[REG_FUNC].width;
+ reg += bank->regs[REG_FUNC].offset;
data = readl(reg);
data &= ~(mask << shift);
@@ -342,10 +339,11 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drvdata = pinctrl_dev_get_drvdata(pctldev);
pin_offset = offset - bank->pin_base;
- reg = drvdata->virt_base + bank->pctl_offset;
+ reg = drvdata->virt_base + bank->pctl_offset
+ + bank->regs[REG_FUNC].offset;
- mask = (1 << bank->func_width) - 1;
- shift = pin_offset * bank->func_width;
+ mask = (1 << bank->regs[REG_FUNC].width) - 1;
+ shift = pin_offset * bank->regs[REG_FUNC].width;
data = readl(reg);
data &= ~(mask << shift);
@@ -382,20 +380,20 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
switch (cfg_type) {
case PINCFG_TYPE_PUD:
- width = bank->pud_width;
- cfg_reg = PUD_REG;
+ width = bank->regs[REG_PUD].width;
+ cfg_reg = bank->regs[REG_PUD].offset;
break;
case PINCFG_TYPE_DRV:
- width = bank->drv_width;
- cfg_reg = DRV_REG;
+ width = bank->regs[REG_DRV].width;
+ cfg_reg = bank->regs[REG_DRV].offset;
break;
case PINCFG_TYPE_CON_PDN:
- width = bank->conpdn_width;
- cfg_reg = CONPDN_REG;
+ width = bank->regs[REG_CONPDN].width;
+ cfg_reg = bank->regs[REG_CONPDN].offset;
break;
case PINCFG_TYPE_PUD_PDN:
- width = bank->pudpdn_width;
- cfg_reg = PUDPDN_REG;
+ width = bank->regs[REG_PUDPDN].width;
+ cfg_reg = bank->regs[REG_PUDPDN].offset;
break;
default:
WARN_ON(1);
@@ -481,13 +479,14 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
void __iomem *reg;
u32 data;
- reg = bank->drvdata->virt_base + bank->pctl_offset;
+ reg = bank->drvdata->virt_base + bank->pctl_offset
+ + bank->regs[REG_DAT].offset;
- data = readl(reg + DAT_REG);
+ data = readl(reg);
data &= ~(1 << offset);
if (value)
data |= 1 << offset;
- writel(data, reg + DAT_REG);
+ writel(data, reg);
}
/* gpiolib gpio_get callback function */
@@ -497,9 +496,10 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
u32 data;
struct samsung_pin_bank *bank = gc_to_pin_bank(gc);
- reg = bank->drvdata->virt_base + bank->pctl_offset;
+ reg = bank->drvdata->virt_base + bank->pctl_offset
+ + bank->regs[REG_DAT].offset;
- data = readl(reg + DAT_REG);
+ data = readl(reg);
data >>= offset;
data &= 1;
return data;
@@ -818,12 +818,24 @@ static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
static const struct of_device_id samsung_pinctrl_dt_match[];
+
+
static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
struct device_node *np)
{
+ static const char *reg_names[REG_NUM] = {
+ [REG_FUNC] = "func",
+ [REG_DAT] = "dat",
+ [REG_PUD] = "pud",
+ [REG_DRV] = "drv",
+ [REG_CONPDN] = "conpdn",
+ [REG_PUDPDN] = "pudpdn",
+ };
struct samsung_pin_bank *type = np->data;
- int ret;
- u32 val;
+ const __be32 *data;
+ int len = 0;
+ int index;
+ int i;
if (type) {
*bank = *type;
@@ -834,26 +846,21 @@ static int samsung_pinctrl_parse_dt_bank_type(struct samsung_pin_bank *bank,
if (!type)
return -ENOMEM;
- ret = of_property_read_u32(np, "samsung,func-width", &val);
- if (ret)
- return ret;
- type->func_width = val;
-
- ret = of_property_read_u32(np, "samsung,pud-width", &val);
- if (!ret)
- type->pud_width = val;
-
- ret = of_property_read_u32(np, "samsung,drv-width", &val);
- if (!ret)
- type->drv_width = val;
-
- ret = of_property_read_u32(np, "samsung,conpdn-width", &val);
- if (!ret)
- type->conpdn_width = val;
+ data = of_get_property(np, "samsung,reg-params", &len);
+ if (!data)
+ return -EINVAL;
+ len /= sizeof(*data);
- ret = of_property_read_u32(np, "samsung,pudpdn-width", &val);
- if (!ret)
- type->pudpdn_width = val;
+ for (i = 0; i < ARRAY_SIZE(reg_names); ++i) {
+ index = of_property_match_string(np, "samsung,reg-names",
+ reg_names[i]);
+ if (index < 0)
+ continue;
+ if (index >= len / 2)
+ return -EINVAL;
+ type->regs[i].offset = be32_to_cpu(data[2 * index]);
+ type->regs[i].width = be32_to_cpu(data[2 * index + 1]);
+ }
*bank = *type;
np->data = type;
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index 355f4e2..684f042 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -25,12 +25,16 @@
#include <linux/gpio.h>
-/* register offsets within a pin bank */
-#define DAT_REG 0x4
-#define PUD_REG 0x8
-#define DRV_REG 0xC
-#define CONPDN_REG 0x10
-#define PUDPDN_REG 0x14
+enum pincfg_reg {
+ REG_FUNC = 0,
+ REG_DAT,
+ REG_PUD,
+ REG_DRV,
+ REG_CONPDN,
+ REG_PUDPDN,
+
+ REG_NUM
+};
/* pinmux function number for pin as gpio output line */
#define FUNC_OUTPUT 0x1
@@ -103,15 +107,21 @@ enum eint_type {
struct samsung_pinctrl_drv_data;
/**
+ * struct samsung_pin_reg: defines a configuration register.
+ * @offset: offset from bank base.
+ * @width: with of a bit field used for single pin.
+ */
+struct samsung_pin_reg {
+ u8 offset;
+ u8 width;
+};
+
+/**
* struct samsung_pin_bank: represent a controller pin-bank.
* @reg_offset: starting offset of the pin-bank registers.
* @pin_base: starting pin number of the bank.
* @nr_pins: number of pins included in this bank.
- * @func_width: width of the function selector bit field.
- * @pud_width: width of the pin pull up/down selector bit field.
- * @drv_width: width of the pin driver strength selector bit field.
- * @conpdn_width: width of the sleep mode function selector bin field.
- * @pudpdn_width: width of the sleep mode pull up/down selector bit field.
+ * @regs: low level parameters of available configuration registers.
* @eint_type: type of the external interrupt supported by the bank.
* @name: name to be prefixed for each pin in this pin bank.
* @of_node: node of pin bank in device tree
@@ -124,11 +134,7 @@ struct samsung_pin_bank {
u32 pctl_offset;
u32 pin_base;
u8 nr_pins;
- u8 func_width;
- u8 pud_width;
- u8 drv_width;
- u8 conpdn_width;
- u8 pudpdn_width;
+ struct samsung_pin_reg regs[REG_NUM];
enum eint_type eint_type;
u32 eint_offset;
const char *name;
--
1.7.12
^ permalink raw reply related
* [PATCH 13/16] pinctrl: exynos: Set pin function to EINT in irq_set_type of wake-up EINT
From: Tomasz Figa @ 2012-10-08 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349685556-23718-1-git-send-email-t.figa@samsung.com>
Pins used as wake-up interrupts need to be configured as EINTs. This
patch adds the required configuration code to exynos_wkup_irq_set_type,
to set the pin as EINT when its interrupt trigger type is configured.
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
drivers/pinctrl/pinctrl-exynos.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index fa6a5be..8cc8018 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -257,6 +257,7 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
unsigned long con, trig_type;
+ unsigned int mask;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -288,6 +289,16 @@ static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
con &= ~(EXYNOS_EINT_CON_MASK << shift);
con |= trig_type << shift;
writel(con, d->virt_base + reg_con);
+
+ reg_con = bank->pctl_offset;
+ shift = pin * bank->func_width;
+ mask = (1 << bank->func_width) - 1;
+
+ con = readl(d->virt_base + reg_con);
+ con &= ~(mask << shift);
+ con |= EXYNOS_EINT_FUNC << shift;
+ writel(con, d->virt_base + reg_con);
+
return 0;
}
--
1.7.12
^ permalink raw reply related
* [PATCH 12/16] pinctrl: samsung: Use per-bank IRQ domain for wake-up interrupts
From: Tomasz Figa @ 2012-10-08 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1349685556-23718-1-git-send-email-t.figa@samsung.com>
This patch reworks wake-up interrupt handling in pinctrl-exynos driver,
so each pin bank, which provides wake-up interrupts, has its own IRQ
domain.
Information about whether given pin bank provides wake-up interrupts,
how many and whether they are separate or muxed are parsed from device
tree.
It gives following advantages:
- interrupts can be specified in device tree in a more readable way,
e.g. :
device {
/* ... */
interrupt-parent = <&gpx2>;
interrupts = <4 0>;
/* ... */
};
- the amount and layout of interrupts is not hardcoded in the driver
anymore
- bank and pin of each wake-up interrupt can be easily identified, to
allow operations, such as setting the pin to EINT function, from
irq_set_type() callback
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
drivers/pinctrl/pinctrl-exynos.c | 159 +++++++++++++++++++++++---------------
drivers/pinctrl/pinctrl-exynos.h | 17 +++-
drivers/pinctrl/pinctrl-samsung.c | 9 ++-
drivers/pinctrl/pinctrl-samsung.h | 6 +-
4 files changed, 119 insertions(+), 72 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
index 53ed5d9..fa6a5be 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -218,46 +218,43 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
static void exynos_wkup_irq_unmask(struct irq_data *irqd)
{
- struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
- unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
- unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
- unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+ struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = b->drvdata;
+ unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
unsigned long mask;
mask = readl(d->virt_base + reg_mask);
- mask &= ~(1 << pin);
+ mask &= ~(1 << irqd->hwirq);
writel(mask, d->virt_base + reg_mask);
}
static void exynos_wkup_irq_mask(struct irq_data *irqd)
{
- struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
- unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
- unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
- unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
+ struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = b->drvdata;
+ unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
unsigned long mask;
mask = readl(d->virt_base + reg_mask);
- mask |= 1 << pin;
+ mask |= 1 << irqd->hwirq;
writel(mask, d->virt_base + reg_mask);
}
static void exynos_wkup_irq_ack(struct irq_data *irqd)
{
- struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
- unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
- unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
- unsigned long pend = d->ctrl->weint_pend + (bank << 2);
+ struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = b->drvdata;
+ unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
- writel(1 << pin, d->virt_base + pend);
+ writel(1 << irqd->hwirq, d->virt_base + pend);
}
static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
{
- struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
- unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
- unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
- unsigned long reg_con = d->ctrl->weint_con + (bank << 2);
+ struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
+ struct samsung_pinctrl_drv_data *d = bank->drvdata;
+ unsigned int pin = irqd->hwirq;
+ unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
unsigned long con, trig_type;
@@ -309,6 +306,7 @@ static struct irq_chip exynos_wkup_irq_chip = {
static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
struct exynos_weint_data *eintd = irq_get_handler_data(irq);
+ struct samsung_pin_bank *bank = eintd->bank;
struct irq_chip *chip = irq_get_chip(irq);
int eint_irq;
@@ -318,20 +316,20 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
if (chip->irq_ack)
chip->irq_ack(&desc->irq_data);
- eint_irq = irq_linear_revmap(eintd->domain, eintd->irq);
+ eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
generic_handle_irq(eint_irq);
chip->irq_unmask(&desc->irq_data);
chained_irq_exit(chip, desc);
}
-static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
- struct irq_domain *domain)
+static inline void exynos_irq_demux_eint(unsigned long pend,
+ struct irq_domain *domain)
{
unsigned int irq;
while (pend) {
irq = fls(pend) - 1;
- generic_handle_irq(irq_find_mapping(domain, irq_base + irq));
+ generic_handle_irq(irq_find_mapping(domain, irq));
pend &= ~(1 << irq);
}
}
@@ -340,18 +338,22 @@ static inline void exynos_irq_demux_eint(int irq_base, unsigned long pend,
static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
- struct exynos_weint_data *eintd = irq_get_handler_data(irq);
- struct samsung_pinctrl_drv_data *d = eintd->domain->host_data;
+ struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
+ struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
+ struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned long pend;
unsigned long mask;
+ int i;
chained_irq_enter(chip, desc);
- pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8);
- mask = readl(d->virt_base + d->ctrl->weint_mask + 0x8);
- exynos_irq_demux_eint(16, pend & ~mask, eintd->domain);
- pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC);
- mask = readl(d->virt_base + d->ctrl->weint_mask + 0xC);
- exynos_irq_demux_eint(24, pend & ~mask, eintd->domain);
+
+ for (i = 0; i < eintd->nr_banks; ++i) {
+ struct samsung_pin_bank *b = eintd->banks[i];
+ pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
+ mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+ exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+ }
+
chained_irq_exit(chip, desc);
}
@@ -381,7 +383,11 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
struct device *dev = d->dev;
struct device_node *wkup_np = NULL;
struct device_node *np;
+ struct samsung_pin_bank *bank;
struct exynos_weint_data *weint_data;
+ struct exynos_muxed_weint_data *muxed_data;
+ unsigned int muxed_banks = 0;
+ unsigned int i;
int idx, irq;
u32 val;
int ret;
@@ -395,11 +401,6 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
if (!wkup_np)
return -ENODEV;
- ret = of_property_read_u32(wkup_np, "samsung,weint-count", &val);
- if (ret)
- return -EINVAL;
- d->ctrl->nr_wint = val;
-
ret = of_property_read_u32(wkup_np, "samsung,weint-con", &val);
if (ret)
return -EINVAL;
@@ -415,40 +416,74 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return -EINVAL;
d->ctrl->weint_pend = val;
- d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
- &exynos_wkup_irqd_ops, d);
- if (!d->wkup_irqd) {
- dev_err(dev, "wakeup irq domain allocation failed\n");
- return -ENXIO;
- }
+ bank = d->ctrl->pin_banks;
+ for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+ if (bank->eint_type != EINT_TYPE_WKUP)
+ continue;
- weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL);
- if (!weint_data) {
- dev_err(dev, "could not allocate memory for weint_data\n");
- return -ENOMEM;
- }
+ bank->irq_domain = irq_domain_add_linear(bank->of_node,
+ bank->nr_pins, &exynos_wkup_irqd_ops, bank);
+ if (!bank->irq_domain) {
+ dev_err(dev, "wkup irq domain add failed\n");
+ return -ENXIO;
+ }
- irq = irq_of_parse_and_map(wkup_np, 16);
- if (irq) {
- weint_data[16].domain = d->wkup_irqd;
- irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
- irq_set_handler_data(irq, &weint_data[16]);
- } else {
- dev_err(dev, "irq number for EINT16-32 not found\n");
- }
+ if (!of_find_property(bank->of_node, "interrupts", NULL)) {
+ bank->eint_type = EINT_TYPE_WKUP_MUX;
+ ++muxed_banks;
+ continue;
+ }
- for (idx = 0; idx < 16; idx++) {
- weint_data[idx].domain = d->wkup_irqd;
- weint_data[idx].irq = idx;
+ weint_data = devm_kzalloc(dev, bank->nr_pins
+ * sizeof(*weint_data), GFP_KERNEL);
+ if (!weint_data) {
+ dev_err(dev, "could not allocate memory for weint_data\n");
+ return -ENOMEM;
+ }
- irq = irq_of_parse_and_map(wkup_np, idx);
- if (irq) {
+ for (idx = 0; idx < bank->nr_pins; ++idx) {
+ irq = irq_of_parse_and_map(bank->of_node, idx);
+ if (!irq) {
+ dev_err(dev, "irq number for eint-%s-%d not found\n",
+ bank->name, idx);
+ continue;
+ }
+ weint_data[idx].irq = idx;
+ weint_data[idx].bank = bank;
irq_set_handler_data(irq, &weint_data[idx]);
irq_set_chained_handler(irq, exynos_irq_eint0_15);
- } else {
- dev_err(dev, "irq number for eint-%x not found\n", idx);
}
}
+
+ if (!muxed_banks)
+ return 0;
+
+ irq = irq_of_parse_and_map(wkup_np, 0);
+ if (!irq) {
+ dev_err(dev, "irq number for muxed EINTs not found\n");
+ return 0;
+ }
+
+ muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
+ + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
+ if (!muxed_data) {
+ dev_err(dev, "could not allocate memory for muxed_data\n");
+ return -ENOMEM;
+ }
+
+ irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
+ irq_set_handler_data(irq, muxed_data);
+
+ bank = d->ctrl->pin_banks;
+ idx = 0;
+ for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+ if (bank->eint_type != EINT_TYPE_WKUP_MUX)
+ continue;
+
+ muxed_data->banks[idx++] = bank;
+ }
+ muxed_data->nr_banks = muxed_banks;
+
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/pinctrl-exynos.h
index 30aca2b..a94d6fc 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/pinctrl-exynos.h
@@ -40,10 +40,21 @@
/**
* struct exynos_weint_data: irq specific data for all the wakeup interrupts
* generated by the external wakeup interrupt controller.
- * @domain: irq domain representing the external wakeup interrupts
* @irq: interrupt number within the domain.
+ * @bank: bank responsible for this interrupt
*/
struct exynos_weint_data {
- struct irq_domain *domain;
- u32 irq;
+ unsigned int irq;
+ struct samsung_pin_bank *bank;
+};
+
+/**
+ * struct exynos_muxed_weint_data: irq specific data for muxed wakeup interrupts
+ * generated by the external wakeup interrupt controller.
+ * @nr_banks: count of banks being part of the mux
+ * @banks: array of banks being part of the mux
+ */
+struct exynos_muxed_weint_data {
+ unsigned int nr_banks;
+ struct samsung_pin_bank *banks[];
};
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
index 4ffd14c..215a7e5 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -615,10 +615,10 @@ static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
*/
for_each_child_of_node(dev_np, cfg_np) {
u32 function;
- if (of_find_property(cfg_np, "interrupt-controller", NULL))
- continue;
if (of_find_property(cfg_np, "gpio-controller", NULL))
continue;
+ if (of_find_property(cfg_np, "compatible", NULL))
+ continue;
ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
&drvdata->pctl, &pin_list, &npins);
@@ -894,7 +894,10 @@ static int samsung_pinctrl_parse_dt_bank(struct samsung_pin_bank *bank,
return 0;
}
- bank->eint_type = EINT_TYPE_GPIO;
+ if (of_find_property(np, "samsung,wkup-eint", NULL))
+ bank->eint_type = EINT_TYPE_WKUP;
+ else
+ bank->eint_type = EINT_TYPE_GPIO;
ret = of_property_read_u32(np, "samsung,eint-offset", &val);
if (ret)
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/pinctrl-samsung.h
index f27b1e0..355f4e2 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/pinctrl-samsung.h
@@ -66,6 +66,7 @@ enum pincfg_type {
* @EINT_TYPE_NONE: bank does not support external interrupts
* @EINT_TYPE_GPIO: bank supportes external gpio interrupts
* @EINT_TYPE_WKUP: bank supportes external wakeup interrupts
+ * @EINT_TYPE_WKUP_MUX: bank supports multiplexed external wakeup interrupts
*
* Samsung GPIO controller groups all the available pins into banks. The pins
* in a pin bank can support external gpio interrupts or external wakeup
@@ -78,6 +79,7 @@ enum eint_type {
EINT_TYPE_NONE,
EINT_TYPE_GPIO,
EINT_TYPE_WKUP,
+ EINT_TYPE_WKUP_MUX,
};
/* maximum length of a pin in pin descriptor (example: "gpa0-0") */
@@ -157,7 +159,6 @@ struct samsung_pin_ctrl_variant {
* @nr_banks: number of pin banks.
* @base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller.
- * @nr_wint: number of external wakeup interrupts supported.
* @geint_con: offset of the ext-gpio controller registers.
* @geint_mask: offset of the ext-gpio interrupt mask registers.
* @geint_pend: offset of the ext-gpio interrupt pending registers.
@@ -177,7 +178,6 @@ struct samsung_pin_ctrl {
u32 base;
u32 nr_pins;
- u32 nr_wint;
u32 geint_con;
u32 geint_mask;
@@ -220,8 +220,6 @@ struct samsung_pinctrl_drv_data {
unsigned int nr_groups;
const struct samsung_pmx_func *pmx_functions;
unsigned int nr_functions;
-
- struct irq_domain *wkup_irqd;
};
/**
--
1.7.12
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox