Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] amba: move to pm ops
From: Rabin Vincent @ 2011-02-17  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

Support pm_ops in the AMBA bus instead of the legacy ops.   pm_ops is needed
for runtime pm, and there is also a general move to convert drivers to
dev_pm_ops rather than bus specific PM ops in order to facilitate core
development.

Since there are only 6 AMBA drivers using suspend/resume, convert them all in
one go and directly use the GENERIC_SUBSYS_PM_OPS in the bus.

Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
 drivers/amba/bus.c              |   25 ++-----------------------
 drivers/input/serio/ambakmi.c   |   13 ++++++++++---
 drivers/mmc/host/mmci.c         |   17 ++++++++++-------
 drivers/spi/amba-pl022.c        |   15 +++++++++------
 drivers/tty/serial/amba-pl010.c |   20 ++++++++++++++------
 drivers/tty/serial/amba-pl011.c |   22 +++++++++++++---------
 include/linux/amba/bus.h        |    4 ++--
 sound/arm/aaci.c                |   18 ++++++++++--------
 8 files changed, 70 insertions(+), 64 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ca96b0a..402b07e 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -13,12 +13,12 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/pm.h>
 #include <linux/amba/bus.h>
 
 #include <asm/irq.h>
 #include <asm/sizes.h>
 
-#define to_amba_device(d)	container_of(d, struct amba_device, dev)
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
 static struct amba_id *
@@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
 #define amba_uevent NULL
 #endif
 
-static int amba_suspend(struct device *dev, pm_message_t state)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->suspend)
-		ret = drv->suspend(to_amba_device(dev), state);
-	return ret;
-}
-
-static int amba_resume(struct device *dev)
-{
-	struct amba_driver *drv = to_amba_driver(dev->driver);
-	int ret = 0;
-
-	if (dev->driver && drv->resume)
-		ret = drv->resume(to_amba_device(dev));
-	return ret;
-}
-
 #define amba_attr_func(name,fmt,arg...)					\
 static ssize_t name##_show(struct device *_dev,				\
 			   struct device_attribute *attr, char *buf)	\
@@ -111,8 +91,7 @@ struct bus_type amba_bustype = {
 	.dev_attrs	= amba_dev_attrs,
 	.match		= amba_match,
 	.uevent		= amba_uevent,
-	.suspend	= amba_suspend,
-	.resume		= amba_resume,
+	.pm		= GENERIC_SUBSYS_PM_OPS,
 };
 
 static int __init amba_init(void)
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 92563a6..c710437 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -176,15 +176,22 @@ static int __devexit amba_kmi_remove(struct amba_device *dev)
 	return 0;
 }
 
