Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* ARM: relocation out of range (when loading a module)
From: Alexander Holler @ 2011-01-13 14:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113100407.GB24149@n2100.arm.linux.org.uk>

Am 13.01.2011 11:04, schrieb Russell King - ARM Linux:

>> At least I like that feature since it is available and won't miss it now. ;)
>
> The feature isn't available if it doesn't work.  It's not going to get
> fixed for 2.6.38 - it'll be 2.6.39 due to the timing and complexity of
> the problem.

I just wanted to express that I like that feature a lot and I didn't 
wanted to ask for a quick fix nor did I wanted to make pressure.

I've tried a the patch from Rabin Vincent (along with an alignment) and 
it works. It might not be the best solution and I certainly waste some 
memory (no free), but I don't care.

Regards,

Alexander

^ permalink raw reply

* [PATCH] ARM: pxa: PalmZ72: Add OV9640 camera support
From: Marek Vasut @ 2011-01-13 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

Rework of patch from 2009:
PalmZ72: Add support for OV9640 camera sensor

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
 arch/arm/mach-pxa/include/mach/palmz72.h |    5 +
 arch/arm/mach-pxa/palmz72.c              |  135 ++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
index 2bbcf70..0d4700a 100644
--- a/arch/arm/mach-pxa/include/mach/palmz72.h
+++ b/arch/arm/mach-pxa/include/mach/palmz72.h
@@ -44,6 +44,11 @@
 #define GPIO_NR_PALMZ72_BT_POWER		17
 #define GPIO_NR_PALMZ72_BT_RESET		83
 
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN		56
+#define GPIO_NR_PALMZ72_CAM_RESET		57
+#define GPIO_NR_PALMZ72_CAM_POWER		91
+
 /** Initial values **/
 
 /* Battery */
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 7bf4017..12d58d2 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -30,6 +30,7 @@
 #include <linux/wm97xx.h>
 #include <linux/power_supply.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,6 +48,9 @@
 #include <mach/palm27x.h>
 
 #include <mach/pm.h>
+#include <mach/camera.h>
+
+#include <media/soc_camera.h>
 
 #include "generic.h"
 #include "devices.h"
@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
 	GPIO22_GPIO,	/* LCD border color */
 	GPIO96_GPIO,	/* lcd power */
 
+	/* PXA Camera */
+	GPIO81_CIF_DD_0,
+	GPIO48_CIF_DD_5,
+	GPIO50_CIF_DD_3,
+	GPIO51_CIF_DD_2,
+	GPIO52_CIF_DD_4,
+	GPIO53_CIF_MCLK,
+	GPIO54_CIF_PCLK,
+	GPIO55_CIF_DD_1,
+	GPIO84_CIF_FV,
+	GPIO85_CIF_LV,
+	GPIO93_CIF_DD_6,
+	GPIO108_CIF_DD_7,
+
+	GPIO56_GPIO,	/* OV9640 Powerdown */
+	GPIO57_GPIO,	/* OV9640 Reset */
+	GPIO91_GPIO,	/* OV9640 Power */
+
+	/* I2C */
+	GPIO117_GPIO,	/* I2C_SCL */
+	GPIO118_GPIO,	/* I2C_SDA */
+
 	/* Misc. */
 	GPIO0_GPIO	| WAKEUP_ON_LEVEL_HIGH,	/* power detect */
 	GPIO88_GPIO,				/* green led */
@@ -254,6 +280,114 @@ device_initcall(palmz72_pm_init);
 #endif
 
 /******************************************************************************
+ * SoC Camera
+ ******************************************************************************/
+#if defined(CONFIG_SOC_CAMERA_OV9640) || \
+	defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
+static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
+	.flags		= PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+			PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz	= 2600,
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info palmz72_i2c_device[] = {
+	{
+		I2C_BOARD_INFO("ov9640", 0x30),
+	}
+};
+
+static int palmz72_camera_power(struct device *dev, int power)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
+	mdelay(50);
+	return 0;
+}
+
+static int palmz72_camera_reset(struct device *dev)
+{
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
+	mdelay(50);
+	gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
+	mdelay(50);
+	return 0;
+}
+
+static struct soc_camera_link palmz72_iclink = {
+	.bus_id		= 0, /* Match id in pxa27x_device_camera in device.c */
+	.board_info	= &palmz72_i2c_device[0],
+	.i2c_adapter_id	= 0,
+	.module_name	= "ov96xx",
+	.power		= &palmz72_camera_power,
+	.reset		= &palmz72_camera_reset,
+	.flags		= SOCAM_DATAWIDTH_8,
+};
+
+static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
+	.sda_pin	= 118,
+	.scl_pin	= 117,
+	.udelay		= 10,
+	.timeout	= 100,
+};
+
+static struct platform_device palmz72_i2c_bus_device = {
+	.name		= "i2c-gpio",
+	.id		= 0, /* we use this as a replacement for i2c-pxa */
+	.dev		= {
+		.platform_data	= &palmz72_i2c_bus_data,
+	}
+};
+
+static struct platform_device palmz72_camera = {
+	.name	= "soc-camera-pdrv",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &palmz72_iclink,
+	},
+};
+
+/* Here we request the camera GPIOs and configure them. We power up the camera
+ * module, deassert the reset pin, but put it into powerdown (low to no power
+ * consumption) mode. This allows us to later bring the module up fast. */
+static inline void __init palmz72_cam_gpio_init(void)
+{
+	if (gpio_request(GPIO_NR_PALMZ72_CAM_PWDN, "Camera PWDN"))
+		goto err1;
+	if (gpio_request(GPIO_NR_PALMZ72_CAM_RESET, "Camera RESET"))
+		goto err2;
+	if (gpio_request(GPIO_NR_PALMZ72_CAM_POWER, "Camera DVDD"))
+		goto err3;
+	if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_POWER, 1))
+		goto err4;
+	if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_RESET, 0))
+		goto err4;
+	if (gpio_direction_output(GPIO_NR_PALMZ72_CAM_PWDN, 0))
+		goto err4;
+	return;
+
+err4:
+	gpio_free(GPIO_NR_PALMZ72_CAM_POWER);
+err3:
+	gpio_free(GPIO_NR_PALMZ72_CAM_RESET);
+err2:
+	gpio_free(GPIO_NR_PALMZ72_CAM_PWDN);
+err1:
+	printk(KERN_ERR "Camera GPIO init failed!\n");
+	return;
+}
+
+static void __init palmz72_camera_init(void)
+{
+	palmz72_cam_gpio_init();
+	pxa_set_camera_info(&palmz72_pxacamera_platform_data);
+	platform_device_register(&palmz72_i2c_bus_device);
+	platform_device_register(&palmz72_camera);
+}
+#else
+static inline void palmz72_camera_init(void) {}
+#endif
+
+/******************************************************************************
  * Machine init
  ******************************************************************************/
 static void __init palmz72_init(void)
@@ -276,6 +410,7 @@ static void __init palmz72_init(void)
 	palm27x_pmic_init();
 	palmz72_kpc_init();
 	palmz72_leds_init();
+	palmz72_camera_init();
 }
 
 MACHINE_START(PALMZ72, "Palm Zire72")
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH v2] unbreak ehci-mxc on otg port of i.MX27
From: Eric Bénard @ 2011-01-13 13:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113091229.GE12078@pengutronix.de>

commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support
for i.MX51 but broke it for (at least) i.MX27 which doesn't have
a usb_phy1 clock but has a pdev->id 0.

Signed-off-by: Eric B?nard <eric@eukrea.com>
Cc: Arnaud Patard <arnaud.patard@rtp-net.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
---
v2: fix missing &, remove parenthesis and add i.MX51 in the comment

 drivers/usb/host/ehci-mxc.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index fa59b26..d443fbd 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -177,8 +177,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
 		clk_enable(priv->ahbclk);
 	}
 