-static int amba_kmi_resume(struct amba_device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int amba_kmi_resume(struct device *dev)
 {
-	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct amba_kmi_port *kmi = amba_get_drvdata(adev);
 
 	/* kick the serio layer to rescan this port */
 	serio_reconnect(kmi->io);
 
 	return 0;
 }
+#else
+#define amba_kmi_resume	NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(amba_kmi_pm, NULL, amba_kmi_resume);
 
 static struct amba_id amba_kmi_idtable[] = {
 	{
@@ -198,11 +205,11 @@ static struct amba_driver ambakmi_driver = {
 	.drv		= {
 		.name	= "kmi-pl050",
 		.owner	= THIS_MODULE,
+		.pm	= &amba_kmi_pm,
 	},
 	.id_table	= amba_kmi_idtable,
 	.probe		= amba_kmi_probe,
 	.remove		= __devexit_p(amba_kmi_remove),
-	.resume		= amba_kmi_resume,
 };
 
 static int __init amba_kmi_init(void)
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 8a29c9f..18e142b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1236,10 +1236,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int mmci_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int mmci_suspend(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
@@ -1253,9 +1254,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state)
 	return ret;
 }
 
-static int mmci_resume(struct amba_device *dev)
+static int mmci_resume(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
@@ -1273,6 +1275,8 @@ static int mmci_resume(struct amba_device *dev)
 #define mmci_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(mmci_pm, mmci_suspend, mmci_resume);
+
 static struct amba_id mmci_ids[] = {
 	{
 		.id	= 0x00041180,
@@ -1306,11 +1310,10 @@ static struct amba_id mmci_ids[] = {
 static struct amba_driver mmci_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
+		.pm	= &mmci_pm,
 	},
 	.probe		= mmci_probe,
 	.remove		= __devexit_p(mmci_remove),
-	.suspend	= mmci_suspend,
-	.resume		= mmci_resume,
 	.id_table	= mmci_ids,
 };
 
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 71a1219..eb16ea5 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -2184,9 +2184,10 @@ pl022_remove(struct amba_device *adev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int pl022_suspend(struct amba_device *adev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl022_suspend(struct device *dev)
 {
+	struct amba_device *adev = to_amba_device(dev);
 	struct pl022 *pl022 = amba_get_drvdata(adev);
 	int status = 0;
 
@@ -2203,8 +2204,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state)
 	return 0;
 }
 
-static int pl022_resume(struct amba_device *adev)
+static int pl022_resume(struct device *dev)
 {
+	struct amba_device *adev = to_amba_device(dev);
 	struct pl022 *pl022 = amba_get_drvdata(adev);
 	int status = 0;
 
@@ -2220,7 +2222,9 @@ static int pl022_resume(struct amba_device *adev)
 #else
 #define pl022_suspend NULL
 #define pl022_resume NULL
-#endif	/* CONFIG_PM */
+#endif
+
+static SIMPLE_DEV_PM_OPS(pl022_pm, pl022_suspend, pl022_resume);
 
 static struct vendor_data vendor_arm = {
 	.fifodepth = 8,
@@ -2284,12 +2288,11 @@ static struct amba_id pl022_ids[] = {
 static struct amba_driver pl022_driver = {
 	.drv = {
 		.name	= "ssp-pl022",
+		.pm	= &pl022_pm,
 	},
 	.id_table	= pl022_ids,
 	.probe		= pl022_probe,
 	.remove		= __devexit_p(pl022_remove),
-	.suspend        = pl022_suspend,
-	.resume         = pl022_resume,
 };
 
 
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c
index 2904aa0..5e0e62f 100644
--- a/drivers/tty/serial/amba-pl010.c
+++ b/drivers/tty/serial/amba-pl010.c
@@ -757,9 +757,11 @@ static int pl010_remove(struct amba_device *dev)
 	return 0;
 }
 
-static int pl010_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl010_suspend(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (uap)
 		uart_suspend_port(&amba_reg, &uap->port);
@@ -767,15 +769,22 @@ static int pl010_suspend(struct amba_device *dev, pm_message_t state)
 	return 0;
 }
 
-static int pl010_resume(struct amba_device *dev)
+static int pl010_resume(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (uap)
 		uart_resume_port(&amba_reg, &uap->port);
 
 	return 0;
 }
+#else
+#define pl010_suspend	NULL
+#define pl010_resume	NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(pl010_pm, pl010_suspend, pl010_resume);
 
 static struct amba_id pl010_ids[] = {
 	{
@@ -788,12 +797,11 @@ static struct amba_id pl010_ids[] = {
 static struct amba_driver pl010_driver = {
 	.drv = {
 		.name	= "uart-pl010",
+		.pm	= &pl010_pm,
 	},
 	.id_table	= pl010_ids,
 	.probe		= pl010_probe,
 	.remove		= pl010_remove,
-	.suspend	= pl010_suspend,
-	.resume		= pl010_resume,
 };
 
 static int __init pl010_init(void)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index e76d7d0..52a5e18 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1438,10 +1438,11 @@ static int pl011_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int pl011_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pl011_suspend(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (!uap)
 		return -EINVAL;
@@ -1449,17 +1450,23 @@ static int pl011_suspend(struct amba_device *dev, pm_message_t state)
 	return uart_suspend_port(&amba_reg, &uap->port);
 }
 
-static int pl011_resume(struct amba_device *dev)
+static int pl011_resume(struct device *dev)
 {
-	struct uart_amba_port *uap = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(adev);
 
 	if (!uap)
 		return -EINVAL;
 
 	return uart_resume_port(&amba_reg, &uap->port);
 }
+#else
+#define pl011_suspend	NULL
+#define pl011_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(pl011_pm, pl011_suspend, pl011_resume);
+
 static struct amba_id pl011_ids[] = {
 	{
 		.id	= 0x00041011,
@@ -1477,14 +1484,11 @@ static struct amba_id pl011_ids[] = {
 static struct amba_driver pl011_driver = {
 	.drv = {
 		.name	= "uart-pl011",
+		.pm	= &pl011_pm,
 	},
 	.id_table	= pl011_ids,
 	.probe		= pl011_probe,
 	.remove		= pl011_remove,
-#ifdef CONFIG_PM
-	.suspend	= pl011_suspend,
-	.resume		= pl011_resume,
-#endif
 };
 
 static int __init pl011_init(void)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index a0ccf28..2f48827 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -46,8 +46,6 @@ struct amba_driver {
 	int			(*probe)(struct amba_device *, struct amba_id *);
 	int			(*remove)(struct amba_device *);
 	void			(*shutdown)(struct amba_device *);
-	int			(*suspend)(struct amba_device *, pm_message_t);
-	int			(*resume)(struct amba_device *);
 	struct amba_id		*id_table;
 };
 
@@ -58,6 +56,8 @@ enum amba_vendor {
 
 extern struct bus_type amba_bustype;
 
+#define to_amba_device(d)	container_of(d, struct amba_device, dev)
+
 #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
 #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
 
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index af5a152..040c5f0 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -35,7 +35,7 @@
 /*
  * PM support is not complete.  Turn it off.
  */
-#undef CONFIG_PM
+#undef CONFIG_PM_SLEEP
 
 static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
 {
@@ -752,7 +752,7 @@ static struct snd_pcm_ops aaci_capture_ops = {
 /*
  * Power Management.
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int aaci_do_suspend(struct snd_card *card, unsigned int state)
 {
 	struct aaci *aaci = card->private_data;
@@ -767,15 +767,17 @@ static int aaci_do_resume(struct snd_card *card, unsigned int state)
 	return 0;
 }
 
-static int aaci_suspend(struct amba_device *dev, pm_message_t state)
+static int aaci_suspend(struct device *dev)
 {
-	struct snd_card *card = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct snd_card *card = amba_get_drvdata(adev);
 	return card ? aaci_do_suspend(card) : 0;
 }
 
-static int aaci_resume(struct amba_device *dev)
+static int aaci_resume(struct device *dev)
 {
-	struct snd_card *card = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct snd_card *card = amba_get_drvdata(adev);
 	return card ? aaci_do_resume(card) : 0;
 }
 #else
@@ -785,6 +787,7 @@ static int aaci_resume(struct amba_device *dev)
 #define aaci_resume		NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(aaci_pm, aaci_suspend, aaci_resume);
 
 static struct ac97_pcm ac97_defs[] __devinitdata = {
 	[0] = {	/* Front PCM */
@@ -1099,11 +1102,10 @@ static struct amba_id aaci_ids[] = {
 static struct amba_driver aaci_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
+		.pm	= &aaci_pm,
 	},
 	.probe		= aaci_probe,
 	.remove		= __devexit_p(aaci_remove),
-	.suspend	= aaci_suspend,
-	.resume		= aaci_resume,
 	.id_table	= aaci_ids,
 };
 
-- 
1.7.2.dirty

^ permalink raw reply related

* [PATCH 1/2] omap4: 4430sdp: drop ehci support
From: Felipe Balbi @ 2011-02-17  7:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297855040-1337-1-git-send-email-gadiyar@ti.com>

On Wed, Feb 16, 2011 at 04:47:19PM +0530, Anand Gadiyar wrote:
> Most revisions of the OMAP4 Blaze/SDP platform do not have
> the EHCI signals routed by default. The pads are routed
> for the alternate HSI functionality instead, and explicit
> board modifications are needed to route the signals to
> the USB PHY on the board.
> 
> Also, turning on the PHY connected to the EHCI port causes
> a board reboot during bootup due to an unintended short
> on the rails - this affects many initial revisions of the
> board, and needs a minor board mod to fix (or as a
> workaround, one should not attempt to power on the
> USB PHY).
> 
> Given that these boards need explicit board mods to even
> get EHCI working (separate from the accidental short above),
> we should not attempt to enable EHCI by default.
> 
> So drop the EHCI support from the board files for the
> Blaze/SDP platforms.
> 
> Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
> Cc: Keshava Munegowda <keshava_mgowda@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>

applied, thanks.

-- 
balbi

^ permalink raw reply

* [PATCH 1/2] omap4: 4430sdp: drop ehci support
From: Felipe Balbi @ 2011-02-17  7:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110217014210.GL20795@atomide.com>

On Wed, Feb 16, 2011 at 05:42:10PM -0800, Tony Lindgren wrote:
> * Felipe Balbi <balbi@ti.com> [110216 03:25]:
> > On Wed, Feb 16, 2011 at 04:47:19PM +0530, Anand Gadiyar wrote:
> > > Most revisions of the OMAP4 Blaze/SDP platform do not have
> > > the EHCI signals routed by default. The pads are routed
> > > for the alternate HSI functionality instead, and explicit
> > > board modifications are needed to route the signals to
> > > the USB PHY on the board.
> > > 
> > > Also, turning on the PHY connected to the EHCI port causes
> > > a board reboot during bootup due to an unintended short
> > > on the rails - this affects many initial revisions of the
> > > board, and needs a minor board mod to fix (or as a
> > > workaround, one should not attempt to power on the
> > > USB PHY).
> > > 
> > > Given that these boards need explicit board mods to even
> > > get EHCI working (separate from the accidental short above),
> > > we should not attempt to enable EHCI by default.
> > > 
> > > So drop the EHCI support from the board files for the
> > > Blaze/SDP platforms.
> > > 
> > > Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
> > > Cc: Keshava Munegowda <keshava_mgowda@ti.com>
> > > Cc: Tony Lindgren <tony@atomide.com>
> > 
> > Tony, if you want to queue this one directly, here's my:
> > 
> > Acked-by: Felipe Balbi <balbi@ti.com>
> > 
> > if you wish, I can send you a pull request as well. I already have
> > another patch for you anyway.
> 
> OK if you have more I'd rather pull.

ok. Taken.

-- 
balbi

^ permalink raw reply

* [PATCH 2/2] ARM: PXA: PXAFB: fix plane Z-ordering problem
From: Vasily Khoruzhick @ 2011-02-17  7:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297928588-10545-1-git-send-email-anarsoul@gmail.com>

pxafb_overlay_init is not right place to change Z-ordering,
move it to main plane initialization.

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
 drivers/video/pxafb.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index c6aad56..590a99a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -942,8 +942,6 @@ static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
 	/* mask all IU/BS/EOF/SOF interrupts */
 	lcd_writel(fbi, LCCR5, ~0);
 
-	/* place overlay(s) on top of base */
-	fbi->lccr0 |= LCCR0_OUC;
 	pr_info("PXA Overlay driver loaded successfully!\n");
 	return 0;
 }
@@ -1827,6 +1825,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
 
 	pxafb_decode_mach_info(fbi, inf);
 
+#ifdef CONFIG_FB_PXA_OVERLAY
+	/* place overlay(s) on top of base */
+	if (pxafb_overlay_supported())
+		fbi->lccr0 |= LCCR0_OUC;
+#endif
+
 	init_waitqueue_head(&fbi->ctrlr_wait);
 	INIT_WORK(&fbi->task, pxafb_task);
 	mutex_init(&fbi->ctrlr_lock);
-- 
1.7.4

^ permalink raw reply related

* [PATCH 1/2] ARM: PXA: PXAFB: Fix double-free issue.
From: Vasily Khoruzhick @ 2011-02-17  7:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201102151718.00800.anarsoul@gmail.com>

From: Russell King - ARM Linux <linux@arm.linux.org.uk>

From: Russell King - ARM Linux <linux@arm.linux.org.uk>

Release callback tries to free memory even if it was not allocated in
map_video_memory, fix it.

Added by Vasily Khoruzhick:

- Clear x_res/y_res fields of fb.var on release, to make sure
our callback will be called on next FBIOPUT_VSCREENINFO ioctl.
- Disable overlay only if it was enabled.

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
 drivers/video/pxafb.c |   55 +++++++++++++++++++++++++++++++++---------------
 drivers/video/pxafb.h |    2 +-
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 825b665..c6aad56 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -629,6 +629,9 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
 {
 	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
+	if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
+		return;
+
 	lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
 
 	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(1));
@@ -636,7 +639,8 @@ static void overlay1fb_disable(struct pxafb_layer *ofb)
 	lcd_writel(ofb->fbi, FBR1, ofb->fbi->fdadr[DMA_OV1] | 0x3);
 
 	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
-		pr_warning("%s: timeout disabling overlay1\n", __func__);
+		pr_warning("%s: timeout disabling overlay1\n",
+			__func__);
 
 	lcd_writel(ofb->fbi, LCCR5, lccr5);
 }
@@ -687,6 +691,9 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
 {
 	uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
+	if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
+		return;
+
 	lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
 
 	lcd_writel(ofb->fbi, LCSR1, LCSR1_BS(2));
@@ -696,7 +703,8 @@ static void overlay2fb_disable(struct pxafb_layer *ofb)
 	lcd_writel(ofb->fbi, FBR4, ofb->fbi->fdadr[DMA_OV2_Cr] | 0x3);
 
 	if (wait_for_completion_timeout(&ofb->branch_done, 1 * HZ) == 0)
-		pr_warning("%s: timeout disabling overlay2\n", __func__);
+		pr_warning("%s: timeout disabling overlay2\n",
+			__func__);
 }
 
 static struct pxafb_layer_ops ofb_ops[] = {
@@ -720,12 +728,10 @@ static int overlayfb_open(struct fb_info *info, int user)
 	if (user == 0)
 		return -ENODEV;
 
-	/* allow only one user at a time */
-	if (atomic_inc_and_test(&ofb->usage))
-		return -EBUSY;
+	if (ofb->usage++ == 0)
+		/* unblank the base framebuffer */
+		fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
 
-	/* unblank the base framebuffer */
-	fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
 	return 0;
 }
 
@@ -733,12 +739,24 @@ static int overlayfb_release(struct fb_info *info, int user)
 {
 	struct pxafb_layer *ofb = (struct pxafb_layer*) info;
 
-	atomic_dec(&ofb->usage);
-	ofb->ops->disable(ofb);
-
-	free_pages_exact(ofb->video_mem, ofb->video_mem_size);
-	ofb->video_mem = NULL;
-	ofb->video_mem_size = 0;
+	if (--ofb->usage == 0) {
+		ofb->ops->disable(ofb);
+		ofb->fb.var.height	= -1;
+		ofb->fb.var.width	= -1;
+		ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
+		ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
+
+		mutex_lock(&ofb->fb.mm_lock);
+		ofb->fb.fix.smem_start	= 0;
+		ofb->fb.fix.smem_len	= 0;
+		mutex_unlock(&ofb->fb.mm_lock);
+
+		if (ofb->video_mem) {
+			free_pages_exact(ofb->video_mem, ofb->video_mem_size);
+			ofb->video_mem = NULL;
+			ofb->video_mem_size = 0;
+		}
+	}
 	return 0;
 }
 
@@ -817,7 +835,8 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
 		if (ofb->video_mem_size >= size)
 			return 0;
 
-		free_pages_exact(ofb->video_mem, ofb->video_mem_size);
+		/* don't re-allocate: userspace may have the buffer mapped */
+		return -EINVAL;
 	}
 
 	ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
@@ -891,7 +910,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
 
 	ofb->id = id;
 	ofb->ops = &ofb_ops[id];
-	atomic_set(&ofb->usage, 0);
+	ofb->usage = 0;
 	ofb->fbi = fbi;
 	init_completion(&ofb->branch_done);
 }
@@ -1368,7 +1387,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
 	    (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
 	    (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
 	    (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
-	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
+	    ((fbi->lccr0 & LCCR0_SDS) &&
+	    (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
 		pxafb_schedule_work(fbi, C_REENABLE);
 
 	return 0;
@@ -1420,7 +1440,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
 
 	lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
-	lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
+	if (fbi->lccr0 & LCCR0_SDS)
+		lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
 	lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
 }
 
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 2353521..84e3ae1 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -92,7 +92,7 @@ struct pxafb_layer_ops {
 struct pxafb_layer {
 	struct fb_info		fb;
 	int			id;
-	atomic_t		usage;
+	uint32_t		usage;
 	uint32_t		control[2];
 
 	struct pxafb_layer_ops	*ops;
-- 
1.7.4

^ permalink raw reply related

* [PATCH 5/5] ARM: S5PC210: add a placeholder for board specific interrupts
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297927527-1338-1-git-send-email-m.szyprowski@samsung.com>

This patch adds a placeholder for board specific interrupts on S5PC210
platform.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv310/include/mach/irqs.h |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 64dbe15..a28de22 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -148,7 +148,11 @@
 #define IRQ_GPIO2_NR_GROUPS	9
 #define IRQ_GPIO_END		(S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
 
+/* optional board specific irqs */
+#define IRQ_BOARD_START		IRQ_GPIO_END
+#define IRQ_NR_BOARD		16
+
 /* Set the default NR_IRQS */
-#define NR_IRQS			(IRQ_GPIO_END)
+#define NR_IRQS			(IRQ_GPIO_END + IRQ_NR_BOARD)
 
 #endif /* __ASM_ARCH_IRQS_H */
-- 
1.7.1.569.g6f426

^ permalink raw reply related

* [PATCH 4/5] ARM: S5PC210: add support for gpio interrupts
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297927527-1338-1-git-send-email-m.szyprowski@samsung.com>

This patch adds support for gpio interrupts on Samsung S5PC210 platform.
Common s5p-gpioint.c code is used for handling gpio interrupts. Each gpio
line that needs gpio interrupt support must be later registered with
s5p_register_gpio_interrupt() function.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv310/gpiolib.c           |   18 +++++++++++++++---
 arch/arm/mach-s5pv310/include/mach/irqs.h |   12 ++++++++++--
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
index f417ecd..288f672 100644
--- a/arch/arm/mach-s5pv310/gpiolib.c
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -304,6 +304,7 @@ static __init int s5pv310_gpiolib_init(void)
 {
 	struct s3c_gpio_chip *chip;
 	int i;
+	int group = 0;
 	int nr_chips;
 
 	/* GPIO part 1 */
@@ -312,8 +313,11 @@ static __init int s5pv310_gpiolib_init(void)
 	nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
 
 	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL)
+		if (chip->config == NULL) {
 			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
 		if (chip->base == NULL)
 			chip->base = S5P_VA_GPIO1 + (i) * 0x20;
 	}
@@ -326,8 +330,11 @@ static __init int s5pv310_gpiolib_init(void)
 	nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
 
 	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL)
+		if (chip->config == NULL) {
 			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
 		if (chip->base == NULL)
 			chip->base = S5P_VA_GPIO2 + (i) * 0x20;
 	}
@@ -340,13 +347,18 @@ static __init int s5pv310_gpiolib_init(void)
 	nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
 
 	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL)
+		if (chip->config == NULL) {
 			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
 		if (chip->base == NULL)
 			chip->base = S5P_VA_GPIO3 + (i) * 0x20;
 	}
 
 	samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
+	s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 536b0b5..64dbe15 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -85,6 +85,9 @@
 #define IRQ_RTC_ALARM		COMBINER_IRQ(23, 0)
 #define IRQ_RTC_TIC		COMBINER_IRQ(23, 1)
 
+#define IRQ_GPIO_XB		COMBINER_IRQ(24, 0)
+#define IRQ_GPIO_XA		COMBINER_IRQ(24, 1)
+
 #define IRQ_UART0		COMBINER_IRQ(26, 0)
 #define IRQ_UART1		COMBINER_IRQ(26, 1)
 #define IRQ_UART2		COMBINER_IRQ(26, 2)
@@ -139,8 +142,13 @@
 #define S5P_EINT_BASE1		(S5P_IRQ_EINT_BASE + 0)
 #define S5P_EINT_BASE2		(S5P_IRQ_EINT_BASE + 16)
 
-/* Set the default NR_IRQS */
+/* optional GPIO interrupts */
+#define S5P_GPIOINT_BASE	(S5P_IRQ_EINT_BASE + 32)
+#define IRQ_GPIO1_NR_GROUPS	16
+#define IRQ_GPIO2_NR_GROUPS	9
+#define IRQ_GPIO_END		(S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
 
-#define NR_IRQS			(S5P_IRQ_EINT_BASE + 32)
+/* Set the default NR_IRQS */
+#define NR_IRQS			(IRQ_GPIO_END)
 
 #endif /* __ASM_ARCH_IRQS_H */
-- 
1.7.1.569.g6f426

^ permalink raw reply related

* [PATCH 3/5] ARM: Samsung: add function to register gpio interrupt bank data
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297927527-1338-1-git-send-email-m.szyprowski@samsung.com>

This patch removes all global data from common s5p gpio interrupt
handler code. This enables to reuse this code on S5PC210 platform.
Instead of global data (IRQ_GPIOINT interrupt number,
S5P_GPIOINT_GROUP_MAXNR groups count), a s5p_register_gpioint_bank()
function is introduced. It is aimed to be called from gpiolib init.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pc100/gpiolib.c               |    1 +
 arch/arm/mach-s5pv210/gpiolib.c               |    1 +
 arch/arm/plat-s5p/irq-gpioint.c               |   69 +++++++++++++++++++++----
 arch/arm/plat-samsung/include/plat/gpio-cfg.h |   16 ++++++
 4 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c
index 20856eb..2842394 100644
--- a/arch/arm/mach-s5pc100/gpiolib.c
+++ b/arch/arm/mach-s5pc100/gpiolib.c
@@ -348,6 +348,7 @@ static __init int s5pc100_gpiolib_init(void)
 	}
 
 	samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
index ab673ef..1ba20a7 100644
--- a/arch/arm/mach-s5pv210/gpiolib.c
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -281,6 +281,7 @@ static __init int s5pv210_gpiolib_init(void)
 	}
 
 	samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
 
 	return 0;
 }
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index af10328..70329e6 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include <mach/map.h>
 #include <plat/gpio-core.h>
@@ -29,7 +30,17 @@
 #define PEND_OFFSET		0xA00
 #define REG_OFFSET(x)		((x) << 2)
 
-static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
+struct s5p_gpioint_bank
+{
+	struct list_head	list;
+	int			start;
+	int			nr_groups;
+	int			irq;
+	struct s3c_gpio_chip	**chips;
+	void			(*handler)(unsigned int, struct irq_desc *);
+};
+
+LIST_HEAD(banks);
 
 static int s5p_gpioint_get_offset(struct irq_data *data)
 {
@@ -139,11 +150,12 @@ static struct irq_chip s5p_gpioint = {
 
 static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
 {
+	struct s5p_gpioint_bank *bank = get_irq_data(irq);
 	int group, pend_offset, mask_offset;
 	unsigned int pend, mask;
 
-	for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
-		struct s3c_gpio_chip *chip = irq_chips[group];
+	for (group = 0; group < bank->nr_groups; group++) {
+		struct s3c_gpio_chip *chip = bank->chips[group];
 		if (!chip)
 			continue;
 
@@ -168,23 +180,44 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
 static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
 {
 	static int used_gpioint_groups = 0;
-	static bool handler_registered = 0;
 	int irq, group = chip->group;
 	int i;
+	struct s5p_gpioint_bank *bank = NULL;
 
 	if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
 		return -ENOMEM;
 
+	list_for_each_entry(bank, &banks, list) {
+		if (group >= bank->start &&
+		    group < bank->start + bank->nr_groups)
+			break;
+	}
+	if (!bank)
+		return -EINVAL;
+
+	if (!bank->handler) {
+		bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
+				      bank->nr_groups, GFP_KERNEL);
+		if (!bank->chips)
+			return -ENOMEM;
+
+		set_irq_chained_handler(bank->irq, s5p_gpioint_handler);
+		set_irq_data(bank->irq, bank);
+		bank->handler = s5p_gpioint_handler;
+		printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
+		       bank->irq);
+	}
+
+	/*
+	 * chained GPIO irq has been sucessfully registered, allocate new gpio
+	 * int group and assign irq nubmers
+	 */
+
 	chip->irq_base = S5P_GPIOINT_BASE +
 			 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
 	used_gpioint_groups++;
 
-	if (!handler_registered) {
-		set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
-		handler_registered = 1;
-	}
-
-	irq_chips[group] = chip;
+	bank->chips[group - bank->start] = chip;
 	for (i = 0; i < chip->chip.ngpio; i++) {
 		irq = chip->irq_base + i;
 		set_irq_chip(irq, &s5p_gpioint);
@@ -221,3 +254,19 @@ int __init s5p_register_gpio_interrupt(int pin)
 	}
 	return ret;
 }
+
+int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
+{
+	struct s5p_gpioint_bank *bank;
+
+	bank = kzalloc(sizeof(*bank), GFP_KERNEL);
+	if (!bank)
+		return -ENOMEM;
+
+	bank->start = start;
+	bank->nr_groups = nr_groups;
+	bank->irq = chain_irq;
+
+	list_add_tail(&bank->list, &banks);
+	return 0;
+}
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index e4b5cf1..5e04fa6 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -225,4 +225,20 @@ extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
  */
 extern int s5p_register_gpio_interrupt(int pin);
 
+/** s5p_register_gpioint_bank() - add gpio bank for further gpio interrupt
+ * registration (see s5p_register_gpio_interrupt function)
+ * @chain_irq: chained irq number for the gpio int handler for this bank
+ * @start: start gpio group number of this bank
+ * @nr_groups: number of gpio groups handled by this bank
+ *
+ * This functions registers initial information about gpio banks that
+ * can be later used by the s5p_register_gpio_interrupt() function to
+ * enable support for gpio interrupt for particular gpio group.
+ */
+#ifdef CONFIG_S5P_GPIO_INT
+extern int s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups);
+#else
+#define s5p_register_gpioint_bank(chain_irq, start, nr_groups) do { } while (0)
+#endif
+
 #endif /* __PLAT_GPIO_CFG_H */
-- 
1.7.1.569.g6f426

^ permalink raw reply related

* [PATCH 2/5] ARM: Samsung: cleanup S5P gpio interrupt code
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297927527-1338-1-git-send-email-m.szyprowski@samsung.com>

This patch performs a global cleanup in s5p gpio interrupt support code.
The code is prepared for upcoming support for gpio interrupts on S5PC210
platform, which has 2 gpio banks (regions) instead of one (like on
S5PC110 and S5PC100).

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/plat-s5p/irq-gpioint.c |  106 +++++++++++++++++----------------------
 1 files changed, 46 insertions(+), 60 deletions(-)

diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 3b6bf89..af10328 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -22,77 +22,64 @@
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 
-#define S5P_GPIOREG(x)			(S5P_VA_GPIO + (x))
+#define GPIO_BASE(chip)		(((unsigned long)(chip)->base) & ~(SZ_4K - 1))
 
-#define GPIOINT_CON_OFFSET		0x700
-#define GPIOINT_MASK_OFFSET		0x900
-#define GPIOINT_PEND_OFFSET		0xA00
+#define CON_OFFSET		0x700
+#define MASK_OFFSET		0x900
+#define PEND_OFFSET		0xA00
+#define REG_OFFSET(x)		((x) << 2)
 
 static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
 
-static int s5p_gpioint_get_group(struct irq_data *data)
-{
-	struct gpio_chip *chip = irq_data_get_irq_data(data);
-	struct s3c_gpio_chip *s3c_chip = container_of(chip,
-			struct s3c_gpio_chip, chip);
-	int group;
-
-	for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
-		if (s3c_chip == irq_chips[group])
-			break;
-
-	return group;
-}
-
 static int s5p_gpioint_get_offset(struct irq_data *data)
 {
-	struct gpio_chip *chip = irq_data_get_irq_data(data);
-	struct s3c_gpio_chip *s3c_chip = container_of(chip,
-			struct s3c_gpio_chip, chip);
-
-	return data->irq - s3c_chip->irq_base;
+	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+	return data->irq - chip->irq_base;
 }
 
 static void s5p_gpioint_ack(struct irq_data *data)
 {
+	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
 	int group, offset, pend_offset;
 	unsigned int value;
 
-	group = s5p_gpioint_get_group(data);
+	group = chip->group;
 	offset = s5p_gpioint_get_offset(data);
-	pend_offset = group << 2;
+	pend_offset = REG_OFFSET(group);
 
-	value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
-	value |= 1 << offset;
-	__raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
+	value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
+	value |= BIT(offset);
+	__raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
 }
 
 static void s5p_gpioint_mask(struct irq_data *data)
 {
+	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
 	int group, offset, mask_offset;
 	unsigned int value;
 
-	group = s5p_gpioint_get_group(data);
+	group = chip->group;
 	offset = s5p_gpioint_get_offset(data);
-	mask_offset = group << 2;
+	mask_offset = REG_OFFSET(group);
 
-	value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
-	value |= 1 << offset;
-	__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+	value |= BIT(offset);
+	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
 }
 
 static void s5p_gpioint_unmask(struct irq_data *data)
 {
+	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
 	int group, offset, mask_offset;
 	unsigned int value;
 
-	group = s5p_gpioint_get_group(data);
+	group = chip->group;
 	offset = s5p_gpioint_get_offset(data);
-	mask_offset = group << 2;
+	mask_offset = REG_OFFSET(group);
 
-	value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
-	value &= ~(1 << offset);
-	__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
+	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+	value &= ~BIT(offset);
+	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
 }
 
 static void s5p_gpioint_mask_ack(struct irq_data *data)
@@ -103,12 +90,13 @@ static void s5p_gpioint_mask_ack(struct irq_data *data)
 
 static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
 {
+	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
 	int group, offset, con_offset;
 	unsigned int value;
 
-	group = s5p_gpioint_get_group(data);
+	group = chip->group;
 	offset = s5p_gpioint_get_offset(data);
-	con_offset = group << 2;
+	con_offset = REG_OFFSET(group);
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -132,15 +120,15 @@ static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
 		return -EINVAL;
 	}
 
-	value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+	value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
 	value &= ~(0x7 << (offset * 0x4));
 	value |= (type << (offset * 0x4));
-	__raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
+	__raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
 
 	return 0;
 }
 
-struct irq_chip s5p_gpioint = {
+static struct irq_chip s5p_gpioint = {
 	.name		= "s5p_gpioint",
 	.irq_ack	= s5p_gpioint_ack,
 	.irq_mask	= s5p_gpioint_mask,
@@ -151,30 +139,28 @@ struct irq_chip s5p_gpioint = {
 
 static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
 {
-	int group, offset, pend_offset, mask_offset;
-	int real_irq;
+	int group, pend_offset, mask_offset;
 	unsigned int pend, mask;
 
 	for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
-		pend_offset = group << 2;
-		pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
-				pend_offset);
+		struct s3c_gpio_chip *chip = irq_chips[group];
+		if (!chip)
+			continue;
+
+		pend_offset = REG_OFFSET(group);
+		pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
 		if (!pend)
 			continue;
 
-		mask_offset = group << 2;
-		mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
-				mask_offset);
+		mask_offset = REG_OFFSET(group);
+		mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
 		pend &= ~mask;
 
-		for (offset = 0; offset < 8; offset++) {
-			if (pend & (1 << offset)) {
-				struct s3c_gpio_chip *chip = irq_chips[group];
-				if (chip) {
-					real_irq = chip->irq_base + offset;
-					generic_handle_irq(real_irq);
-				}
-			}
+		while (pend) {
+			int offset = fls(pend) - 1;
+			int real_irq = chip->irq_base + offset;
+			generic_handle_irq(real_irq);
+			pend &= ~BIT(offset);
 		}
 	}
 }
@@ -202,7 +188,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
 	for (i = 0; i < chip->chip.ngpio; i++) {
 		irq = chip->irq_base + i;
 		set_irq_chip(irq, &s5p_gpioint);
-		set_irq_data(irq, &chip->chip);
+		set_irq_data(irq, chip);
 		set_irq_handler(irq, handle_level_irq);
 		set_irq_flags(irq, IRQF_VALID);
 	}
-- 
1.7.1.569.g6f426

^ permalink raw reply related

* [PATCH 1/5] ARM: S5PV310: Add missing GPYx banks.
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297927527-1338-1-git-send-email-m.szyprowski@samsung.com>

This patch adds missing GPYx gpio banks on Samsung S5PC210 platform.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv310/gpiolib.c           |   49 +++++++++++++++++++++++++++++
 arch/arm/mach-s5pv310/include/mach/gpio.h |   23 +++++++++++++-
 2 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
index 55217b8..f417ecd 100644
--- a/arch/arm/mach-s5pv310/gpiolib.c
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -199,6 +199,55 @@ static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
 			.label	= "GPL2",
 		},
 	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY0(0),
+			.ngpio	= S5PV310_GPIO_Y0_NR,
+			.label	= "GPY0",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY1(0),
+			.ngpio	= S5PV310_GPIO_Y1_NR,
+			.label	= "GPY1",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY2(0),
+			.ngpio	= S5PV310_GPIO_Y2_NR,
+			.label	= "GPY2",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY3(0),
+			.ngpio	= S5PV310_GPIO_Y3_NR,
+			.label	= "GPY3",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY4(0),
+			.ngpio	= S5PV310_GPIO_Y4_NR,
+			.label	= "GPY4",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY5(0),
+			.ngpio	= S5PV310_GPIO_Y5_NR,
+			.label	= "GPY5",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV310_GPY6(0),
+			.ngpio	= S5PV310_GPIO_Y6_NR,
+			.label	= "GPY6",
+		},
+	}, {
 		.base	= (S5P_VA_GPIO2 + 0xC00),
 		.config	= &gpio_cfg_noint,
 		.irq_base = IRQ_EINT(0),
diff --git a/arch/arm/mach-s5pv310/include/mach/gpio.h b/arch/arm/mach-s5pv310/include/mach/gpio.h
index 20cb80c..4b44463 100644
--- a/arch/arm/mach-s5pv310/include/mach/gpio.h
+++ b/arch/arm/mach-s5pv310/include/mach/gpio.h
@@ -50,6 +50,13 @@
 #define S5PV310_GPIO_X1_NR	(8)
 #define S5PV310_GPIO_X2_NR	(8)
 #define S5PV310_GPIO_X3_NR	(8)
+#define S5PV310_GPIO_Y0_NR	(6)
+#define S5PV310_GPIO_Y1_NR	(4)
+#define S5PV310_GPIO_Y2_NR	(6)
+#define S5PV310_GPIO_Y3_NR	(8)
+#define S5PV310_GPIO_Y4_NR	(8)
+#define S5PV310_GPIO_Y5_NR	(8)
+#define S5PV310_GPIO_Y6_NR	(8)
 #define S5PV310_GPIO_Z_NR	(7)
 
 /* GPIO bank numbers */
@@ -87,7 +94,14 @@ enum s5p_gpio_number {
 	S5PV310_GPIO_X1_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_X0),
 	S5PV310_GPIO_X2_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_X1),
 	S5PV310_GPIO_X3_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_X2),
-	S5PV310_GPIO_Z_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
+	S5PV310_GPIO_Y0_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_X3),
+	S5PV310_GPIO_Y1_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y0),
+	S5PV310_GPIO_Y2_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y1),
+	S5PV310_GPIO_Y3_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y2),
+	S5PV310_GPIO_Y4_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y3),
+	S5PV310_GPIO_Y5_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y4),
+	S5PV310_GPIO_Y6_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y5),
+	S5PV310_GPIO_Z_START	= S5PV310_GPIO_NEXT(S5PV310_GPIO_Y6),
 };
 
 /* S5PV310 GPIO number definitions */
@@ -120,6 +134,13 @@ enum s5p_gpio_number {
 #define S5PV310_GPX1(_nr)	(S5PV310_GPIO_X1_START + (_nr))
 #define S5PV310_GPX2(_nr)	(S5PV310_GPIO_X2_START + (_nr))
 #define S5PV310_GPX3(_nr)	(S5PV310_GPIO_X3_START + (_nr))
+#define S5PV310_GPY0(_nr)	(S5PV310_GPIO_Y0_START + (_nr))
+#define S5PV310_GPY1(_nr)	(S5PV310_GPIO_Y1_START + (_nr))
+#define S5PV310_GPY2(_nr)	(S5PV310_GPIO_Y2_START + (_nr))
+#define S5PV310_GPY3(_nr)	(S5PV310_GPIO_Y3_START + (_nr))
+#define S5PV310_GPY4(_nr)	(S5PV310_GPIO_Y4_START + (_nr))
+#define S5PV310_GPY5(_nr)	(S5PV310_GPIO_Y5_START + (_nr))
+#define S5PV310_GPY6(_nr)	(S5PV310_GPIO_Y6_START + (_nr))
 #define S5PV310_GPZ(_nr)	(S5PV310_GPIO_Z_START + (_nr))
 
 /* the end of the S5PV310 specific gpios */
-- 
1.7.1.569.g6f426

^ permalink raw reply related

* [PATCH 0/5] S5PC210/S5PV310/EXYNOS4 interrupts update
From: Marek Szyprowski @ 2011-02-17  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch series perform an update on interrupts support for
S5PC210/S5PV310/EXYNOS4 platform. Two optional features have been added.
The first one is GPIO interrupts handler, a second is support for board
specific interrupts. The patches have been prepared to maximise the code
reuse, so common code for gpio interrupts for s5pc100, s5pc110 & s5pc210
have been prepared.

The patches have been prepared against
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
for-next branch (commit 857ddb87db).

Patches that make use of these 2 optional features for universal c210
board will follow soon.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center



Patch summary:

Marek Szyprowski (5):
  ARM: S5PV310: Add missing GPYx banks.
  ARM: Samsung: cleanup S5P gpio interrupt code
  ARM: Samsung: add function to register gpio interrupt bank data
  ARM: S5PC210: add support for gpio interrupts
  ARM: S5PC210: add a placeholder for board specific interrupts

 arch/arm/mach-s5pc100/gpiolib.c               |    1 +
 arch/arm/mach-s5pv210/gpiolib.c               |    1 +
 arch/arm/mach-s5pv310/gpiolib.c               |   67 ++++++++++-
 arch/arm/mach-s5pv310/include/mach/gpio.h     |   23 ++++-
 arch/arm/mach-s5pv310/include/mach/irqs.h     |   16 ++-
 arch/arm/plat-s5p/irq-gpioint.c               |  169 +++++++++++++++----------
 arch/arm/plat-samsung/include/plat/gpio-cfg.h |   16 +++
 7 files changed, 220 insertions(+), 73 deletions(-)

-- 
1.7.1.569.g6f426

^ permalink raw reply

* [PATCH 4/4] ARM: mxs/mx28evk: add auart devices
From: Shawn Guo @ 2011-02-17  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297924132-17402-1-git-send-email-shawn.guo@freescale.com>

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx28evk.c |   21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 3c5ce09..55bf075 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -29,6 +29,7 @@ config MACH_MX28EVK
 	bool "Support MX28EVK Platform"
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_AUART
 	select MXS_HAVE_PLATFORM_FEC
 	select MXS_OCOTP
 	default y
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index e8db99f..1f0b708 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -38,6 +38,25 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	MX28_PAD_PWM1__DUART_TX |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 
+	/* auart0 */
+	MX28_PAD_AUART0_RX__AUART0_RX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART0_TX__AUART0_TX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART0_CTS__AUART0_CTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART0_RTS__AUART0_RTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* auart3 */
+	MX28_PAD_AUART3_RX__AUART3_RX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART3_TX__AUART3_TX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART3_CTS__AUART3_CTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_AUART3_RTS__AUART3_RTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
 	/* fec0 */
 	MX28_PAD_ENET0_MDC__ENET0_MDC |
 		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
@@ -164,6 +183,8 @@ static void __init mx28evk_init(void)
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
+	mx28_add_auart0();
+	mx28_add_auart3();
 
 	if (mx28evk_fec_get_mac())
 		pr_warn("%s: failed on fec mac setup\n", __func__);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/4] ARM: mxs/mx23evk: add auart device
From: Shawn Guo @ 2011-02-17  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297924132-17402-1-git-send-email-shawn.guo@freescale.com>

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx23evk.c |   11 +++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index cd2fbdf..3c5ce09 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -19,6 +19,7 @@ config MACH_MX23EVK
 	bool "Support MX23EVK Platform"
 	select SOC_IMX23
 	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_AUART
 	default y
 	help
 	  Include support for MX23EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
index aa06400..0737ce2 100644
--- a/arch/arm/mach-mxs/mach-mx23evk.c
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -30,6 +30,16 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = {
 	/* duart */
 	MX23_PAD_PWM0__DUART_RX | MXS_PAD_4MA,
 	MX23_PAD_PWM1__DUART_TX | MXS_PAD_4MA,
+
+	/* auart */
+	MX23_PAD_AUART1_RX__AUART1_RX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_AUART1_TX__AUART1_TX |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_AUART1_CTS__AUART1_CTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_AUART1_RTS__AUART1_RTS |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 
 static void __init mx23evk_init(void)
@@ -37,6 +47,7 @@ static void __init mx23evk_init(void)
 	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
 
 	mx23_add_duart();
+	mx23_add_auart0();
 }
 
 static void __init mx23evk_timer_init(void)
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/4] ARM: mx23: dynamically allocate mx23 auart device
From: Shawn Guo @ 2011-02-17  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297924132-17402-1-git-send-email-shawn.guo@freescale.com>

i.MX23 Reference Manaul starts auart index from 1 than 0.  Changing
the index to start from 0 requires corresponding changes on base
address, irq, and iomux definitions, and will probably confuse people
who reads codes and hardware documents together.

This patch introduced the field 'hwid' to distinguish the driver id
and controller id.  These two ids are different on mx23 while
identical on mx28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c             |    1 +
 arch/arm/mach-mxs/devices-mx23.h           |    5 +++++
 arch/arm/mach-mxs/devices/platform-auart.c |   22 ++++++++++++++++------
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index ca72a05..7c5dace 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -442,6 +442,7 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
 	/* for amba-pl011 driver */
 	_REGISTER_CLOCK("duart", NULL, uart_clk)
+	_REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
 	_REGISTER_CLOCK(NULL, "usb", usb_clk)
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
index 1256788..c4d4773 100644
--- a/arch/arm/mach-mxs/devices-mx23.h
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -14,3 +14,8 @@
 extern const struct amba_device mx23_duart_device __initconst;
 #define mx23_add_duart() \
 	mxs_add_duart(&mx23_duart_device)
+
+extern const struct mxs_auart_data mx23_auart_data[] __initconst;
+#define mx23_add_auart(id)	mxs_add_auart(&mx23_auart_data[id])
+#define mx23_add_auart0()		mx23_add_auart(0)
+#define mx23_add_auart1()		mx23_add_auart(1)
diff --git a/arch/arm/mach-mxs/devices/platform-auart.c b/arch/arm/mach-mxs/devices/platform-auart.c
index f0dbf8a..796606c 100644
--- a/arch/arm/mach-mxs/devices/platform-auart.c
+++ b/arch/arm/mach-mxs/devices/platform-auart.c
@@ -7,23 +7,33 @@
  * Free Software Foundation.
  */
 #include <asm/sizes.h>
+#include <mach/mx23.h>
 #include <mach/mx28.h>
 #include <mach/devices-common.h>
 
-#define mxs_auart_data_entry_single(soc, _id)				\
+#define mxs_auart_data_entry_single(soc, _id, hwid)			\
 	{								\
 		.id = _id,						\
-		.iobase = soc ## _AUART ## _id ## _BASE_ADDR,		\
-		.irq = soc ## _INT_AUART ## _id,			\
+		.iobase = soc ## _AUART ## hwid ## _BASE_ADDR,		\
+		.irq = soc ## _INT_AUART ## hwid,			\
 	}
 
-#define mxs_auart_data_entry(soc, _id)					\
-	[_id] = mxs_auart_data_entry_single(soc, _id)
+#define mxs_auart_data_entry(soc, _id, hwid)				\
+	[_id] = mxs_auart_data_entry_single(soc, _id, hwid)
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_auart_data mx23_auart_data[] __initconst = {
+#define mx23_auart_data_entry(_id, hwid)				\
+	mxs_auart_data_entry(MX23, _id, hwid)
+	mx23_auart_data_entry(0, 1),
+	mx23_auart_data_entry(1, 2),
+};
+#endif
 
 #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)
+	mxs_auart_data_entry(MX28, _id, _id)
 	mx28_auart_data_entry(0),
 	mx28_auart_data_entry(1),
 	mx28_auart_data_entry(2),
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/4] ARM: mx23: rename mx23 auart irq definition to align with mx28
From: Shawn Guo @ 2011-02-17  6:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297924132-17402-1-git-send-email-shawn.guo@freescale.com>