-	/* "dr" device has its own clock */
-	if (pdev->id == 0) {
+	/* "dr" device has its own clock on i.MX51 */
+	if (cpu_is_mx51() && (pdev->id == 0)) {
 		priv->phy1clk = clk_get(dev, "usb_phy1");
 		if (IS_ERR(priv->phy1clk)) {
 			ret = PTR_ERR(priv->phy1clk);
-- 
1.7.3.4

^ permalink raw reply related

* NFS root lockups with -next 20110113
From: Santosh Shilimkar @ 2011-01-13 13:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8138.1294924927@jrobl>

(+ 'linux-arm' since same problem was getting discussed
 in another thread)

> -----Original Message-----
> From: Santosh Shilimkar [mailto:santosh.shilimkar at ti.com]
> Sent: Thursday, January 13, 2011 6:59 PM
> To: 'J. R. Okajima'; 'Mark Brown'
> Cc: 'Trond Myklebust'; 'Nick Piggin'; 'linux-nfs at vger.kernel.org';
> 'linux-kernel at vger.kernel.org'; 'linux-fsdevel at vger.kernel.org'
> Subject: RE: NFS root lockups with -next 20110113
>
> > -----Original Message-----
> > From: J. R. Okajima [mailto:hooanon05 at yahoo.co.jp]
> > Sent: Thursday, January 13, 2011 6:52 PM
> > To: Mark Brown
> > Cc: Trond Myklebust; Santosh Shilimkar; Nick Piggin; linux-
> > nfs at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> > fsdevel at vger.kernel.org
> > Subject: Re: NFS root lockups with -next 20110113
> >
> >
> > Mark Brown:
> > > With -next 20110113 I'm experiencing lockups shortly after
> > userspace
> > > starts when booting with my root filesystem on NFS, log below.
> I
> > can
> > > boot into /bin/sh but running real userspace triggers this very
> > easily.
> > > This was introduced sometime this week.
> > >
> > > I've not bisected or otherwise investigated much yet, but I do
> > notice
> > > code added recently by Nick in "fs: rcu-walk for path lookup"
> > showing up
> > > in the backtrace so including him in the CCs.
> >
> > This and a report from Santosh Shilimkar look like the same
> problem
> > which I reported, and I am testing this patch. If you can, please
> > try it
> > too.
> > Note: Of course this is not offcial fix.
> >
>
> It works. My board booted with NFS with below patch
>
>
> >
> > diff --git a/fs/namei.c b/fs/namei.c
> > index 5bb7588..51d052f 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -480,6 +480,7 @@ static int nameidata_dentry_drop_rcu(struct
> > nameidata *nd, struct dentry *dentry
> >  {
> >  	struct fs_struct *fs = current->fs;
> >  	struct dentry *parent = nd->path.dentry;
> > +	int isroot;
> >
> >  	BUG_ON(!(nd->flags & LOOKUP_RCU));
> >  	if (nd->root.mnt) {
> > @@ -489,18 +490,22 @@ static int nameidata_dentry_drop_rcu(struct
> > nameidata *nd, struct dentry *dentry
> >  			goto err_root;
> >  	}
> >  	spin_lock(&parent->d_lock);
> > -	spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
> > -	if (!__d_rcu_to_refcount(dentry, nd->seq))
> > -		goto err;
> > +	isroot = IS_ROOT(dentry);
> > +	if (!isroot) {
> > +		spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
> > +		if (!__d_rcu_to_refcount(dentry, nd->seq))
> > +			goto err;
> > +	}
> >  	/*
> >  	 * If the sequence check on the child dentry passed, then the
> > child has
> >  	 * not been removed from its parent. This means the parent
> > dentry must
> >  	 * be valid and able to take a reference at this point.
> >  	 */
> > -	BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent);
> > +	BUG_ON(!isroot && dentry->d_parent != parent);
> >  	BUG_ON(!parent->d_count);
> >  	parent->d_count++;
> > -	spin_unlock(&dentry->d_lock);
> > +	if (!isroot)
> > +		spin_unlock(&dentry->d_lock);
> >  	spin_unlock(&parent->d_lock);
> >  	if (nd->root.mnt) {
> >  		path_get(&nd->root);
> > @@ -513,7 +518,8 @@ static int nameidata_dentry_drop_rcu(struct
> > nameidata *nd, struct dentry *dentry
> >  	nd->flags &= ~LOOKUP_RCU;
> >  	return 0;
> >  err:
> > -	spin_unlock(&dentry->d_lock);
> > +	if (!isroot)
> > +		spin_unlock(&dentry->d_lock);
> >  	spin_unlock(&parent->d_lock);
> >  err_root:
> >  	if (nd->root.mnt)

^ permalink raw reply

* [patch 2/2] mx51: add support for pwm
From: Uwe Kleine-König @ 2011-01-13 13:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113113007.690473432@rtp-net.org>

On Thu, Jan 13, 2011 at 12:26:40PM +0100, Arnaud Patard wrote:
> This patch is adding support for pwm1 and pwm2 devices found
> on mx51.
> [ this patch has been tested with pwm-backlight driver ]
> 
> Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>
> Index: linux-2.6-submit/arch/arm/mach-mx5/clock-mx51-mx53.c
> ===================================================================
> --- linux-2.6-submit.orig/arch/arm/mach-mx5/clock-mx51-mx53.c	2011-01-12 16:51:29.000000000 +0100
> +++ linux-2.6-submit/arch/arm/mach-mx5/clock-mx51-mx53.c	2011-01-12 16:54:40.000000000 +0100
> @@ -1228,6 +1228,11 @@
>  DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
>  	NULL,  NULL, &ipg_clk, &gpt_ipg_clk);
>  
> +DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
> +	NULL, NULL, &ipg_clk, NULL);
> +DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
> +	NULL, NULL, &ipg_clk, NULL);
> +
>  /* I2C */
>  DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
>  	NULL, NULL, &ipg_clk, NULL);
> @@ -1320,6 +1325,8 @@
>  	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
>  	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
>  	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +	_REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
> +	_REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
You really need "pwm"? I'd prefer NULL if that works, too.  (And if not,
please fix the driver :-)

Uwe
>  	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
>  	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
>  	_REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
> Index: linux-2.6-submit/arch/arm/plat-mxc/pwm.c
> ===================================================================
> --- linux-2.6-submit.orig/arch/arm/plat-mxc/pwm.c	2011-01-12 16:48:33.000000000 +0100
> +++ linux-2.6-submit/arch/arm/plat-mxc/pwm.c	2011-01-12 16:54:40.000000000 +0100
> @@ -57,7 +57,7 @@
>  	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
>  		return -EINVAL;
>  
> -	if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
> +	if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
>  		unsigned long long c;
>  		unsigned long period_cycles, duty_cycles, prescale;
>  		u32 cr;
Hmm, time to convert to platform-id?

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply

* [PATCH 2/2] ARM MXS: Add auart platform support for i.MX28
From: Sascha Hauer @ 2011-01-13 13:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294924476-10653-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-mxs/clock-mx28.c                  |    5 ++
 arch/arm/mach-mxs/devices-mx28.h                |    8 +++
 arch/arm/mach-mxs/devices/Kconfig               |    3 +
 arch/arm/mach-mxs/devices/Makefile              |    1 +
 arch/arm/mach-mxs/devices/platform-auart.c      |   54 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   10 ++++
 6 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-auart.c

diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 74e2103..9f65934 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -603,6 +603,11 @@ _DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
 
 static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
 	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 00b736c..a0b70df 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -15,6 +15,14 @@ extern const struct mxs_duart_data mx28_duart_data __initconst;
 #define mx28_add_duart() \
 	mxs_add_duart(&mx28_duart_data)
 
+extern const struct mxs_auart_data mx28_auart_data[] __initconst;
+#define mx28_add_auart(id)	mxs_add_auart(&mx28_auart_data[id])
+#define mx28_add_auart0()		mx28_add_auart(0)
+#define mx28_add_auart1()		mx28_add_auart(1)
+#define mx28_add_auart2()		mx28_add_auart(2)
+#define mx28_add_auart3()		mx28_add_auart(3)
+#define mx28_add_auart4()		mx28_add_auart(4)
+
 extern const struct mxs_fec_data mx28_fec_data[] __initconst;
 #define mx28_add_fec(id, pdata) \
 	mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index a35a2dc..9d16540 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -1,5 +1,8 @@
 config MXS_HAVE_PLATFORM_DUART
 	bool
 
+config MXS_HAVE_PLATFORM_AUART
+	bool
+
 config MXS_HAVE_PLATFORM_FEC
 	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index 4b5266a..b46d18d 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
diff --git a/arch/arm/mach-mxs/devices/platform-auart.c b/arch/arm/mach-mxs/devices/platform-auart.c
new file mode 100644
index 0000000..f0dbf8a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-auart.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * 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 <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_auart_data_entry_single(soc, _id)				\
+	{								\
+		.id = _id,						\
+		.iobase = soc ## _AUART ## _id ## _BASE_ADDR,		\
+		.irq = soc ## _INT_AUART ## _id,			\
+	}
+
+#define mxs_auart_data_entry(soc, _id)					\
+	[_id] = mxs_auart_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_auart_data mx28_auart_data[] __initconst = {
+#define mx28_auart_data_entry(_id)					\
+	mxs_auart_data_entry(MX28, _id)
+	mx28_auart_data_entry(0),
+	mx28_auart_data_entry(1),
+	mx28_auart_data_entry(2),
+	mx28_auart_data_entry(3),
+	mx28_auart_data_entry(4),
+};
+#endif
+
+struct platform_device *__init mxs_add_auart(
+		const struct mxs_auart_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_8K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device_dmamask("mxs-auart", data->id,
+					res, ARRAY_SIZE(res), NULL, 0,
+					DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 3da48d4..b8ab332 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -33,6 +33,16 @@ struct mxs_duart_data {
 struct platform_device *__init mxs_add_duart(
 		const struct mxs_duart_data *data);
 
+/* auart */
+struct mxs_auart_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_auart(
+		const struct mxs_auart_data *data);
+
 /* fec */
 #include <linux/fec.h>
 struct mxs_fec_data {
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 1/2] serial: Add auart driver for i.MX23/28
From: Sascha Hauer @ 2011-01-13 13:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294924476-10653-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/serial/Kconfig     |   15 +
 drivers/serial/Makefile    |    1 +
 drivers/serial/mxs-auart.c |  806 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 822 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/mxs-auart.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ec3c214..6a2a39c 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1657,4 +1657,19 @@ config SERIAL_PCH_UART
 	  This driver is for PCH(Platform controller Hub) UART of Intel EG20T
 	  which is an IOH(Input/Output Hub) for x86 embedded processor.
 	  Enabling PCH_DMA, this PCH UART works as DMA mode.
+
+config SERIAL_MXS_AUART
+	depends on ARCH_MXS
+	tristate "MXS AUART support"
+	select SERIAL_CORE
+	help
+	  This driver supports the MXS Application UART (AUART) port.
+
+config SERIAL_MXS_AUART_CONSOLE
+	bool "MXS AUART console support"
+	depends on SERIAL_MXS_AUART=y
+	select SERIAL_CORE_CONSOLE
+	help
+	  Enable a MXS AUART port to be the system console.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 8ea92e9..c855071 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -92,3 +92,4 @@ obj-$(CONFIG_SERIAL_MRST_MAX3110)	+= mrst_max3110.o
 obj-$(CONFIG_SERIAL_MFD_HSU)	+= mfd.o
 obj-$(CONFIG_SERIAL_IFX6X60)  	+= ifx6x60.o
 obj-$(CONFIG_SERIAL_PCH_UART)	+= pch_uart.o
+obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
diff --git a/drivers/serial/mxs-auart.c b/drivers/serial/mxs-auart.c
new file mode 100644
index 0000000..6529fd7
--- /dev/null
+++ b/drivers/serial/mxs-auart.c
@@ -0,0 +1,806 @@
+/*
+ * Freescale STMP37XX/STMP378X Application UART driver
+ *
+ * Author: dmitry pervushin <dimka@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#define MXS_AUART_PORTS 5
+
+#define AUART_CTRL0			0x00000000
+#define AUART_CTRL0_SET			0x00000004
+#define AUART_CTRL0_CLR			0x00000008
+#define AUART_CTRL0_TOG			0x0000000c
+#define AUART_CTRL1			0x00000010
+#define AUART_CTRL1_SET			0x00000014
+#define AUART_CTRL1_CLR			0x00000018
+#define AUART_CTRL1_TOG			0x0000001c
+#define AUART_CTRL2			0x00000020
+#define AUART_CTRL2_SET			0x00000024
+#define AUART_CTRL2_CLR			0x00000028
+#define AUART_CTRL2_TOG			0x0000002c
+#define AUART_LINECTRL			0x00000030
+#define AUART_LINECTRL_SET		0x00000034
+#define AUART_LINECTRL_CLR		0x00000038
+#define AUART_LINECTRL_TOG		0x0000003c
+#define AUART_LINECTRL2			0x00000040
+#define AUART_LINECTRL2_SET		0x00000044
+#define AUART_LINECTRL2_CLR		0x00000048
+#define AUART_LINECTRL2_TOG		0x0000004c
+#define AUART_INTR			0x00000050
+#define AUART_INTR_SET			0x00000054
+#define AUART_INTR_CLR			0x00000058
+#define AUART_INTR_TOG			0x0000005c
+#define AUART_DATA			0x00000060
+#define AUART_STAT			0x00000070
+#define AUART_DEBUG			0x00000080
+#define AUART_VERSION			0x00000090
+#define AUART_AUTOBAUD			0x000000a0
+
+#define AUART_CTRL0_SFTRST			(1 << 31)
+#define AUART_CTRL0_CLKGATE			(1 << 30)
+
+
+#define AUART_CTRL2_CTSEN			(1 << 15)
+#define AUART_CTRL2_RTS				(1 << 11)
+#define AUART_CTRL2_RXE				(1 << 9)
+#define AUART_CTRL2_TXE				(1 << 8)
+#define AUART_CTRL2_UARTEN			(1 << 0)
+
+#define AUART_LINECTRL_BAUD_DIVINT_SHIFT	16
+#define AUART_LINECTRL_BAUD_DIVINT_MASK		0xffff0000
+#define AUART_LINECTRL_BAUD_DIVINT(v)		(((v) & 0xffff) << 16)
+#define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT	8
+#define AUART_LINECTRL_BAUD_DIVFRAC_MASK	0x00003f00
+#define AUART_LINECTRL_BAUD_DIVFRAC(v)		(((v) & 0x3f) << 8)
+#define AUART_LINECTRL_WLEN_MASK		0x00000060
+#define AUART_LINECTRL_WLEN(v)			(((v) & 0x3) << 5)
+#define AUART_LINECTRL_FEN			(1 << 4)
+#define AUART_LINECTRL_STP2			(1 << 3)
+#define AUART_LINECTRL_EPS			(1 << 2)
+#define AUART_LINECTRL_PEN			(1 << 1)
+#define AUART_LINECTRL_BRK			(1 << 0)
+
+#define AUART_INTR_RTIEN			(1 << 22)
+#define AUART_INTR_TXIEN			(1 << 21)
+#define AUART_INTR_RXIEN			(1 << 20)
+#define AUART_INTR_CTSMIEN			(1 << 17)
+#define AUART_INTR_RTIS				(1 << 6)
+#define AUART_INTR_TXIS				(1 << 5)
+#define AUART_INTR_RXIS				(1 << 4)
+#define AUART_INTR_CTSMIS			(1 << 1)
+
+#define AUART_STAT_BUSY				(1 << 29)
+#define AUART_STAT_CTS				(1 << 28)
+#define AUART_STAT_TXFE				(1 << 27)
+#define AUART_STAT_TXFF				(1 << 25)
+#define AUART_STAT_RXFE				(1 << 24)
+#define AUART_STAT_OERR				(1 << 19)
+#define AUART_STAT_BERR				(1 << 18)
+#define AUART_STAT_PERR				(1 << 17)
+#define AUART_STAT_FERR				(1 << 16)
+
+#define UART_DUMMY_STAT_RX			(1 << 31)
+
+static struct uart_driver auart_driver;
+
+struct mxs_auart_port {
+	struct uart_port port;
+
+	unsigned int flags;
+	unsigned int ctrl;
+
+	unsigned int irq;
+
+	struct clk *clk;
+	struct device *dev;
+};
+
+static void mxs_auart_stop_tx(struct uart_port *u);
+
+#define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
+
+static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
+{
+	struct circ_buf *xmit = &s->port.state->xmit;
+
+	while (!(readl(s->port.membase + AUART_STAT) &
+		 AUART_STAT_TXFF)) {
+		if (s->port.x_char) {
+			s->port.icount.tx++;
+			writel(s->port.x_char,
+				     s->port.membase + AUART_DATA);
+			s->port.x_char = 0;
+			continue;
+		}
+		if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
+			s->port.icount.tx++;
+			writel(xmit->buf[xmit->tail],
+				     s->port.membase + AUART_DATA);
+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+			if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+				uart_write_wakeup(&s->port);
+		} else
+			break;
+	}
+	if (uart_circ_empty(&(s->port.state->xmit)))
+		writel(AUART_INTR_TXIEN,
+			     s->port.membase + AUART_INTR_CLR);
+	else
+		writel(AUART_INTR_TXIEN,
+			     s->port.membase + AUART_INTR_SET);
+
+	if (uart_tx_stopped(&s->port))
+		mxs_auart_stop_tx(&s->port);
+}
+
+static void mxs_auart_rx_char(struct mxs_auart_port *s)
+{
+	int flag;
+	u32 stat;
+	u8 c;
+
+	c = readl(s->port.membase + AUART_DATA);
+	stat = readl(s->port.membase + AUART_STAT) | UART_DUMMY_STAT_RX;
+
+	flag = TTY_NORMAL;
+	s->port.icount.rx++;
+
+	if (stat & AUART_STAT_BERR) {
+		s->port.icount.brk++;
+		if (uart_handle_break(&s->port))
+			goto out;
+	} else if (stat & AUART_STAT_PERR) {
+		s->port.icount.parity++;
+	} else if (stat & AUART_STAT_FERR) {
+		s->port.icount.frame++;
+	}
+
+	/*
+	 * Mask off conditions which should be ingored.
+	 */
+	stat &= s->port.read_status_mask;
+
+	if (stat & AUART_STAT_BERR) {
+		flag = TTY_BREAK;
+	} else if (stat & AUART_STAT_PERR)
+		flag = TTY_PARITY;
+	else if (stat & AUART_STAT_FERR)
+		flag = TTY_FRAME;
+
+	if (stat & AUART_STAT_OERR)
+		s->port.icount.overrun++;
+
+	if (uart_handle_sysrq_char(&s->port, c))
+		goto out;
+
+	uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag);
+out:
+	writel(stat, s->port.membase + AUART_STAT);
+}
+
+static void mxs_auart_rx_chars(struct mxs_auart_port *s)
+{
+	struct tty_struct *tty = s->port.state->port.tty;
+	u32 stat = 0;
+
+	for (;;) {
+		stat = readl(s->port.membase + AUART_STAT);
+		if (stat & AUART_STAT_RXFE)
+			break;
+		mxs_auart_rx_char(s);
+	}
+
+	writel(stat, s->port.membase + AUART_STAT);
+	tty_flip_buffer_push(tty);
+}
+
+static int mxs_auart_request_port(struct uart_port *u)
+{
+	return 0;
+}
+
+static int mxs_auart_verify_port(struct uart_port *u,
+				    struct serial_struct *ser)
+{
+	if (u->type != PORT_UNKNOWN && u->type != PORT_IMX)
+		return -EINVAL;
+	return 0;
+}
+
+static void mxs_auart_config_port(struct uart_port *u, int flags)
+{
+}
+
+static const char *mxs_auart_type(struct uart_port *u)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	return dev_name(s->dev);
+}
+
+static void mxs_auart_release_port(struct uart_port *u)
+{
+}
+
+static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	u32 ctrl = readl(u->membase + AUART_CTRL2);
+
+	ctrl &= ~AUART_CTRL2_RTS;
+	if (mctrl & TIOCM_RTS)
+		ctrl |= AUART_CTRL2_RTS;
+	s->ctrl = mctrl;
+	writel(ctrl, u->membase + AUART_CTRL2);
+}
+
+static u32 mxs_auart_get_mctrl(struct uart_port *u)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+	u32 stat = readl(u->membase + AUART_STAT);
+	int ctrl2 = readl(u->membase + AUART_CTRL2);
+	u32 mctrl = s->ctrl;
+
+	mctrl &= ~TIOCM_CTS;
+	if (stat & AUART_STAT_CTS)
+		mctrl |= TIOCM_CTS;
+
+	if (ctrl2 & AUART_CTRL2_RTS)
+		mctrl |= TIOCM_RTS;
+
+	return mctrl;
+}
+
+static void mxs_auart_settermios(struct uart_port *u,
+				 struct ktermios *termios,
+				 struct ktermios *old)
+{
+	u32 bm, ctrl, ctrl2, div;
+	unsigned int cflag, baud;
+
+	cflag = termios->c_cflag;
+
+	ctrl = AUART_LINECTRL_FEN;
+	ctrl2 = readl(u->membase + AUART_CTRL2);
+
+	/* byte size */
+	switch (cflag & CSIZE) {
+	case CS5:
+		bm = 0;
+		break;
+	case CS6:
+		bm = 1;
+		break;
+	case CS7:
+		bm = 2;
+		break;
+	case CS8:
+		bm = 3;
+		break;
+	default:
+		return;
+	}
+
+	ctrl |= AUART_LINECTRL_WLEN(bm);
+
+	/* parity */
+	if (cflag & PARENB) {
+		ctrl |= AUART_LINECTRL_PEN;
+		if ((cflag & PARODD) == 0)
+			ctrl |= AUART_LINECTRL_EPS;
+	}
+
+	u->read_status_mask = 0;
+
+	if (termios->c_iflag & INPCK)
+		u->read_status_mask |= AUART_STAT_PERR;
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		u->read_status_mask |= AUART_STAT_BERR;
+
+	/*
+	 * Characters to ignore
+	 */
+	u->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		u->ignore_status_mask |= AUART_STAT_PERR;
+	if (termios->c_iflag & IGNBRK) {
+		u->ignore_status_mask |= AUART_STAT_BERR;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			u->ignore_status_mask |= AUART_STAT_OERR;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		u->ignore_status_mask |= UART_DUMMY_STAT_RX;
+
+	/* figure out the stop bits requested */
+	if (cflag & CSTOPB)
+		ctrl |= AUART_LINECTRL_STP2;
+
+	/* figure out the hardware flow control settings */
+	if (cflag & CRTSCTS)
+		ctrl2 |= AUART_CTRL2_CTSEN;
+	else
+		ctrl2 &= ~AUART_CTRL2_CTSEN;
+
+	/* set baud rate */
+	baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
+	div = u->uartclk * 32 / baud;
+	ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
+	ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6);
+
+	if ((cflag & CREAD) != 0)
+		ctrl2 |= AUART_CTRL2_RXE;
+
+	writel(ctrl, u->membase + AUART_LINECTRL);
+	writel(ctrl2, u->membase + AUART_CTRL2);
+}
+
+static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
+{
+	u32 istatus, istat;
+	struct mxs_auart_port *s = context;
+	u32 stat = readl(s->port.membase + AUART_STAT);
+
+	istatus = istat = readl(s->port.membase + AUART_INTR);
+
+	if (istat & AUART_INTR_CTSMIS) {
+		uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
+		writel(AUART_INTR_CTSMIS,
+				s->port.membase + AUART_INTR_CLR);
+		istat &= ~AUART_INTR_CTSMIS;
+	}
+
+	if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) {
+		mxs_auart_rx_chars(s);
+		istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS);
+	}
+
+	if (istat & AUART_INTR_TXIS) {
+		mxs_auart_tx_chars(s);
+		istat &= ~AUART_INTR_TXIS;
+	}
+
+	writel(istatus & (AUART_INTR_RTIS
+		| AUART_INTR_TXIS
+		| AUART_INTR_RXIS
+		| AUART_INTR_CTSMIS),
+			s->port.membase + AUART_INTR_CLR);
+
+	return IRQ_HANDLED;
+}
+
+static void mxs_auart_reset(struct uart_port *u)
+{
+	int i;
+	unsigned int reg;
+
+	writel(AUART_CTRL0_SFTRST,
+		     u->membase + AUART_CTRL0_CLR);
+
+	for (i = 0; i < 10000; i++) {
+		reg = readl(u->membase + AUART_CTRL0);
+		if (!(reg & AUART_CTRL0_SFTRST))
+			break;
+		udelay(3);
+	}
+}
+
+static int mxs_auart_startup(struct uart_port *u)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	clk_enable(s->clk);
+
+	writel(AUART_CTRL0_CLKGATE,
+		     u->membase + AUART_CTRL0_CLR);
+
+	writel(AUART_CTRL2_UARTEN,
+		     s->port.membase + AUART_CTRL2_SET);
+
+	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN,
+		     s->port.membase + AUART_INTR);
+
+	writel(AUART_INTR_CTSMIEN,
+		     s->port.membase + AUART_INTR_SET);
+
+	/*
+	 * Enable fifo so all four bytes of a DMA word are written to
+	 * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
+	 */
+	writel(AUART_LINECTRL_FEN,
+		     s->port.membase + AUART_LINECTRL_SET);
+
+	return 0;
+}
+
+static void mxs_auart_shutdown(struct uart_port *u)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	writel(AUART_CTRL2_UARTEN,
+		     s->port.membase + AUART_CTRL2_CLR);
+
+	writel(AUART_CTRL0_CLKGATE,
+		     u->membase + AUART_CTRL0_SET);
+
+	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN |
+			AUART_INTR_CTSMIEN,
+			s->port.membase + AUART_INTR_CLR);
+
+	clk_disable(s->clk);
+}
+
+static unsigned int mxs_auart_tx_empty(struct uart_port *u)
+{
+	if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE)
+		return TIOCSER_TEMT;
+	else
+		return 0;
+}
+
+static void mxs_auart_start_tx(struct uart_port *u)
+{
+	struct mxs_auart_port *s = to_auart_port(u);
+
+	/* enable transmitter */
+	writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET);
+
+	mxs_auart_tx_chars(s);
+}
+
+static void mxs_auart_stop_tx(struct uart_port *u)
+{
+	writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR);
+}
+
+static void mxs_auart_stop_rx(struct uart_port *u)
+{
+	writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR);
+}
+
+static void mxs_auart_break_ctl(struct uart_port *u, int ctl)
+{
+	if (ctl)
+		writel(AUART_LINECTRL_BRK,
+			     u->membase + AUART_LINECTRL_SET);
+	else
+		writel(AUART_LINECTRL_BRK,
+			     u->membase + AUART_LINECTRL_CLR);
+}
+
+static void mxs_auart_enable_ms(struct uart_port *port)
+{
+	/* just empty */
+}
+
+static struct uart_ops mxs_auart_ops = {
+	.tx_empty       = mxs_auart_tx_empty,
+	.start_tx       = mxs_auart_start_tx,
+	.stop_tx	= mxs_auart_stop_tx,
+	.stop_rx	= mxs_auart_stop_rx,
+	.enable_ms      = mxs_auart_enable_ms,
+	.break_ctl      = mxs_auart_break_ctl,
+	.set_mctrl	= mxs_auart_set_mctrl,
+	.get_mctrl      = mxs_auart_get_mctrl,
+	.startup	= mxs_auart_startup,
+	.shutdown       = mxs_auart_shutdown,
+	.set_termios    = mxs_auart_settermios,
+	.type	   	= mxs_auart_type,
+	.release_port   = mxs_auart_release_port,
+	.request_port   = mxs_auart_request_port,
+	.config_port    = mxs_auart_config_port,
+	.verify_port    = mxs_auart_verify_port,
+};
+
+static struct mxs_auart_port *auart_port[MXS_AUART_PORTS];
+
+#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
+static void mxs_auart_console_putchar(struct uart_port *port, int ch)
+{
+	unsigned int status;
+
+	do {
+		status = readl(port->membase + AUART_STAT);
+	} while (status & AUART_STAT_TXFF);
+	writel(ch, port->membase + AUART_DATA);
+}
+
+static void
+auart_console_write(struct console *co, const char *str, unsigned int count)
+{
+	struct mxs_auart_port *s;
+	struct uart_port *port;
+	unsigned int status, old_ctrl0, old_ctrl2;
+
+	if (co->index >	MXS_AUART_PORTS || co->index < 0)
+		return;
+
+	s = auart_port[co->index];
+	port = &s->port;
+
+	clk_enable(s->clk);
+
+	/* First save the CR then disable the interrupts */
+	old_ctrl2 = readl(port->membase + AUART_CTRL2);
+	old_ctrl0 = readl(port->membase + AUART_CTRL0);
+
+	writel(AUART_CTRL0_CLKGATE,
+		     port->membase + AUART_CTRL0_CLR);
+	writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE,
+		     port->membase + AUART_CTRL2_SET);
+
+	uart_console_write(port, str, count, mxs_auart_console_putchar);
+
+	/*
+	 * Finally, wait for transmitter to become empty
+	 * and restore the TCR
+	 */
+	do {
+		status = readl(port->membase + AUART_STAT);
+	} while (status & AUART_STAT_BUSY);
+
+	writel(old_ctrl0, port->membase + AUART_CTRL0);
+	writel(old_ctrl2, port->membase + AUART_CTRL2);
+
+	clk_disable(s->clk);
+}
+
+static void __init
+auart_console_get_options(struct uart_port *port, int *baud,
+			  int *parity, int *bits)
+{
+	unsigned int lcr_h, quot;
+
+	if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN))
+		return;
+
+	lcr_h = readl(port->membase + AUART_LINECTRL);
+
+	*parity = 'n';
+	if (lcr_h & AUART_LINECTRL_PEN) {
+		if (lcr_h & AUART_LINECTRL_EPS)
+			*parity = 'e';
+		else
+			*parity = 'o';
+	}
+
+	if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2))
+		*bits = 7;
+	else
+		*bits = 8;
+
+	quot = ((readl(port->membase + AUART_LINECTRL)
+			& AUART_LINECTRL_BAUD_DIVINT_MASK))
+			    >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6);
+	quot |= ((readl(port->membase + AUART_LINECTRL)
+			& AUART_LINECTRL_BAUD_DIVFRAC_MASK))
+				>> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT;
+	if (quot == 0)
+		quot = 1;
+
+	*baud = (port->uartclk << 2) / quot;
+}
+
+static int __init
+auart_console_setup(struct console *co, char *options)
+{
+	struct mxs_auart_port *s;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+	int ret;
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port))
+		co->index = 0;
+	s = auart_port[co->index];
+	if (!s)
+		return -ENODEV;
+
+	clk_enable(s->clk);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		auart_console_get_options(&s->port, &baud, &parity, &bits);
+
+	ret = uart_set_options(&s->port, co, baud, parity, bits, flow);
+
+	clk_disable(s->clk);
+
+	return ret;
+}
+
+static struct console auart_console = {
+	.name		= "ttyAPP",
+	.write		= auart_console_write,
+	.device		= uart_console_device,
+	.setup		= auart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &auart_driver,
+};
+#endif
+
+static struct uart_driver auart_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "ttyAPP",
+	.dev_name	= "ttyAPP",
+	.major		= 0,
+	.minor		= 0,
+	.nr		= MXS_AUART_PORTS,
+#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
+	.cons =		&auart_console,
+#endif
+};
+
+static int __devinit mxs_auart_probe(struct platform_device *pdev)
+{
+	struct mxs_auart_port *s;
+	u32 version;
+	int ret = 0;
+	struct resource *r;
+
+	s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
+	if (!s) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	s->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(s->clk)) {
+		ret = PTR_ERR(s->clk);
+		goto out_free;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		ret = -ENXIO;
+		goto out_free_clk;
+	}
+
+	s->port.mapbase = r->start;
+	s->port.membase = ioremap(r->start, resource_size(r));
+	s->port.ops = &mxs_auart_ops;
+	s->port.iotype = UPIO_MEM;
+	s->port.line = pdev->id < 0 ? 0 : pdev->id;
+	s->port.fifosize = 16;
+	s->port.uartclk = clk_get_rate(s->clk);
+	s->port.type = PORT_IMX;
+	s->port.dev = s->dev = get_device(&pdev->dev);
+
+	s->flags = 0;
+	s->ctrl = 0;
+
+	s->irq = platform_get_irq(pdev, 0);
+	s->port.irq = s->irq;
+	ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s);
+	if (ret)
+		goto out_free_clk;
+
+	platform_set_drvdata(pdev, s);
+
+	auart_port[pdev->id] = s;
+
+	mxs_auart_reset(&s->port);
+
+	ret = uart_add_one_port(&auart_driver, &s->port);
+	if (ret)
+		goto out_free_irq;
+
+	version = readl(s->port.membase + AUART_VERSION);
+	dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
+	       (version >> 24) & 0xff,
+	       (version >> 16) & 0xff, version & 0xffff);
+
+	return 0;
+
+out_free_irq:
+	auart_port[pdev->id] = NULL;
+	free_irq(s->irq, s);
+out_free_clk:
+	clk_put(s->clk);
+out_free:
+	kfree(s);
+out:
+	return ret;
+}
+
+static int __devexit mxs_auart_remove(struct platform_device *pdev)
+{
+	struct mxs_auart_port *s = platform_get_drvdata(pdev);
+
+	uart_remove_one_port(&auart_driver, &s->port);
+
+	auart_port[pdev->id] = NULL;
+
+	clk_put(s->clk);
+	free_irq(s->irq, s);
+	kfree(s);
+
+	return 0;
+}
+
+static struct platform_driver mxs_auart_driver = {
+	.probe = mxs_auart_probe,
+	.remove = __devexit_p(mxs_auart_remove),
+	.driver = {
+		.name = "mxs-auart",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mxs_auart_init(void)
+{
+	int r;
+
+	r = uart_register_driver(&auart_driver);
+	if (r)
+		goto out;
+
+	r = platform_driver_register(&mxs_auart_driver);
+	if (r)
+		goto out_err;
+
+	return 0;
+out_err:
+	uart_unregister_driver(&auart_driver);
+out:
+	return r;
+}
+
+static void __exit mxs_auart_exit(void)
+{
+	platform_driver_unregister(&mxs_auart_driver);
+	uart_unregister_driver(&auart_driver);
+}
+
+module_init(mxs_auart_init);
+module_exit(mxs_auart_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Freescale MXS application uart driver");
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH v2] Add i.MX23/28 auart support
From: Sascha Hauer @ 2011-01-13 13:14 UTC (permalink / raw)
  To: linux-arm-kernel

This is the second version of these patches. I have reworked the driver to
support the NPCK, BRKINT, PARMRK, IGNPAR, IGNBRK and cflag CREAD flags. I have
tested these flags to the best of my knowledge, but it's sometimes hard to
judge if the behaviour is expected.

Sascha


Sascha Hauer (2):
      serial: Add auart driver for i.MX23/28
      ARM MXS: Add auart platform support for i.MX28

 arch/arm/mach-mxs/clock-mx28.c                  |    5 +
 arch/arm/mach-mxs/devices-mx28.h                |    8 +
 arch/arm/mach-mxs/devices/Kconfig               |    3 +
 arch/arm/mach-mxs/devices/Makefile              |    1 +
 arch/arm/mach-mxs/devices/platform-auart.c      |   54 ++
 arch/arm/mach-mxs/include/mach/devices-common.h |   10 +
 drivers/serial/Kconfig                          |   15 +
 drivers/serial/Makefile                         |    1 +
 drivers/serial/mxs-auart.c                      |  806 +++++++++++++++++++++++
 9 files changed, 903 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-auart.c
 create mode 100644 drivers/serial/mxs-auart.c

^ permalink raw reply

* Possible patch; fix perf Annotation of Thumb code
From: Dr. David Alan Gilbert @ 2011-01-13 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,
  I'm finding that if I annotate an ARM Thumb function with perf that it's
mis-disassembling it; below is a patch that fixes it, but I'm not sure if
it's the best place for the fix.

  The problem is that on Thumb, the bottom bit of the symbol address is
set for thumb functions, and thus perf starts disassembling at address+1,
and since all thumb instructions are 2 bytes aligned to 2 bytes you end
up disassembling across the middle of pairs of instructions.


  The patch removes that bottom bit during symbol loading.

  Questions:
    1) Is this the right place to do it - does some other bit of Perf need the
raw symbol value?  My alternative is to mask it just before the objdump,
but then my worry is if it also needs masking somewhere else.

    2) Should the check be more selective - i.e. only some symbol types?