i.MX23 Reference Manual names auart irq differently from i.MX28.
This patch is to align the naming with mx28, so that some device
registration codes can be shared.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/mx23.h |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
index 9edd02e..4768402 100644
--- a/arch/arm/mach-mxs/include/mach/mx23.h
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -101,9 +101,9 @@
 #define MX23_INT_SSP2_DMA		20
 #define MX23_INT_ECC8_IRQ		21
 #define MX23_INT_RTC_ALARM		22
-#define MX23_INT_UARTAPP_TX_DMA		23
-#define MX23_INT_UARTAPP_INTERNAL	24
-#define MX23_INT_UARTAPP_RX_DMA		25
+#define MX23_INT_AUART1_TX_DMA		23
+#define MX23_INT_AUART1			24
+#define MX23_INT_AUART1_RX_DMA		25
 #define MX23_INT_I2C_DMA		26
 #define MX23_INT_I2C_ERROR		27
 #define MX23_INT_TIMER0			28
@@ -135,9 +135,9 @@
 #define MX23_INT_DCP			54
 #define MX23_INT_BCH			56
 #define MX23_INT_PXP			57
-#define MX23_INT_UARTAPP2_TX_DMA	58
-#define MX23_INT_UARTAPP2_INTERNAL	59
-#define MX23_INT_UARTAPP2_RX_DMA	60
+#define MX23_INT_AUART2_TX_DMA		58
+#define MX23_INT_AUART2			59
+#define MX23_INT_AUART2_RX_DMA		60
 #define MX23_INT_VDAC_DETECT		61
 #define MX23_INT_VDD5V_DROOP		64
 #define MX23_INT_DCDC4P2_BO		65
-- 
1.7.1

^ permalink raw reply related

* [PATCH] Add auart devices for mx23 and mx28 evk boards
From: Shawn Guo @ 2011-02-17  6:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch set is to add auart devices for mx23evk and mx28evk board.

Regards,
Shawn

^ permalink raw reply

* [RFC 2/5] ARM: P2V: avoid initializers and assembly using PHYS_OFFSET
From: Kukjin Kim @ 2011-02-17  5:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1PaDOv-00023d-Gi@rmk-PC.arm.linux.org.uk>

Russell King - ARM Linux wrote:
> 
> As PHYS_OFFSET will be becoming a variable, we can't have it used in
> initializers nor assembly code.  Replace those in generic code with
> a run-time initialization.  Replace those in platform code using the
> individual platform specific PLAT_PHYS_OFFSET.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/kernel/setup.c                  |    4 +++-
>  arch/arm/mach-msm/board-msm7x27.c        |    8 ++++----
>  arch/arm/mach-msm/board-msm7x30.c        |    6 +++---
>  arch/arm/mach-msm/board-qsd8x50.c        |    4 ++--
>  arch/arm/mach-msm/board-sapphire.c       |    2 +-
>  arch/arm/mach-mx5/board-cpuimx51.c       |    2 +-
>  arch/arm/mach-mx5/board-cpuimx51sd.c     |    2 +-
>  arch/arm/mach-mx5/board-mx51_3ds.c       |    2 +-
>  arch/arm/mach-pxa/balloon3.c             |    2 +-
>  arch/arm/mach-realview/realview_eb.c     |    2 +-
>  arch/arm/mach-realview/realview_pb1176.c |    2 +-
>  arch/arm/mach-realview/realview_pb11mp.c |    2 +-
>  arch/arm/mach-realview/realview_pba8.c   |    2 +-
>  arch/arm/mach-realview/realview_pbx.c    |    2 +-
>  arch/arm/mach-s5pv210/sleep.S            |    2 +-
>  arch/arm/mach-tcc8k/board-tcc8000-sdk.c  |    2 +-
>  arch/arm/mach-vexpress/ct-ca9x4.c        |    2 +-
>  17 files changed, 25 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index 3455ad3..f67e682 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -705,7 +705,7 @@ static struct init_tags {
>  	{ tag_size(tag_core), ATAG_CORE },
>  	{ 1, PAGE_SIZE, 0xff },
>  	{ tag_size(tag_mem32), ATAG_MEM },
> -	{ MEM_SIZE, PHYS_OFFSET },
> +	{ MEM_SIZE },
>  	{ 0, ATAG_NONE }
>  };
> 
> @@ -804,6 +804,8 @@ void __init setup_arch(char **cmdline_p)
>  	struct machine_desc *mdesc;
>  	char *from = default_command_line;
> 
> +	tags->mem.start = PHYS_OFFSET;
> +
>  	unwind_init();
> 
>  	setup_processor();

(snip)

> diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
> index d4d222b..2737622 100644
> --- a/arch/arm/mach-s5pv210/sleep.S
> +++ b/arch/arm/mach-s5pv210/sleep.S
> @@ -65,7 +65,7 @@ resume_with_mmu:
>  	/*
>  	 * After MMU is turned on, restore the previous MMU table.
>  	 */
> -	ldr	r9 , =(PAGE_OFFSET - PHYS_OFFSET)
> +	ldr	r9 , =(PAGE_OFFSET - PLAT_PHYS_OFFSET)
>  	add	r4, r4, r9
>  	str	r12, [r4]
> 

(snip)

> --
> 1.6.2.5

Acked-by: Kukjin Kim <kgene.kim@samsung.com>

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [RFC 1/5] ARM: P2V: separate PHYS_OFFSET from platform definitions
From: Kukjin Kim @ 2011-02-17  5:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1PaDOb-00023Z-CR@rmk-PC.arm.linux.org.uk>

Russell King - ARM Linux wrote:
> 
> This uncouple PHYS_OFFSET from the platform definitions, thereby
> facilitating run-time computation of the physical memory offset.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/include/asm/memory.h                  |    2 ++
>  arch/arm/kernel/tcm.c                          |    2 +-
>  arch/arm/mach-aaec2000/include/mach/memory.h   |    2 +-
>  arch/arm/mach-at91/include/mach/memory.h       |    2 +-
>  arch/arm/mach-bcmring/include/mach/hardware.h  |    2 +-
>  arch/arm/mach-bcmring/include/mach/memory.h    |    2 +-
>  arch/arm/mach-clps711x/include/mach/memory.h   |    2 +-
>  arch/arm/mach-cns3xxx/include/mach/memory.h    |    2 +-
>  arch/arm/mach-davinci/include/mach/memory.h    |    4 ++--
>  arch/arm/mach-dove/include/mach/memory.h       |    2 +-
>  arch/arm/mach-ebsa110/include/mach/memory.h    |    2 +-
>  arch/arm/mach-ep93xx/include/mach/memory.h     |   10 +++++-----
>  arch/arm/mach-footbridge/include/mach/memory.h |    2 +-
>  arch/arm/mach-h720x/include/mach/memory.h      |    2 +-
>  arch/arm/mach-integrator/include/mach/memory.h |    2 +-
>  arch/arm/mach-iop13xx/include/mach/memory.h    |    2 +-
>  arch/arm/mach-iop32x/include/mach/memory.h     |    2 +-
>  arch/arm/mach-iop33x/include/mach/memory.h     |    2 +-
>  arch/arm/mach-ixp2000/include/mach/memory.h    |    2 +-
>  arch/arm/mach-ixp23xx/include/mach/memory.h    |    2 +-
>  arch/arm/mach-ixp4xx/include/mach/memory.h     |    2 +-
>  arch/arm/mach-kirkwood/include/mach/memory.h   |    2 +-
>  arch/arm/mach-ks8695/include/mach/memory.h     |    2 +-
>  arch/arm/mach-lh7a40x/include/mach/memory.h    |    2 +-
>  arch/arm/mach-loki/include/mach/memory.h       |    2 +-
>  arch/arm/mach-lpc32xx/include/mach/memory.h    |    2 +-
>  arch/arm/mach-mmp/include/mach/memory.h        |    2 +-
>  arch/arm/mach-msm/board-msm7x30.c              |    2 +-
>  arch/arm/mach-msm/include/mach/memory.h        |   10 +++++-----
>  arch/arm/mach-mv78xx0/include/mach/memory.h    |    2 +-
>  arch/arm/mach-mx3/mach-kzm_arm11_01.c          |    2 +-
>  arch/arm/mach-netx/include/mach/memory.h       |    2 +-
>  arch/arm/mach-nomadik/include/mach/memory.h    |    2 +-
>  arch/arm/mach-ns9xxx/include/mach/memory.h     |    2 +-
>  arch/arm/mach-nuc93x/include/mach/memory.h     |    2 +-
>  arch/arm/mach-orion5x/include/mach/memory.h    |    2 +-
>  arch/arm/mach-pnx4008/include/mach/memory.h    |    2 +-
>  arch/arm/mach-pxa/include/mach/memory.h        |    2 +-
>  arch/arm/mach-realview/include/mach/memory.h   |    4 ++--
>  arch/arm/mach-rpc/include/mach/memory.h        |    2 +-
>  arch/arm/mach-s3c2400/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s3c2410/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s3c24a0/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s3c64xx/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s5p6442/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s5p64x0/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s5pc100/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s5pv210/include/mach/memory.h    |    2 +-
>  arch/arm/mach-s5pv310/include/mach/memory.h    |    2 +-
>  arch/arm/mach-sa1100/include/mach/memory.h     |    2 +-
>  arch/arm/mach-shark/include/mach/memory.h      |    2 +-
>  arch/arm/mach-shmobile/include/mach/memory.h   |    2 +-
>  arch/arm/mach-tegra/include/mach/memory.h      |    2 +-
>  arch/arm/mach-u300/include/mach/memory.h       |    6 +++---
>  arch/arm/mach-u300/u300.c                      |    2 +-
>  arch/arm/mach-ux500/include/mach/memory.h      |    2 +-
>  arch/arm/mach-versatile/include/mach/memory.h  |    2 +-
>  arch/arm/mach-vexpress/include/mach/memory.h   |    2 +-
>  arch/arm/mach-w90x900/include/mach/memory.h    |    2 +-
>  arch/arm/plat-omap/include/plat/memory.h       |    4 ++--
>  arch/arm/plat-spear/include/plat/memory.h      |    2 +-
>  arch/arm/plat-stmp3xxx/include/mach/memory.h   |    2 +-
>  arch/arm/plat-tcc/include/mach/memory.h        |    2 +-
>  63 files changed, 77 insertions(+), 75 deletions(-)
> 
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index 23c2e8e..00b04ae 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -24,6 +24,8 @@
>   */
>  #define UL(x) _AC(x, UL)
> 
> +#define PHYS_OFFSET	PLAT_PHYS_OFFSET
> +
>  #ifdef CONFIG_MMU
> 
>  /*
> diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
> index 26685c2..f5cf660 100644
> --- a/arch/arm/kernel/tcm.c
> +++ b/arch/arm/kernel/tcm.c
> @@ -15,7 +15,7 @@
>  #include <linux/string.h> /* memcpy */
>  #include <asm/cputype.h>
>  #include <asm/mach/map.h>
> -#include <mach/memory.h>
> +#include <asm/memory.h>
>  #include "tcm.h"
> 
>  static struct gen_pool *tcm_pool;

(snip)

> diff --git a/arch/arm/mach-s3c2400/include/mach/memory.h b/arch/arm/mach-
> s3c2400/include/mach/memory.h
> index cf5901f..3f33670 100644
> --- a/arch/arm/mach-s3c2400/include/mach/memory.h
> +++ b/arch/arm/mach-s3c2400/include/mach/memory.h
> @@ -15,6 +15,6 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET	UL(0x0C000000)
> +#define PLAT_PHYS_OFFSET	UL(0x0C000000)
> 
>  #endif
> diff --git a/arch/arm/mach-s3c2410/include/mach/memory.h b/arch/arm/mach-
> s3c2410/include/mach/memory.h
> index 6f1e587..f92b97b 100644
> --- a/arch/arm/mach-s3c2410/include/mach/memory.h
> +++ b/arch/arm/mach-s3c2410/include/mach/memory.h
> @@ -11,6 +11,6 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET	UL(0x30000000)
> +#define PLAT_PHYS_OFFSET	UL(0x30000000)
> 
>  #endif
> diff --git a/arch/arm/mach-s3c24a0/include/mach/memory.h b/arch/arm/mach-
> s3c24a0/include/mach/memory.h
> index 7d74fd5..7d208a7 100644
> --- a/arch/arm/mach-s3c24a0/include/mach/memory.h
> +++ b/arch/arm/mach-s3c24a0/include/mach/memory.h
> @@ -11,7 +11,7 @@
>  #ifndef __ASM_ARCH_24A0_MEMORY_H
>  #define __ASM_ARCH_24A0_MEMORY_H __FILE__
> 
> -#define PHYS_OFFSET UL(0x10000000)
> +#define PLAT_PHYS_OFFSET UL(0x10000000)
> 
>  #define __virt_to_bus(x) __virt_to_phys(x)
>  #define __bus_to_virt(x) __phys_to_virt(x)
> diff --git a/arch/arm/mach-s3c64xx/include/mach/memory.h b/arch/arm/mach-
> s3c64xx/include/mach/memory.h
> index 42cc54e..4760cda 100644
> --- a/arch/arm/mach-s3c64xx/include/mach/memory.h
> +++ b/arch/arm/mach-s3c64xx/include/mach/memory.h
> @@ -13,7 +13,7 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET     UL(0x50000000)
> +#define PLAT_PHYS_OFFSET     UL(0x50000000)
> 
>  #define CONSISTENT_DMA_SIZE	SZ_8M
> 
> diff --git a/arch/arm/mach-s5p6442/include/mach/memory.h b/arch/arm/mach-
> s5p6442/include/mach/memory.h
> index 9ddd877..cfe259d 100644
> --- a/arch/arm/mach-s5p6442/include/mach/memory.h
> +++ b/arch/arm/mach-s5p6442/include/mach/memory.h
> @@ -13,7 +13,7 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET		UL(0x20000000)
> +#define PLAT_PHYS_OFFSET		UL(0x20000000)
>  #define CONSISTENT_DMA_SIZE	SZ_8M
> 
>  #endif /* __ASM_ARCH_MEMORY_H */
> diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-
> s5p64x0/include/mach/memory.h
> index 1b036b0..365a6eb 100644
> --- a/arch/arm/mach-s5p64x0/include/mach/memory.h
> +++ b/arch/arm/mach-s5p64x0/include/mach/memory.h
> @@ -13,7 +13,7 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H __FILE__
> 
> -#define PHYS_OFFSET		UL(0x20000000)
> +#define PLAT_PHYS_OFFSET		UL(0x20000000)
>  #define CONSISTENT_DMA_SIZE	SZ_8M
> 
>  #endif /* __ASM_ARCH_MEMORY_H */
> diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-
> s5pc100/include/mach/memory.h
> index 4b60d18..bda4e79 100644
> --- a/arch/arm/mach-s5pc100/include/mach/memory.h
> +++ b/arch/arm/mach-s5pc100/include/mach/memory.h
> @@ -13,6 +13,6 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET     	UL(0x20000000)
> +#define PLAT_PHYS_OFFSET     	UL(0x20000000)
> 
>  #endif
> diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-
> s5pv210/include/mach/memory.h
> index d503e0c..7b5fcf0 100644
> --- a/arch/arm/mach-s5pv210/include/mach/memory.h
> +++ b/arch/arm/mach-s5pv210/include/mach/memory.h
> @@ -13,7 +13,7 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H
> 
> -#define PHYS_OFFSET		UL(0x20000000)
> +#define PLAT_PHYS_OFFSET		UL(0x20000000)
>  #define CONSISTENT_DMA_SIZE	(SZ_8M + SZ_4M + SZ_2M)
> 
>  /*
> diff --git a/arch/arm/mach-s5pv310/include/mach/memory.h b/arch/arm/mach-
> s5pv310/include/mach/memory.h
> index 1dffb48..470b01b 100644
> --- a/arch/arm/mach-s5pv310/include/mach/memory.h
> +++ b/arch/arm/mach-s5pv310/include/mach/memory.h
> @@ -13,7 +13,7 @@
>  #ifndef __ASM_ARCH_MEMORY_H
>  #define __ASM_ARCH_MEMORY_H __FILE__
> 
> -#define PHYS_OFFSET		UL(0x40000000)
> +#define PLAT_PHYS_OFFSET		UL(0x40000000)
> 
>  /* Maximum of 256MiB in one bank */
>  #define MAX_PHYSMEM_BITS	32

(snip)

> --
> 1.6.2.5

Acked-by: Kukjin Kim <kgene.kim@samsung.com>

Hmm...and as a note, submitted changing 'mach-exynos4' from 'mach-s5pv310'.
I know you can handle it later :)

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 2/2] ARM: remove the 4x expansion presumption while decompressing the kernel
From: Grant Likely @ 2011-02-17  4:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1102161944090.14920@xanadu.home>

On Wed, Feb 16, 2011 at 6:48 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Wed, 16 Feb 2011, Grant Likely wrote:
>
>> Patch looks good to me, but on a related note, I'm looking for a way
>> to also find the end of .bss.
>>
>> When John looks at adding support for appending an initrd and/or dtb
>> to the zimage, it will be important to make sure the start of the
>> initrd/dtb does not overlap the ram the kernel is expecting to be
>> empty and available. ?I was thinking about simply grepping System.map
>> for __end and doing some sed magic to extract the offset from the
>> beginning of the kernel.
>
> I'd use the 'size' command instead:
>
> $ arm-linux-size vmlinux
> ? text ? ?data ? ? bss ? ? dec ? ? hex filename
> 3707759 ?135316 ?137808 3980883 ?3cbe53 vmlinux
>
>> Do you think that is sufficient to protect appended data images?
>
> Starting with my compressed/head.S rework, you'd have to:
>
> 1) Detect if there is some valuable data past _edata, and if so then
> ? increase the cached _edata value in r6 accordingly. ?This way, if
> ? zImage needs to relocate itself then that will include that data.
>
> 2) Modify the conditions and parameters for a zImage relocation to
> ? ensure the end of the kernel .bss is below the start of your data.
>
> 3) Modify the relocation of .bss entries in the GOT table so .bss is
> ? effectively moved after that appended data.
>
> 4) Tell the kernel about the data via extra ATAG/DTB entries.
>
> Except for (4), this can be done with only a few assembly instructions.
> And even in the ATAG case there is a good example in
> arch/arm/boot/bootp/init.S for (4), but that could as well be done in C
> instead, like the initial patch that John Bonesio did.

Cool, that matches my thinking.  We'll start working on this.

g.

^ permalink raw reply

* ALSA issue on DA850/OMAP-L138/AM18x
From: Rajashekhara, Sudhakar @ 2011-02-17  4:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D5BDA3D.5080905@acn-group.ch>

Hi Christophe,

On Wed, Feb 16, 2011 at 19:37:57, Christophe Aeschlimann wrote:
> Hi Sudhakar,
> 
> On 18.01.2011 05:43, Rajashekhara, Sudhakar wrote:
> 
> [...]
> 
>  > With the above fixes, arecord and aplay does not work for the first time.
>  > Couple of times I get the below error:
>  >
>  > root at da850-omapl138-evm:~# arecord -f dat | aplay -f dat
>  > arecord: main:608: audio open error: Invalid argument
>  > aplay: playback:2297: read error
>  > root at da850-omapl138-evm:~# arecord -f dat | aplay -f dat
>  > aplay: main:608: audio open error: Invalid argument
>  > Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 48000 Hz, 
> Stereo
>  >
>  > Third time arecord and aplay work normally.
>  >
>  > Has anyone seen such issues on DA850 or any other platform?
>  >
>  > I am currently debugging this issue. I'll submit the above patch to 
> community
>  > once the issue of fixed.
> 
> I'm facing the same issue here.
> 
> Did you make any progress on that one ?
> 

Reverting the commit 140176159597ea1f23dcccb47b5c38fdf7c7faa8 
(ASoC: Configure symmetric rates for tlv320aic3x) resolves the issue. We are
still working on the proper fix.

Thanks,
Sudhakar 

^ permalink raw reply

* [PATCH V5 12/63] ST SPEAr: Adding support for CLCD on SPEAr3xx/6xx
From: viresh kumar @ 2011-02-17  4:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110216101426.GC6504@n2100.arm.linux.org.uk>

On 02/16/2011 03:44 PM, Russell King - ARM Linux wrote:
>> > This choice stuff has gone with the removal of the lpd code from the
>> > kernel, and thus is unmergable.  This kind of platform specific
>> > configuration has no business being in this file anyway.
> The other thing is that the handling of BGR/RGB has changed in the
> 'versatile' branch too, so you may want to delay this patch until
> later.

Ok.

--
viresh

^ permalink raw reply

* [PATCH 5/5] OMAP2+: clock: remove the DPLL rate tolerance code
From: Paul Walmsley @ 2011-02-17  4:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110217041437.16009.52336.stgit@twilight.localdomain>

Remove the DPLL rate tolerance code that is called during rate
rounding.  As far as I know, this code is never used, since it's been
more important for callers of the DPLL round_rate()/set_rate()
functions to obtain an exact rate than it is to save a relatively
small amount of power.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clkt_dpll.c         |   91 ++++++++-----------------------
 arch/arm/mach-omap2/clock.h             |    4 -
 arch/arm/mach-omap2/clock2420_data.c    |    1 
 arch/arm/mach-omap2/clock2430_data.c    |    1 
 arch/arm/mach-omap2/clock3xxx_data.c    |    6 --
 arch/arm/plat-omap/include/plat/clock.h |    7 --
 6 files changed, 24 insertions(+), 86 deletions(-)

diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index 337392c..17735e7 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -178,12 +178,11 @@ void omap2_init_dpll_parent(struct clk *clk)
 	if (!dd)
 		return;
 
-	/* Return bypass rate if DPLL is bypassed */
 	v = __raw_readl(dd->control_reg);
 	v &= dd->enable_mask;
 	v >>= __ffs(dd->enable_mask);
 
-	/* Reparent in case the dpll is in bypass */
+	/* Reparent the struct clk in case the dpll is in bypass */
 	if (cpu_is_omap24xx()) {
 		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
@@ -260,50 +259,22 @@ u32 omap2_get_dpll_rate(struct clk *clk)
 /* DPLL rate rounding code */
 
 /**
- * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
- * @clk: struct clk * of the DPLL
- * @tolerance: maximum rate error tolerance
- *
- * Set the maximum DPLL rate error tolerance for the rate rounding
- * algorithm.  The rate tolerance is an attempt to balance DPLL power
- * saving (the least divider value "n") vs. rate fidelity (the least
- * difference between the desired DPLL target rate and the rounded
- * rate out of the algorithm).  So, increasing the tolerance is likely
- * to decrease DPLL power consumption and increase DPLL rate error.
- * Returns -EINVAL if provided a null clock ptr or a clk that is not a
- * DPLL; or 0 upon success.
- */
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
-{
-	if (!clk || !clk->dpll_data)
-		return -EINVAL;
-
-	clk->dpll_data->rate_tolerance = tolerance;
-
-	return 0;
-}
-
-/**
  * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
  * @clk: struct clk * for a DPLL
  * @target_rate: desired DPLL clock rate
  *
- * Given a DPLL, a desired target rate, and a rate tolerance, round
- * the target rate to a possible, programmable rate for this DPLL.
- * Rate tolerance is assumed to be set by the caller before this
- * function is called.  Attempts to select the minimum possible n
- * within the tolerance to reduce power consumption.  Stores the
- * computed (m, n) in the DPLL's dpll_data structure so set_rate()
- * will not need to call this (expensive) function again.  Returns ~0
- * if the target rate cannot be rounded, either because the rate is
- * too low or because the rate tolerance is set too tightly; or the
- * rounded rate upon success.
+ * Given a DPLL and a desired target rate, round the target rate to a
+ * possible, programmable rate for this DPLL.  Attempts to select the
+ * minimum possible n.  Stores the computed (m, n) in the DPLL's
+ * dpll_data structure so set_rate() will not need to call this
+ * (expensive) function again.  Returns ~0 if the target rate cannot
+ * be rounded, or the rounded rate upon success.
  */
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 {
-	int m, n, r, e, scaled_max_m;
-	unsigned long scaled_rt_rp, new_rate;
-	int min_e = -1, min_e_m = -1, min_e_n = -1;
+	int m, n, r, scaled_max_m;
+	unsigned long scaled_rt_rp;
+	unsigned long new_rate = 0;
 	struct dpll_data *dd;
 
 	if (!clk || !clk->dpll_data)
@@ -311,8 +282,8 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 
 	dd = clk->dpll_data;
 
-	pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
-		 "%ld\n", clk->name, target_rate);
+	pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
+		 clk->name, target_rate);
 
 	scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
 	scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
@@ -347,39 +318,23 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
 		if (r == DPLL_MULT_UNDERFLOW)
 			continue;
 
-		e = target_rate - new_rate;
-		pr_debug("clock: n = %d: m = %d: rate error is %d "
-			 "(new_rate = %ld)\n", n, m, e, new_rate);
-
-		if (min_e == -1 ||
-		    min_e >= (int)(abs(e) - dd->rate_tolerance)) {
-			min_e = e;
-			min_e_m = m;
-			min_e_n = n;
-
-			pr_debug("clock: found new least error %d\n", min_e);
+		pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
+			 clk->name, m, n, new_rate);
 
-			/* We found good settings -- bail out now */
-			if (min_e <= dd->rate_tolerance)
-				break;
+		if (target_rate == new_rate) {
+			dd->last_rounded_m = m;
+			dd->last_rounded_n = n;
+			dd->last_rounded_rate = target_rate;
+			break;
 		}
 	}
 
-	if (min_e < 0) {
-		pr_debug("clock: error: target rate or tolerance too low\n");
+	if (target_rate != new_rate) {
+		pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
+			 target_rate);
 		return ~0;
 	}
 
-	dd->last_rounded_m = min_e_m;
-	dd->last_rounded_n = min_e_n;
-	dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
-						       min_e_m,  min_e_n);
-
-	pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
-		 min_e, min_e_m, min_e_n);
-	pr_debug("clock: final rate: %ld  (target rate: %ld)\n",
-		 dd->last_rounded_rate, target_rate);
-
-	return dd->last_rounded_rate;
+	return target_rate;
 }
 
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 70f8b07..62cfd6c 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -18,9 +18,6 @@
 
 #include <plat/clock.h>
 
-/* The maximum error between a target DPLL rate and the rounded rate in Hz */
-#define DEFAULT_DPLL_RATE_TOLERANCE	50000
-
 /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
 #define CORE_CLK_SRC_32K		0x0
 #define CORE_CLK_SRC_DPLL		0x1
@@ -55,7 +52,6 @@ void omap2_clk_disable(struct clk *clk);
 long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
 int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
-int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
 long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
 unsigned long omap3_dpll_recalc(struct clk *clk);
 unsigned long omap3_clkoutx2_recalc(struct clk *clk);
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 6e9d20d..22eeafc 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -116,7 +116,6 @@ static struct dpll_data dpll_dd = {
 	.max_multiplier		= 1023,
 	.min_divider		= 1,
 	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 /*
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 3378dbf..df4cac5 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -116,7 +116,6 @@ static struct dpll_data dpll_dd = {
 	.max_multiplier		= 1023,
 	.min_divider		= 1,
 	.max_divider		= 16,
-	.rate_tolerance		= DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 /*
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 58db368..b82afec 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -291,7 +291,6 @@ static struct dpll_data dpll1_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll1_ck = {
@@ -364,7 +363,6 @@ static struct dpll_data dpll2_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll2_ck = {
@@ -424,7 +422,6 @@ static struct dpll_data dpll3_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll3_ck = {
@@ -583,7 +580,6 @@ static struct dpll_data dpll4_dd_34xx __initdata = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct dpll_data dpll4_dd_3630 __initdata = {
@@ -607,7 +603,6 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
 	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
 	.flags		= DPLL_J_TYPE
 };
 
@@ -939,7 +934,6 @@ static struct dpll_data dpll5_dd = {
 	.max_multiplier = OMAP3_MAX_DPLL_MULT,
 	.min_divider	= 1,
 	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
 };
 
 static struct clk dpll5_ck = {
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 48b52fb..072eef1 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -108,7 +108,6 @@ struct clksel {
  * @clk_ref: struct clk pointer to the clock's reference clock input
  * @control_reg: register containing the DPLL mode bitfield
  * @enable_mask: mask of the DPLL mode bitfield in @control_reg
- * @rate_tolerance: maximum variance allowed from target rate (in Hz)
  * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
  * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
  * @max_multiplier: maximum valid non-bypass multiplier value (actual)
@@ -134,12 +133,9 @@ struct clksel {
  * XXX Some DPLLs have multiple bypass inputs, so it's not technically
  * correct to only have one @clk_bypass pointer.
  *
- * XXX @rate_tolerance should probably be deprecated - currently there
- * don't seem to be any usecases for DPLL rounding that is not exact.
- *
  * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
  * @last_rounded_n) should be separated from the runtime-fixed fields
- * and placed into a differenct structure, so that the runtime-fixed data
+ * and placed into a different structure, so that the runtime-fixed data
  * can be placed into read-only space.
  */
 struct dpll_data {
@@ -150,7 +146,6 @@ struct dpll_data {
 	struct clk		*clk_ref;
 	void __iomem		*control_reg;
 	u32			enable_mask;
-	unsigned int		rate_tolerance;
 	unsigned long		last_rounded_rate;
 	u16			last_rounded_m;
 	u16			max_multiplier;

^ permalink raw reply related

* [PATCH 4/5] OMAP: clock: bail out early if arch_clock functions not implemented
From: Paul Walmsley @ 2011-02-17  4:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110217041437.16009.52336.stgit@twilight.localdomain>

Bail out before we take the clockfw_lock spinlock if the corresponding
OMAP1 or OMAP2+ clock function is not defined.  The intention is to
reduce and simplify the work that is done inside the spinlock.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/plat-omap/clock.c |   66 +++++++++++++++++++++++++-------------------
 1 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 2770ddd..c9122dd 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -37,14 +37,16 @@ static struct clk_functions *arch_clock;
 int clk_enable(struct clk *clk)
 {
 	unsigned long flags;
-	int ret = 0;
+	int ret;
 
 	if (clk == NULL || IS_ERR(clk))
 		return -EINVAL;
 
+	if (!arch_clock || !arch_clock->clk_enable)
+		return -EINVAL;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_enable)
-		ret = arch_clock->clk_enable(clk);
+	ret = arch_clock->clk_enable(clk);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -58,6 +60,9 @@ void clk_disable(struct clk *clk)
 	if (clk == NULL || IS_ERR(clk))
 		return;
 
+	if (!arch_clock || !arch_clock->clk_disable)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (clk->usecount == 0) {
 		pr_err("Trying disable clock %s with 0 usecount\n",
@@ -66,8 +71,7 @@ void clk_disable(struct clk *clk)
 		goto out;
 	}
 
-	if (arch_clock->clk_disable)
-		arch_clock->clk_disable(clk);
+	arch_clock->clk_disable(clk);
 
 out:
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -77,7 +81,7 @@ EXPORT_SYMBOL(clk_disable);
 unsigned long clk_get_rate(struct clk *clk)
 {
 	unsigned long flags;
-	unsigned long ret = 0;
+	unsigned long ret;
 
 	if (clk == NULL || IS_ERR(clk))
 		return 0;
@@ -97,14 +101,16 @@ EXPORT_SYMBOL(clk_get_rate);
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long flags;
-	long ret = 0;
+	long ret;
 
 	if (clk == NULL || IS_ERR(clk))
-		return ret;
+		return 0;
+
+	if (!arch_clock || !arch_clock->clk_round_rate)
+		return 0;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_round_rate)
-		ret = arch_clock->clk_round_rate(clk, rate);
+	ret = arch_clock->clk_round_rate(clk, rate);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -119,14 +125,13 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (clk == NULL || IS_ERR(clk))
 		return ret;
 
+	if (!arch_clock || !arch_clock->clk_set_rate)
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_set_rate)
-		ret = arch_clock->clk_set_rate(clk, rate);
-	if (ret == 0) {
-		if (clk->recalc)
-			clk->rate = clk->recalc(clk);
+	ret = arch_clock->clk_set_rate(clk, rate);
+	if (ret == 0)
 		propagate_rate(clk);
-	}
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 
 	return ret;
@@ -141,15 +146,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 	if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
 		return ret;
 
+	if (!arch_clock || !arch_clock->clk_set_parent)
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (clk->usecount == 0) {
-		if (arch_clock->clk_set_parent)
-			ret = arch_clock->clk_set_parent(clk, parent);
-		if (ret == 0) {
-			if (clk->recalc)
-				clk->rate = clk->recalc(clk);
+		ret = arch_clock->clk_set_parent(clk, parent);
+		if (ret == 0)
 			propagate_rate(clk);
-		}
 	} else
 		ret = -EBUSY;
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -399,9 +403,11 @@ void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
 {
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_init_cpufreq_table)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_init_cpufreq_table)
-		arch_clock->clk_init_cpufreq_table(table);
+	arch_clock->clk_init_cpufreq_table(table);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 
@@ -409,9 +415,11 @@ void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
 {
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_exit_cpufreq_table)
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
-	if (arch_clock->clk_exit_cpufreq_table)
-		arch_clock->clk_exit_cpufreq_table(table);
+	arch_clock->clk_exit_cpufreq_table(table);
 	spin_unlock_irqrestore(&clockfw_lock, flags);
 }
 #endif
@@ -429,6 +437,9 @@ static int __init clk_disable_unused(void)
 	struct clk *ck;
 	unsigned long flags;
 
+	if (!arch_clock || !arch_clock->clk_disable_unused)
+		return 0;
+
 	pr_info("clock: disabling unused clocks to save power\n");
 	list_for_each_entry(ck, &clocks, node) {
 		if (ck->ops == &clkops_null)
@@ -438,8 +449,7 @@ static int __init clk_disable_unused(void)
 			continue;
 
 		spin_lock_irqsave(&clockfw_lock, flags);
-		if (arch_clock->clk_disable_unused)
-			arch_clock->clk_disable_unused(ck);
+		arch_clock->clk_disable_unused(ck);
 		spin_unlock_irqrestore(&clockfw_lock, flags);
 	}
 

^ permalink raw reply related

* [PATCH 3/5] OMAP2xxx: clock: fix interface clocks and clockdomains for modules in the WKUP domain
From: Paul Walmsley @ 2011-02-17  4:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110217041437.16009.52336.stgit@twilight.localdomain>

The parent of the interface clocks for GPTIMER1, MPU_WDT,
SYNCTIMER_32K, SCM, WDT1, and the ICR (2430 only) were all listed as
being l4_ck.  This isn't accurate; these modules exist inside the WKUP
domain, and the interface clock to these modules runs at the SYS_CLK
rate rather than the CORE L4 rate.

So, create a new clock "wu_l4_ick", similar to the OMAP3
"wkup_l4_ick", that serves as the parent for these clocks.

Also, these clocks were listed as existing inside core_l4_clkdm;
wkup_clkdm is probably more accurate.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock2420_data.c |   33 +++++++++++++++++++-----------
 arch/arm/mach-omap2/clock2430_data.c |   37 +++++++++++++++++++++-------------
 2 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index fd5ba90..6e9d20d 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -826,6 +826,14 @@ static struct clk dss_54m_fck = {	/* Alt clk used in power management */
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk wu_l4_ick = {
+	.name		= "wu_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
 /*
  * CORE power domain ICLK & FCLK defines.
  * Many of the these can have more than one possible parent. Entries
@@ -847,8 +855,8 @@ static const struct clksel omap24xx_gpt_clksel[] = {
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1300,8 +1308,8 @@ static struct clk uart3_fck = {
 static struct clk gpios_ick = {
 	.name		= "gpios_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1320,8 +1328,8 @@ static struct clk gpios_fck = {
 static struct clk mpu_wdt_ick = {
 	.name		= "mpu_wdt_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1340,9 +1348,9 @@ static struct clk mpu_wdt_fck = {
 static struct clk sync_32k_ick = {
 	.name		= "sync_32k_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1351,8 +1359,8 @@ static struct clk sync_32k_ick = {
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1361,9 +1369,9 @@ static struct clk wdt1_ick = {
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1825,6 +1833,7 @@ static struct omap_clk omap2420_clks[] = {
 	/* L4 domain clocks */
 	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),
 	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_242X),
 	/* virtual meta-group clock */
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
 	/* general l4 interface ck, multi-parent functional clk */
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 0d069ef..3378dbf 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -814,6 +814,14 @@ static struct clk dss_54m_fck = {	/* Alt clk used in power management */
 	.recalc		= &followparent_recalc,
 };
 
+static struct clk wu_l4_ick = {
+	.name		= "wu_l4_ick",
+	.ops		= &clkops_null,
+	.parent		= &sys_ck,
+	.clkdm_name	= "wkup_clkdm",
+	.recalc		= &followparent_recalc,
+};
+
 /*
  * CORE power domain ICLK & FCLK defines.
  * Many of the these can have more than one possible parent. Entries
@@ -835,8 +843,8 @@ static const struct clksel omap24xx_gpt_clksel[] = {
 static struct clk gpt1_ick = {
 	.name		= "gpt1_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1380,8 +1388,8 @@ static struct clk uart3_fck = {
 static struct clk gpios_ick = {
 	.name		= "gpios_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1400,8 +1408,8 @@ static struct clk gpios_fck = {
 static struct clk mpu_wdt_ick = {
 	.name		= "mpu_wdt_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1420,9 +1428,9 @@ static struct clk mpu_wdt_fck = {
 static struct clk sync_32k_ick = {
 	.name		= "sync_32k_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1431,8 +1439,8 @@ static struct clk sync_32k_ick = {
 static struct clk wdt1_ick = {
 	.name		= "wdt1_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1441,9 +1449,9 @@ static struct clk wdt1_ick = {
 static struct clk omapctrl_ick = {
 	.name		= "omapctrl_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
 	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1452,8 +1460,8 @@ static struct clk omapctrl_ick = {
 static struct clk icr_ick = {
 	.name		= "icr_ick",
 	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
+	.parent		= &wu_l4_ick,
+	.clkdm_name	= "wkup_clkdm",
 	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
 	.recalc		= &followparent_recalc,
@@ -1914,6 +1922,7 @@ static struct omap_clk omap2430_clks[] = {
 	/* L4 domain clocks */
 	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),
 	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_243X),
 	/* virtual meta-group clock */
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
 	/* general l4 interface ck, multi-parent functional clk */

^ permalink raw reply related

* [PATCH 2/5] OMAP2xxx: clock: fix low-frequency oscillator clock rate
From: Paul Walmsley @ 2011-02-17  4:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110217041437.16009.52336.stgit@twilight.localdomain>

The OMAP2420/2430 external 32-kHz low-frequency oscillator is a 32768
Hz oscillator, not a 32,000 Hz oscillator[1][2].  Fix this in the clock
tree.

Signed-off-by: Paul Walmsley <paul@pwsan.com>

1. OMAP2420/22 Multimedia Processor Data Manual, Version P [SWPS019P],
   section 5.1.4 "External 32-kHz CMOS Clock" (note that it refers to
   a "32.768-kHz" clock; this presumably should be "32.768-KHz")

2. OMAP2430 Multimedia Processor ES2.1 Data Manual, Version V [SWPS023V],
   section 5.1.4 "External 32-kHz CMOS Clock" (note that it refers to
   a "32.768-kHz" clock; this presumably should be "32.768-KHz")
---
 arch/arm/mach-omap2/clock2420_data.c |    2 +-
 arch/arm/mach-omap2/clock2430_data.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 693a0a8..fd5ba90 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -55,7 +55,7 @@
 static struct clk func_32k_ck = {
 	.name		= "func_32k_ck",
 	.ops		= &clkops_null,
-	.rate		= 32000,
+	.rate		= 32768,
 	.clkdm_name	= "wkup_clkdm",
 };
 
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index f00f52e..0d069ef 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -55,7 +55,7 @@
 static struct clk func_32k_ck = {
 	.name		= "func_32k_ck",
 	.ops		= &clkops_null,
-	.rate		= 32000,
+	.rate		= 32768,
 	.clkdm_name	= "wkup_clkdm",
 };
 

^ permalink raw reply related


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