This is against the Linaro 2.6.37 tree; I'm happy to rebase it against
the clean 2.6.37 if people agree the patch is doing the right thing.

Dave
(For reference this corresponds to this bug 
https://bugs.launchpad.net/linux-linaro/+bug/677547 )

	Signed-off-by: Dr. David Alan Gilbert <david.gilbert@linaro.org>
---
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 439ab94..3d77b5e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1129,6 +1129,11 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 
 		section_name = elf_sec__name(&shdr, secstrs);
 
+		/* On ARM, symbols for thumb functions have 1 added to
+		the symbol address as a flag - remove it */
+		if ((ehdr.e_machine == EM_ARM) && (sym.st_value & 1))
+			sym.st_value-=1;
+
 		if (self->kernel != DSO_TYPE_USER || kmodule) {
 			char dso_name[PATH_MAX];
 

^ permalink raw reply related

* [PATCH] unbreak ehci-mxc on otg port of i.MX27
From: Sergei Shtylyov @ 2011-01-13 12:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294909575-32709-1-git-send-email-eric@eukrea.com>

On 13-01-2011 12:06, Eric B?nard wrote:

> commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support

    Forgot to say that Linus has asked to also specify the commit summary in 
parens after the commit ID.

> for i.MX51 but broke it for (at least) i.MX27 which doesn't have
> a usb_phy1 clock but has a pdev->id 0.

> Signed-off-by: Eric B?nard<eric@eukrea.com>
> Cc: Arnaud Patard<arnaud.patard@rtp-net.org>
> Cc: Sascha Hauer<s.hauer@pengutronix.de>
> ---
>   drivers/usb/host/ehci-mxc.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)

> diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
> index fa59b26..18eb597 100644
> --- a/drivers/usb/host/ehci-mxc.c
> +++ b/drivers/usb/host/ehci-mxc.c
> @@ -178,7 +178,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
>   	}
>
>   	/* "dr" device has its own clock */
> -	if (pdev->id == 0) {
> +	if ((cpu_is_mx51())&  (pdev->id == 0)) {

    And it should be &&, not &.

WBR, Sergei

^ permalink raw reply

* [PATCH] unbreak ehci-mxc on otg port of i.MX27
From: Sergei Shtylyov @ 2011-01-13 12:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294909575-32709-1-git-send-email-eric@eukrea.com>

Hello.

On 13-01-2011 12:06, Eric B?nard wrote:

> commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support
> for i.MX51 but broke it for (at least) i.MX27 which doesn't have
> a usb_phy1 clock but has a pdev->id 0.

> Signed-off-by: Eric B?nard<eric@eukrea.com>
> Cc: Arnaud Patard<arnaud.patard@rtp-net.org>
> Cc: Sascha Hauer<s.hauer@pengutronix.de>
> ---
>   drivers/usb/host/ehci-mxc.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)

> diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
> index fa59b26..18eb597 100644
> --- a/drivers/usb/host/ehci-mxc.c
> +++ b/drivers/usb/host/ehci-mxc.c
> @@ -178,7 +178,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
>   	}
>
>   	/* "dr" device has its own clock */
> -	if (pdev->id == 0) {
> +	if ((cpu_is_mx51()) & (pdev->id == 0)) {

    Why enclose the function call in parens at all? You also don't need parens 
around 'pdev->id == 0'...

WBR, Sergei

^ permalink raw reply

* BUG: spinlock recursion (sys_chdir, user_path_at, do_path_lookup ...)
From: Peter Zijlstra @ 2011-01-13 11:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1101131220240.2678@localhost6.localdomain6>

On Thu, 2011-01-13 at 12:21 +0100, Thomas Gleixner wrote:
> On Thu, 13 Jan 2011, Peter Zijlstra wrote:
> 
> > 
> > > On Wed, 2011-01-12 at 23:52 +0100, Thomas Gleixner wrote:
> > 
> > > > @peterz: Why does lockdep ignore the lock recursion in that
> > > >          spin_lock_nested() call?
> > 
> > So after some hints on IRC on where to look:
> > 
> > <tglx>         spin_lock(&parent->d_lock);
> > <tglx>         spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
> > <tglx> if parent == dentry
> > 
> > That won't yell because you explicitly tell lockdep its ok, I know what
> > I'm doing.
> > 
> > Several lockdep annotations (including this one) allow you to annotate
> > real bugs away, hence you really need to be sure about things when you
> > make them.
> 
> Yeah, I suspected that, but checking whether the pointers are same
> would be nice as it would tell us right away where we fcked up :)
> 

Something like the below would indeed do that, but it makes the
lock_acquire path more expensive, since it will now have to iterate the
held lock stack every time.

(not actually tested)

---
 kernel/lockdep.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 42ba65d..d053d9a 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2740,11 +2740,12 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 {
 	struct task_struct *curr = current;
 	struct lock_class *class = NULL;
-	struct held_lock *hlock;
+	struct held_lock *hlock, *rhlock;
 	unsigned int depth, id;
 	int chain_head = 0;
 	int class_idx;
 	u64 chain_key;
+	int i;
 
 	if (!prove_locking)
 		check = 1;
@@ -2817,6 +2818,21 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
 	hlock->holdtime_stamp = lockstat_clock();
 #endif
 
+	for (i = depth-1; i >= 0; i--) {
+		rhlock = curr->held_locks + i;
+		if (rhlock->instance == lock) {
+			if (debug_locks_off() || debug_locks_silent)
+				return 0;
+			printk("Lock recursion, trying to acquire:\n");
+			print_lock(hlock);
+			printk("while already holding:\n");
+			print_lock(rhlock);
+			printk("which is the same lock instance!\n");
+			dump_stack();
+			return 0;
+		}
+	}
+
 	if (check == 2 && !mark_irqflags(curr, hlock))
 		return 0;
 

^ permalink raw reply related

* [patch 2/2] mx51: add support for pwm
From: Arnaud Patard (Rtp) @ 2011-01-13 11:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113112638.328269873@rtp-net.org>

An embedded and charset-unspecified text was scrubbed...
Name: mx51_pwm.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110113/806de120/attachment.ksh>

^ permalink raw reply

* [patch 1/2] Fix pwm-related build failure
From: Arnaud Patard (Rtp) @ 2011-01-13 11:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113112638.328269873@rtp-net.org>

An embedded and charset-unspecified text was scrubbed...
Name: pwm_ftbfs.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110113/507e1d79/attachment.ksh>

^ permalink raw reply

* [patch 0/2] imx51 pwm support fixes.
From: Arnaud Patard (Rtp) @ 2011-01-13 11:26 UTC (permalink / raw)
  To: linux-arm-kernel


This patchset aims at getting imx51 pwm support into shape. The first patch
fix a build failure when trying to use imx51_add_mxc_pwm() and the other adds
a missing clock and fixes a test to detect which kind of pwm where's using.


Arnaud

^ permalink raw reply

* mmaping a fixed address fails on ARM
From: Russell King - ARM Linux @ 2011-01-13 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTin0jjxLTWzkLHnJ+sGQz=jdDDL94R9o1gh-rO9P@mail.gmail.com>

On Thu, Jan 13, 2011 at 05:58:01AM +0800, Bryan Wu wrote:
> The implementation of arch_get_unmapped_area() is different from ARM
> and x86, that might makes mmap behavior different between ARM and x86.
> Andre said 2.6.28-versatile. I'm not sure whether it is a regression.

For the same conditions (iow, same mapping) on ARMv7 and ARMv5-only
kernels vs x86 the results will be the same.  On ARMv6-supporting kernels
we have aliasing caches to deal with where we intentionally force the
alignment of non-MAP_FIXED mappings.

^ permalink raw reply

* BUG: spinlock recursion (sys_chdir, user_path_at, do_path_lookup ...)
From: Thomas Gleixner @ 2011-01-13 11:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294917467.19601.94.camel@laptop>

On Thu, 13 Jan 2011, Peter Zijlstra wrote:

> 
> > On Wed, 2011-01-12 at 23:52 +0100, Thomas Gleixner wrote:
> 
> > > @peterz: Why does lockdep ignore the lock recursion in that
> > >          spin_lock_nested() call?
> 
> So after some hints on IRC on where to look:
> 
> <tglx>         spin_lock(&parent->d_lock);
> <tglx>         spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
> <tglx> if parent == dentry
> 
> That won't yell because you explicitly tell lockdep its ok, I know what
> I'm doing.
> 
> Several lockdep annotations (including this one) allow you to annotate
> real bugs away, hence you really need to be sure about things when you
> make them.

Yeah, I suspected that, but checking whether the pointers are same
would be nice as it would tell us right away where we fcked up :)

^ permalink raw reply

* [PATCH v5 09/14] OMAP: DMA: Convert DMA library into platform driver
From: G, Manjunath Kondaiah @ 2011-01-13 11:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20101203164317.GB10048@GLPP-machine>

Hi Tony,

On Fri, Dec 3, 2010 at 10:13 PM, G, Manjunath Kondaiah <manjugk@ti.com> wrote:
> Hi Tony,
>
> * Tony Lindgren <tony@atomide.com> [2010-12-02 12:52:19 -0800]:
>
>> * G, Manjunath Kondaiah <manjugk@ti.com> [101202 11:55]:
>> >
>> > >
>> > > Note that even with these three fixes, 5912OSK still fails to
>> > > boot to init. Maybe something wrong with the framebuffer DMA?
>> >
>> > Not sure. I don't have omap1 board for testing. Patch series is only
>> > build tested for omap1.
>> >
>> > Can you pls confirm if OSK5912 boots successfully without this patch
>> > series?
>>
>> Yeah boots just fine without these as always.
>>
>> Anybody care to donate a OSK5912 or similar for the TI guys
>> for doing quick omap1 boot testing on?
>>
>> > If yes, I will cross verify omap1 changes again.
>>
>> Found the problem. INT_DMA_LCD is handled in mach-omap1/lcd_dma.c.
>> In your omap_system_dma_probe we now exit everything if request_irq
>> fails for one channel. So let's skip INT_DMA_LCD.
>>
>> Also, you should check the logic in omap_system_dma_probe as it's
>> not very good handling right now. Note how platform_get_irq_byname
>> does not free other dma_irqs like after request_irq we do.
>
> Fixed error handling cases.
>
>>
>> With your patches applied up to patch "Convert DMA library into
>> platform driver" + my three earlie fixes + the following fix
>> I can now boot OSK5912 and see the penguin on the LCD too.
>
> Thanks a lot. I pulled in all these fixes into the patch series.
>
>>
>> I suggest you break your series into two where the last patch
>> in the first series is "Convert DMA library into platform driver".
>
> I am ok with this approach.
>
>> That way the init related changes are done, and we can merge
>> those in for testing while you update the rest of the series.
>
> cool.
>
> I have done required changes to patch series and tested the same on
> omap2+ boards. Can you pls test OSK5912 board boot from the below
> git repo? If OSK5912 boots up(with LCD), I will post the 1st series to
> LO ML.
>
> git://dev.omapzoom.org/pub/scm/manju/kernel-omap3-dev.git
> Branch: dma_testing
> commit 3047de5b11cc3fef9ea18a7e8d64fec7a9ea7a89
> Author: G, Manjunath Kondaiah <manjugk@ti.com>
> Date: ? Fri Dec 3 20:03:23 2010 +0530
>
> ? ?OMAP: DMA: Convert DMA library into platform driver
>
> ? ?Convert DMA library into DMA platform driver and make use of
> ? ?platform data provided by hwmod data base for OMAP2+ onwards.
>
> ? ?For OMAP1 processors, the DMA driver in mach-omap uses resource
> ? ?structures for getting platform data.
>
> ? ?Thanks to Tony Lindgren <tony@atomide.com> for fixing various
> ? ?omap1 issues and testing the same on OSK5912 board.
>
> ? ?Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
> ? ?Signed-off-by: Tony Lindgren <tony@atomide.com>
> ? ?Cc: Benoit Cousson <b-cousson@ti.com>
> ? ?Cc: Kevin Hilman <khilman@deeprootsystems.com>
> ? ?Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>
>>
>> Also, eventually within next few merge cycles we should have:
>>
>> arch/arm/mach-omap1/dma.c ? ? omap1 specific platform init
>> arch/arm/mach-omap2/dma.c ? ? omap2+ specific platform init
>
> This seems to be ok.
>
>> drivers/dma/omap-dma.c ? ? ? ? ? ? ? ?driver using dmaengine.c
>
> This might require more time.

Since this will take more time, can we have run time pm changes on top
of existing dma hwmod changes?
If so, I can pull out run time pm patch from the dma hwmod series and
resend it again.

-Manjunath

^ permalink raw reply

* BUG: spinlock recursion (sys_chdir, user_path_at, do_path_lookup ...)
From: Peter Zijlstra @ 2011-01-13 11:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294916460.19601.89.camel@laptop>


> On Wed, 2011-01-12 at 23:52 +0100, Thomas Gleixner wrote:

> > @peterz: Why does lockdep ignore the lock recursion in that
> >          spin_lock_nested() call?

So after some hints on IRC on where to look:

<tglx>         spin_lock(&parent->d_lock);
<tglx>         spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
<tglx> if parent == dentry

That won't yell because you explicitly tell lockdep its ok, I know what
I'm doing.

Several lockdep annotations (including this one) allow you to annotate
real bugs away, hence you really need to be sure about things when you
make them.

^ permalink raw reply

* [RFC] Make SMP secondary CPU up more resilient to failure.
From: Russell King - ARM Linux @ 2011-01-13 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTimLcGEDrexVCyMROYA1x_GsXdpx_6_ziYWVipMp@mail.gmail.com>

On Thu, Jan 13, 2011 at 04:19:40AM -0600, Andrei Warkentin wrote:
> I fully agree. Would you be interested in me bringing back the actual
> synchronization code from platform-dependent code into the preinit
> function and posting that as a patch for review?

I really don't like the idea of a preinit function - it's completely
unnecessary as I've been trying to point out.  It has been shown that
it takes a hundred or so microseconds to get into the kernel, and
then a couple of hundred milliseconds to run the delay loop.

As platforms are expected to wait in their boot_secondary() for the
first half - currently platforms wait one second - we're talking
about around a hundred microseconds vs a timeout of one second.
That's a factor of 10000 beyond what's required.

It has also been shown that the problem you were seeing was down to
synchronization/delayed write bugs which have since been solved - and
adding yet more synchronization is not the answer to buggy
synchronization.

So, as the timeouts are already well in excess and the root cause of
your problem has been resolved, I see no need to make this stuff more
complex - the more complexity there is, the more chance there is of
things going wrong.

^ permalink raw reply

* [PATCH] ARM: SMDK6410: Update regulator names for debugfs compatiblity
From: Mark Brown @ 2011-01-13 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

The debugfs support added to the regulator API (which will be merged
in during this merge window) creates directories for regulators named
after the display names for the regulators so replace / as a separator
for multiple supplies with + in the SMDK6410 machine.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 arch/arm/mach-s3c64xx/mach-smdk6410.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 19f9d3f..c8a84be 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -352,7 +352,7 @@ static __initdata struct regulator_init_data smdk6410_vddpll = {
 /* VDD_UH_MMC, LDO5 on J5 */
 static __initdata struct regulator_init_data smdk6410_vdduh_mmc = {
 	.constraints = {
-		.name = "PVDD_UH/PVDD_MMC",
+		.name = "PVDD_UH+PVDD_MMC",
 		.always_on = 1,
 	},
 };
@@ -418,7 +418,7 @@ static __initdata struct regulator_init_data smdk6410_vddaudio = {
 /* S3C64xx internal logic & PLL */
 static __initdata struct regulator_init_data wm8350_dcdc1_data = {
 	.constraints = {
-		.name = "PVDD_INT/PVDD_PLL",
+		.name = "PVDD_INT+PVDD_PLL",
 		.min_uV = 1200000,
 		.max_uV = 1200000,
 		.always_on = 1,
@@ -453,7 +453,7 @@ static __initdata struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
 
 static __initdata struct regulator_init_data wm8350_dcdc4_data = {
 	.constraints = {
-		.name = "PVDD_HI/PVDD_EXT/PVDD_SYS/PVCCM2MTV",
+		.name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV",
 		.min_uV = 3000000,
 		.max_uV = 3000000,
 		.always_on = 1,
@@ -465,7 +465,7 @@ static __initdata struct regulator_init_data wm8350_dcdc4_data = {
 /* OTGi/1190-EV1 HPVDD & AVDD */
 static __initdata struct regulator_init_data wm8350_ldo4_data = {
 	.constraints = {
-		.name = "PVDD_OTGI/HPVDD/AVDD",
+		.name = "PVDD_OTGI+HPVDD+AVDD",
 		.min_uV = 1200000,
 		.max_uV = 1200000,
 		.apply_uV = 1,
@@ -556,7 +556,7 @@ static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
 
 static struct regulator_init_data wm1192_dcdc3 = {
 	.constraints = {
-		.name = "PVDD_MEM/PVDD_GPS",
+		.name = "PVDD_MEM+PVDD_GPS",
 		.always_on = 1,
 	},
 };
@@ -567,7 +567,7 @@ static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
 
 static struct regulator_init_data wm1192_ldo1 = {
 	.constraints = {
-		.name = "PVDD_LCD/PVDD_EXT",
+		.name = "PVDD_LCD+PVDD_EXT",
 		.always_on = 1,
 	},
 	.consumer_supplies = wm1192_ldo1_consumers,
-- 
1.7.2.3

^ permalink raw reply related

* i.MX & IRQF_ONESHOT
From: Nicolas Ferre @ 2011-01-13 11:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110113091355.GP24920@pengutronix.de>

Le 13/01/2011 10:13, Uwe Kleine-K?nig :
> <jason77.wang@gmail.com>
> Bcc: 
> Subject: Re: i.MX & IRQF_ONESHOT
> Reply-To: 
> In-Reply-To: <4D2EB6EF.7030608@eukrea.com>
> 
> Hello,
> 
> [adding tglx who AFAIK invented threaded irqs and the people involved
> in 2991a1ca6e9b to Cc]
> 
> On Thu, Jan 13, 2011 at 09:25:19AM +0100, Eric B?nard wrote:
>> while testing 2.6.37 on our i.MX27 based board - code in
>> arch/arm/mach-imx/eukrea_mbimx27-baseboard.c - I noticed the
>> touchscreen controller (ADS7846) doesn't work anymore.
>>
>> A few IRQ are generated when probing for the chipset and starting
>> calibration (usually first point works), then nothing more (even if
>> the IRQ signals is generated as seen on the scope, the irq count
>> doesn't increase anymore and stays <= 4 and no data is reported to
>> the input layer).
>>
>> drivers/input/touchscreen/ads7846.c was switched to threaded IRQ in
>> commit 2991a1ca6e9b13b639a82c0eec0cbc191bf1f42f where was added :
>> irq_flags |= IRQF_ONESHOT;
> AFAIK this is how threaded irq usually work.  The irq should get
> reenabled by irq_thread -> irq_finalize_oneshot then.
> 
>> Commenting out this line in the ads7846 driver makes it work again.
>> Am I missing something obvious or is there a reason for IRQF_ONESHOT
>> creating trouble with gpio irq or SPI on i.MX ?
> I don't know.  Is the irq masked?  pending?

Just to let you know that I have the same issue on my at91sam9g10ek:
atmel_spi + ads7846 (using ADS7843e actually).
... solved by same workaround.

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply

* BUG: spinlock recursion (sys_chdir, user_path_at, do_path_lookup ...)
From: Peter Zijlstra @ 2011-01-13 11:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1101122344500.2678@localhost6.localdomain6>

On Wed, 2011-01-12 at 23:52 +0100, Thomas Gleixner wrote:
> On Wed, 12 Jan 2011, Uwe Kleine-K?nig wrote:
> > > Reverting: fs: rcu-walk aware d_revalidate method
> > > commit: 34286d6662308d82aed891852d04c7c3a2649b16
> > I found that one, too, in the meantime.  Currently debugging that with
> > tglx on irc.
> 
> The last finding is that parent and dentry in
> nameidata_dentry_drop_rcu() are the same, which explains the lock
> recursion nicely. 
> 
> @nick: Anything you want us to add to the debugging ?
> 
> @peterz: Why does lockdep ignore the lock recursion in that
>          spin_lock_nested() call?

$ git show 34286d6662308d82aed891852d04c7c3a2649b16 | grep spin_lock_nested | wc -l
0

Uhm, whot?!

^ permalink raw reply

* [PATCH] unbreak ehci-mxc on otg port of i.MX27
From: Arnaud Patard (Rtp) @ 2011-01-13 10:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1294909575-32709-1-git-send-email-eric@eukrea.com>

Eric B?nard <eric@eukrea.com> writes:

> commit 711669e5b80b6f2d88f61ed8a9681f83d8cbd201 fixed port 0 support
> for i.MX51 but broke it for (at least) i.MX27 which doesn't have
> a usb_phy1 clock but has a pdev->id 0.

ouch. Sorry for this. I didn't thought that imx51 was an exception
rather than the rule. Also, I think that imx53 may deserve same
treatment but I've neither a  imx53 nor its datasheet at hand to check
that.

thanks,
Arnaud

^ permalink raw reply

* [RFC] Make SMP secondary CPU up more resilient to failure.
From: Andrei Warkentin @ 2011-01-13 10:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20101224173824.GI20587@n2100.arm.linux.org.uk>

On Fri, Dec 24, 2010 at 11:38 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
>
> On Tue, Dec 21, 2010 at 03:53:46PM -0600, Andrei Warkentin wrote:
> > Russel,
>
> Grr.
>
> > Thank you! The culprit looks as it seems to be the writel without
> > __iowmb, as you pointed out. At the very least I've yet to hit the
> > problem again this way.
>
> Good news.
>
> > I still want to add code inside the platform SMP support as a safety
> > net. Maybe I am being too pedantic, but ?In the near future (with
> > those 40 patches), secondaries are going to boot directly via
> > secondary_startup as well, so the first time platform-specific code
> > gets invoked is platform_secondary_init. I want to ensure that when
> > boot_secondary returns, the CPU is either guaranteed to be running or
> > for-sure dead. The problem is that platform_secondary_init is already
> > too late - if the CPU gets killed due to timeout anytime between the
> > entry to secondary_start_kernel and ?platform_secondary_init, it could
> > have already increased the refcount on init_mm or disabled preemption.
>
> Here's a problem for you to ponder on over Christmas.
>
> Let's say the secondary CPU is running slowly due to system load. ?It
> makes it through to secondary_start_kernel(), and calls through to
> your preinit function. ?It checks that it should be booting, and
> passes that test.
>
> At this point, the requesting CPU times out, but gets preempted to
> other tasks (which could very well happen on a heavily loaded system
> with preempt enabled).
>
> The booting CPU signals that via writing the reset vector, and continues
> on to increment the mm_count and switch its page tables.

My goal was for the preinit to run explicitely before the mm_count is
incremented. The cpu
sits (spins) inside the preinit until it is either told to continue
with the init (thus the synchronized CPU knows it succeeded), or it
sits there spinning inside the preinit until it gets killed due to a
timeout. Since I think the "side effects" only start after the
mm_count is incremented, I thought right before would be a good place.

>
> The requesting CPU finally switches back to the thread requesting
> that the CPU be brought up. ?It decides as it timed out to kill the
> booting CPU, and does so.

I should have made this clearer in my email when I said 'synchronize',
but if the timeout ever occurs it means two things -
1) CPU is dead or someplace before secondary_start_kernel
2) CPU is about to enter/entering preinit
3) CPU is already spinning inside preinit waiting to be allowed to
continue. It hasn't incremented mm_count, switched pts, or done
anything else that affects global kernel state.

In either case, it can be torn down (by say, fiddling with the power/reset).

If the timeout doesn't occur, then the requesting cpu will allow the
secondary to quit spinning inside the preinit.

>
> What this means that we now have exactly the same scenario you've
> referred to above, and adding the pre-init function hasn't really
> solved anything.
>
> I _really_ don't want platforms to start playing these games, because
> we'll end up with lots of different attempts to solve the problem,
> each of them probably racy like the above. ?The safest solution is to
> use a longer timeout - maybe an excessively long timeout - to guarantee
> that we never miss a starting CPU.
>
> If we do end up needing something like this in the kernel, then it needs
> to be done carefully and in generic code where it can be done properly
> once. ?(If any bugs are found in it, we've also only one version to fix,
> not five or six different versions.)

I fully agree. Would you be interested in me bringing back the actual
synchronization code from platform-dependent code into the preinit
function and posting that as a patch for review?

?However, I'd argue that it's better
> to wait longer for the CPU to come up if there's a possibility that it
> will rather than trying to sort out the mess from a partially booted
> secondary CPU.

Fair enough, I suppose that does make any platform bugs in smp path
more immediately obvious :)

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox