Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] PRUSS UIO driver support
From: Pratheesh Gangadhar @ 2011-02-24 14:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298556402-26456-1-git-send-email-pratheesh@ti.com>

This patch implements PRUSS (Programmable Real-time Unit Sub System)
UIO driver which exports SOC resources associated with PRUSS like
I/O, memories and IRQs to user space. PRUSS is dual 32-bit RISC
processors which is efficient in performing embedded tasks that
require manipulation of packed memory mapped data structures and
efficient in handling system events that have tight real time
constraints. This driver is currently supported on Texas Instruments
DA850, AM18xx and OMAPL1-38 devices.
For example, PRUSS runs firmware for real-time critical industrial
communication data link layer and communicates with application stack
running in user space via shared memory and IRQs.

Signed-off-by: Pratheesh Gangadhar <pratheesh@ti.com>
---
 drivers/uio/Kconfig     |   17 ++++
 drivers/uio/Makefile    |    1 +
 drivers/uio/uio_pruss.c |  216 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 drivers/uio/uio_pruss.c

diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index bb44079..6f3ea9b 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -94,4 +94,21 @@ config UIO_NETX
 	  To compile this driver as a module, choose M here; the module
 	  will be called uio_netx.
 
+config UIO_PRUSS
+	tristate "Texas Instruments PRUSS driver"
+	depends on ARCH_DAVINCI_DA850
+	help
+	  PRUSS driver for OMAPL138/DA850/AM18XX devices
+	  PRUSS driver requires user space components, examples and user space
+	  driver is available from below SVN repo - you may use anonymous login
+
+	  https://gforge.ti.com/gf/project/pru_sw/
+
+	  More info on API is available at below wiki
+
+	  http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called uio_pruss.
+
 endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 18fd818..d4dd9a5 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_UIO_AEC)	+= uio_aec.o
 obj-$(CONFIG_UIO_SERCOS3)	+= uio_sercos3.o
 obj-$(CONFIG_UIO_PCI_GENERIC)	+= uio_pci_generic.o
 obj-$(CONFIG_UIO_NETX)	+= uio_netx.o
+obj-$(CONFIG_UIO_PRUSS)         += uio_pruss.o
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
new file mode 100644
index 0000000..bb92941
--- /dev/null
+++ b/drivers/uio/uio_pruss.c
@@ -0,0 +1,216 @@
+/*
+ * Programmable Real-Time Unit Sub System (PRUSS) UIO driver (uio_pruss)
+ *
+ * This driver exports PRUSS host event out interrupts and PRUSS, L3 RAM,
+ * and DDR RAM to user space for applications interacting with PRUSS firmware
+ *
+ * Copyright (C) 2010-11 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#define DRV_NAME "pruss"
+#define DRV_VERSION "0.50"
+
+/*
+ * Host event IRQ numbers from PRUSS - PRUSS can generate upto 8 interrupt
+ * events to AINTC of ARM host processor - which can be used for IPC b/w PRUSS
+ * firmware and user space application, async notification from PRU firmware
+ * to user space application
+ * 3	PRU_EVTOUT0
+ * 4	PRU_EVTOUT1
+ * 5	PRU_EVTOUT2
+ * 6	PRU_EVTOUT3
+ * 7	PRU_EVTOUT4
+ * 8	PRU_EVTOUT5
+ * 9	PRU_EVTOUT6
+ * 10	PRU_EVTOUT7
+*/
+
+#define MAX_PRUSS_EVT			8
+
+#define	PINTC_HIPIR			0x4900
+#define	HIPIR_NOPEND			0x80000000
+#define	PINTC_HIER			0x5500
+
+static struct clk *pruss_clk;
+static struct uio_info *info;
+static dma_addr_t ddr_paddr;
+static void *ddr_vaddr, *prussio_vaddr;
+
+static irqreturn_t pruss_handler(int irq, struct uio_info *dev_info)
+{
+	void __iomem *base = dev_info->mem[0].internal_addr;
+	void __iomem *intren_reg = base + PINTC_HIER;
+	void __iomem *intrstat_reg = base + PINTC_HIPIR + ((irq - 1) << 2);
+	int val = ioread32(intren_reg), intr_mask = (1 << (irq - 1));
+
+	/* Is interrupt enabled and active ? */
+	if (!(val & intr_mask) && (ioread32(intrstat_reg) & HIPIR_NOPEND))
+		return IRQ_NONE;
+
+	/* Disable interrupt */
+	iowrite32((val & ~intr_mask), intren_reg);
+	return IRQ_HANDLED;
+}
+
+static void pruss_cleanup(struct platform_device *dev, struct uio_info *info)
+{
+	struct uio_info *p = info;
+	int cnt;
+
+	for (cnt = 0; cnt < MAX_PRUSS_EVT; cnt++, p++) {
+		uio_unregister_device(p);
+		kfree(p->name);
+	}
+	iounmap(prussio_vaddr);
+	if (ddr_vaddr)
+		dma_free_coherent(&dev->dev, info->mem[2].size,
+			info->mem[2].internal_addr, info->mem[2].addr);
+	kfree(info);
+	clk_put(pruss_clk);
+}
+
+static int __devinit pruss_probe(struct platform_device *dev)
+{
+	struct uio_info *p;
+	int ret = -ENODEV, cnt = 0, len;
+	struct resource *regs_prussio, *regs_l3ram, *regs_ddr;
+
+	info = kzalloc(sizeof(struct uio_info) * MAX_PRUSS_EVT, GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	/* Power on PRU in case its not done as part of boot-loader */
+	pruss_clk = clk_get(&dev->dev, "pruss");
+	if (IS_ERR(pruss_clk)) {
+		dev_err(&dev->dev, "Failed to get clock\n");
+		kfree(info);
+		ret = PTR_ERR(pruss_clk);
+		return ret;
+	} else {
+		clk_enable(pruss_clk);
+	}
+
+	regs_prussio = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!regs_prussio) {
+		dev_err(&dev->dev, "No PRUSS I/O resource specified\n");
+		goto out_free;
+	}
+
+	regs_l3ram = platform_get_resource(dev, IORESOURCE_MEM, 1);
+	if (!regs_l3ram) {
+		dev_err(&dev->dev, "No L3 RAM resource specified\n");
+		goto out_free;
+	}
+
+	regs_ddr = platform_get_resource(dev, IORESOURCE_MEM, 2);
+	if (!regs_ddr) {
+		dev_err(&dev->dev, "No External RAM resource specified\n");
+		goto out_free;
+	}
+
+	if (!regs_prussio->start || !regs_l3ram->start) {
+		dev_err(&dev->dev, "Invalid memory resource\n");
+		goto out_free;
+	}
+	len = resource_size(regs_ddr);
+	ddr_vaddr =
+	dma_alloc_coherent(&dev->dev, len, &ddr_paddr, GFP_KERNEL | GFP_DMA);
+	if (!ddr_vaddr) {
+		dev_err(&dev->dev, "Could not allocate external memory\n");
+		goto out_free;
+	}
+	len = resource_size(regs_prussio);
+	prussio_vaddr = ioremap(regs_prussio->start, len);
+	if (!prussio_vaddr) {
+		dev_err(&dev->dev, "Can't remap PRUSS I/O  address range\n");
+		goto out_free;
+	}
+
+	for (cnt = 0, p = info; cnt < MAX_PRUSS_EVT; cnt++, p++) {
+		p->mem[0].internal_addr = prussio_vaddr;
+		p->mem[0].addr = regs_prussio->start;
+		p->mem[0].size = resource_size(regs_prussio);
+		p->mem[0].memtype = UIO_MEM_PHYS;
+
+		p->mem[1].addr = regs_l3ram->start;
+		p->mem[1].size = resource_size(regs_l3ram);
+		p->mem[1].memtype = UIO_MEM_PHYS;
+
+		p->mem[2].internal_addr = ddr_vaddr;
+		p->mem[2].addr = ddr_paddr;
+		p->mem[2].size = resource_size(regs_ddr);
+		p->mem[2].memtype = UIO_MEM_PHYS;
+
+		p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt);
+		p->version = "0.50";
+
+		/* Register PRUSS IRQ lines */
+		p->irq = IRQ_DA8XX_EVTOUT0 + cnt;
+		p->handler = pruss_handler;
+
+		ret = uio_register_device(&dev->dev, p);
+
+		if (ret < 0)
+			goto out_free;
+	}
+
+	platform_set_drvdata(dev, info);
+	return 0;
+
+out_free:
+	pruss_cleanup(dev, info);
+	return ret;
+}
+
+static int __devexit pruss_remove(struct platform_device *dev)
+{
+	struct uio_info *info = platform_get_drvdata(dev);
+
+	pruss_cleanup(dev, info);
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+static struct platform_driver pruss_driver = {
+	.probe = pruss_probe,
+	.remove = __devexit_p(pruss_remove),
+	.driver = {
+		   .name = DRV_NAME,
+		   .owner = THIS_MODULE,
+		   },
+};
+
+static int __init pruss_init_module(void)
+{
+	return platform_driver_register(&pruss_driver);
+}
+
+module_init(pruss_init_module);
+
+static void __exit pruss_exit_module(void)
+{
+	platform_driver_unregister(&pruss_driver);
+}
+
+module_exit(pruss_exit_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Amit Chatterjee <amit.chatterjee@ti.com>");
+MODULE_AUTHOR("Pratheesh Gangadhar <pratheesh@ti.com>");
-- 
1.6.0.6

^ permalink raw reply related

* [PATCH v4 0/2] Add PRUSS UIO driver support
From: Pratheesh Gangadhar @ 2011-02-24 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series add support for PRUSS (Programmable Real-time Unit Sub
System) UIO driver in Texas Instruments DA850, AM18xx and OMAPL1-38 processors.
PRUSS is programmable RISC core which can be used to implement Soft IPs
(eg:- DMA, CAN, UART,SmartCard) and Industrial communications data link layers
(eg:- PROFIBUS). UIO driver exposes PRUSS resources like memory and interrupts 
to user space application.PRUSS UIO application API can be used to control PRUs
 in PRUSS, setup PRU INTC, load firmware to PRUs and implement IPC between Host
 processor and PRUs. More information on PRUSS and UIO linux user space API 
available in the links below

http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit_Subsystem
http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader
http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader_API_Guide

Pratheesh Gangadhar (2):
  PRUSS UIO driver support
  Defines DA850/AM18xx/OMAPL1-38 SOC resources used by PRUSS UIO driver

 arch/arm/mach-davinci/board-da850-evm.c    |    4 +
 arch/arm/mach-davinci/da850.c              |   35 +++++
 arch/arm/mach-davinci/devices-da8xx.c      |   73 ++++++++++
 arch/arm/mach-davinci/include/mach/da8xx.h |    3 +
 drivers/uio/Kconfig                        |   17 +++
 drivers/uio/Makefile                       |    1 +
 drivers/uio/uio_pruss.c                    |  216 ++++++++++++++++++++++++++++
 7 files changed, 349 insertions(+), 0 deletions(-)
 create mode 100644 drivers/uio/uio_pruss.c

^ permalink raw reply

* [PATCH v3 1/2] PRUSS UIO driver support
From: TK, Pratheesh Gangadhar @ 2011-02-24 13:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110223173724.GA2801@local>



> -----Original Message-----
> From: Hans J. Koch [mailto:hjk at hansjkoch.de]
> Sent: Wednesday, February 23, 2011 11:07 PM
> To: TK, Pratheesh Gangadhar
> Cc: davinci-linux-open-source at linux.davincidsp.com; hjk at hansjkoch.de;
> gregkh at suse.de; Chatterjee, Amit; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/2] PRUSS UIO driver support
> 
> On Wed, Feb 23, 2011 at 07:22:40PM +0530, Pratheesh Gangadhar wrote:
> > This patch implements PRUSS (Programmable Real-time Unit Sub System)
> > UIO driver which exports SOC resources associated with PRUSS like
> > I/O, memories and IRQs to user space. PRUSS is dual 32-bit RISC
> > processors which is efficient in performing embedded tasks that
> > require manipulation of packed memory mapped data structures and
> > efficient in handling system events that have tight real time
> > constraints. This driver is currently supported on Texas Instruments
> > DA850, AM18xx and OMAPL1-38 devices.
> > For example, PRUSS runs firmware for real-time critical industrial
> > communication data link layer and communicates with application stack
> > running in user space via shared memory and IRQs.
> >
> > Signed-off-by: Pratheesh Gangadhar <pratheesh@ti.com>
> > ---
> >  drivers/uio/Kconfig     |   17 ++++
> >  drivers/uio/Makefile    |    1 +
> >  drivers/uio/uio_pruss.c |  223
> +++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 241 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/uio/uio_pruss.c
> >
> 
> [...]
> 
> > +
> > +static int __devinit pruss_probe(struct platform_device *dev)
> > +{
> > +	int ret = -ENODEV, count = 0;
> > +	struct resource *regs_prussio, *regs_l3ram, *regs_ddr;
> > +	struct uio_info *p;
> > +
> > +	info = kzalloc(sizeof(struct uio_info) * MAX_PRUSS_EVTOUT_INSTANCE,
> > +		       GFP_KERNEL);
> > +	if (!info)
> > +		return -ENOMEM;
> > +
> > +	/* Power on PRU in case its not done as part of boot-loader */
> > +	pruss_clk = clk_get(&dev->dev, "pruss");
> > +	if (IS_ERR(pruss_clk)) {
> > +		dev_err(&dev->dev, "Failed to get clock\n");
> > +		ret = PTR_ERR(pruss_clk);
> > +		return ret;
> 
> You leak memory here. What about freeing "info"?

Ok. Will fix.

Thanks,
Pratheesh

^ permalink raw reply

* [PATCH v3 1/2] PRUSS UIO driver support
From: TK, Pratheesh Gangadhar @ 2011-02-24 13:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1102232153500.2701@localhost6.localdomain6>


> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: Thursday, February 24, 2011 2:24 AM
> To: Sergei Shtylyov
> Cc: TK, Pratheesh Gangadhar; davinci-linux-open-
> source at linux.davincidsp.com; Chatterjee, Amit; gregkh at suse.de; linux-
> kernel at vger.kernel.org; hjk at hansjkoch.de; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/2] PRUSS UIO driver support
> 
> On Wed, 23 Feb 2011, Sergei Shtylyov wrote:
> > Hello.
> >
> > On 23-02-2011 23:25, Thomas Gleixner wrote:
> >
> > > > +	prussio_virt_addr =
> > > > +	    ioremap(regs_prussio->start,
> > > > +		    regs_prussio->end - regs_prussio->start + 1);
> >
> > > Either make those variable names shorter or do:
> >
> > >         len = regs_prussio->end - regs_prussio->start + 1;
> >
> >    Or even:
> >
> > 	len = resource_size(regs_prussio);
> >
> > >         prussio_virt_addr = ioremap(regs_prussio->start, len);
> 
> Good point. Forgot about that one :)
> 
Thanks will do this.

Pratheesh

^ permalink raw reply

* [PATCH v3 1/2] PRUSS UIO driver support
From: TK, Pratheesh Gangadhar @ 2011-02-24 13:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1102232057260.2701@localhost6.localdomain6>


> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: Thursday, February 24, 2011 1:56 AM
> To: TK, Pratheesh Gangadhar
> Cc: davinci-linux-open-source at linux.davincidsp.com; hjk at hansjkoch.de;
> gregkh at suse.de; Chatterjee, Amit; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/2] PRUSS UIO driver support
> 
> On Wed, 23 Feb 2011, Pratheesh Gangadhar wrote:
> 
> Is it actually too much of an hassle to cc the people who spent their
> time to review previous versions of your patch ?
> 
Sorry. Will do...
> > +struct clk *pruss_clk;
> > +struct uio_info *info;
> > +void *ddr_virt_addr = NULL, *prussio_virt_addr = NULL;
> 
> Grrr. We do not initialize with NULL.
> 
> > +dma_addr_t ddr_phy_addr;
> 
> Also all of these want to be static.
> 
Ok.
> 
> > +		uio_unregister_device(p);
> > +		kfree(p->name);
> > +	}
> > +	iounmap(prussio_virt_addr);
> > +	dma_free_coherent(&dev->dev, info[0].mem[2].size,
> > +			  info[0].mem[2].internal_addr, info[0].mem[2].addr);
> 
> You sure, that iounmap and dma_free_coherent are too happy about being
> called with NULL pointers?
> 
For iounmap its ok, not ok for dma_free_coherent. Will fix.
> > +
> > +	kfree(info);
> > +	clk_put(pruss_clk);
> > +}
> > +
> > +static int __devinit pruss_probe(struct platform_device *dev)
> > +{
> > +	int ret = -ENODEV, count = 0;
> > +	struct resource *regs_prussio, *regs_l3ram, *regs_ddr;
> > +	struct uio_info *p;
> > +
> > +	info = kzalloc(sizeof(struct uio_info) * MAX_PRUSS_EVTOUT_INSTANCE,
> > +		       GFP_KERNEL);
> > +	if (!info)
> > +		return -ENOMEM;
> > +
> > +	/* Power on PRU in case its not done as part of boot-loader */
> > +	pruss_clk = clk_get(&dev->dev, "pruss");
> > +	if (IS_ERR(pruss_clk)) {
> > +		dev_err(&dev->dev, "Failed to get clock\n");
> > +		ret = PTR_ERR(pruss_clk);
> > +		return ret;
> 
> Memory leak.
Will fix.
 

Thanks,
Pratheesh

^ permalink raw reply

* [PATCH v3] mmc: mxs-mmc: add mmc host driver for i.MX23/28
From: Shawn Guo @ 2011-02-24 13:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110222080905.GB16141@S2101-09.ap.freescale.net>

Please ignore the message which is the one I sent a few days ago
and I thought it did not get through.

On Tue, Feb 22, 2011 at 04:09:06PM +0800, Shawn Guo wrote:
> Hi Wolfram,
> 
> On Mon, Feb 21, 2011 at 06:40:16PM +0100, Wolfram Sang wrote:
> > Shawn,
> > 
> > On Mon, Feb 21, 2011 at 06:35:28PM +0800, Shawn Guo wrote:
> > > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > > The driver calls into mxs-dma via generic dmaengine api for both pio
> > > and data transfer.
> > > 
> > > Thanks Chris Ball for the indentation patch.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > > Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> > 
> > What throughput rates do you get on a mx28-regulated slot serving a card
> > at 50Mhz? This is poor here (55kb/s) while it is OK at 25Mhz. Could be a
> 
> To make sure we are on the same page, can you share me the test you
> ran?  And I can give it a try on my board.
> 
> > board issue though (or we can fix it later), rest works fine, thus:
> > 
> > Tested-by: Wolfram Sang <w.sang@pengutronix.de>
> > 
> 
> -- 
> Regards,
> Shawn
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Regards,
Shawn

^ permalink raw reply

* [PATCH V3 0/5] sdhci-esdhc-imx: use gpio for write protection and card detection
From: Wolfram Sang @ 2011-02-24 13:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87k4gp3bl1.fsf@lebrac.rtp-net.org>

> I'm getting a hard freeze on my efika sb and mx once I remove the
> unconditional BROKEN_CARD_DETECTION flag. I'm still investigating the
> issue. I'll keep you informed if I find something.

Hmm, this is probably an unhandled interrupt. Will see if I can get the
efika here...

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110224/8852c4d8/attachment.sig>

^ permalink raw reply

* [PATCH] ldp: Fix regulator mapping for ads7846 TS controller
From: Rajendra Nayak @ 2011-02-24 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

On the OMAP3430LDP board, the ads7846 touchscreen controller
is powered by VAUX1 regulator (supplying 3.0v).
Fix this mapping in the board file, and hence prevent
the ads7846 driver init to fail with the below error..

ads7846 spi1.0: unable to get regulator: -19

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/board-ldp.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index a3fae56..9a99cad 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -329,6 +329,26 @@ static struct regulator_init_data ldp_vmmc1 = {
 	.consumer_supplies	= &ldp_vmmc1_supply,
 };
 
+/* ads7846 on SPI */
+static struct regulator_consumer_supply ldp_vaux1_supplies[] = {
+	REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+/* VAUX1 */
+static struct regulator_init_data ldp_vaux1 = {
+	.constraints = {
+		.min_uV			= 3000000,
+		.max_uV			= 3000000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies		= ARRAY_SIZE(ldp_vaux1_supplies),
+	.consumer_supplies		= ldp_vaux1_supplies,
+};
+
 static struct twl4030_platform_data ldp_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
@@ -337,6 +357,7 @@ static struct twl4030_platform_data ldp_twldata = {
 	.madc		= &ldp_madc_data,
 	.usb		= &ldp_usb_data,
 	.vmmc1		= &ldp_vmmc1,
+	.vaux1		= &ldp_vaux1,
 	.gpio		= &ldp_gpio_data,
 	.keypad		= &ldp_kp_twl4030_data,
 };
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 5/5] ARM: msm: update GPIO chained IRQ handler to use EOI in parent chip
From: Thomas Gleixner @ 2011-02-24 12:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D65A4BA.8030206@codeaurora.org>

On Wed, 23 Feb 2011, Abhijeet Dharmapurikar wrote:

> Will Deacon wrote:
> > The chained GPIO IRQ handler on MSM8x60 calls ->ack on the parent chip
> > after handling the interrupt.
> > 
> > This patch updates the code to use ->irq_eoi now that the GIC has moved
> > to using the fasteoi flow model.
> > 
> > Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > ---
> >  arch/arm/mach-msm/gpio-v2.c |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c
> > index 0de19ec..04fb411 100644
> > --- a/arch/arm/mach-msm/gpio-v2.c
> > +++ b/arch/arm/mach-msm/gpio-v2.c
> > @@ -318,7 +318,7 @@ static void msm_summary_irq_handler(unsigned int irq,
> > struct irq_desc *desc)
> >  			generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
> >  							   i));
> >  	}
> > -	desc->chip->ack(irq);
> > +	desc->chip->irq_eoi(irq);
> 
> should be dec->chip->irq_eoi(&desc->irq_data);

Nope, it should do:

      struct irq_chip *chip = get_irq_desc_chip(desc);

      chip->irq_eoi();

Thanks,

	tglx

^ permalink raw reply

* [PATCH 0/3] OMAP2+: voltage: first pass at cleanup/reorganization
From: Rajendra Nayak @ 2011-02-24 11:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110221020231.7598.14024.stgit@twilight.localdomain>

Hi Paul,

> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org
[mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf
> Of Paul Walmsley
> Sent: Monday, February 21, 2011 7:39 AM
> To: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Cc: khilman at ti.com; nm at ti.com; b-cousson at ti.com; mturquette at ti.com
> Subject: [PATCH 0/3] OMAP2+: voltage: first pass at
cleanup/reorganization
>
> Hello,
>
> this patch set does an initial round of cleanup on the OMAP "voltage"
code
> in arch/arm/mach-omap2/voltage.c.  As part of this process, the header
files
> for the voltage code and SmartReflex are moved into arch/arm/mach-omap2,
since
> they are currently OMAP2+-specific.
>
> There is still quite a bit of cleanup left to do; hopefully someone else
will
> get to it before I do.  More details are in the last patch.
>
> This series was built-tested for an OSK5912-specific config,
omap1_defconfig,
> a N800-specific config, omap2plus_defconfig, an OMAP3-specific config,
and
> an OMAP4-specific config.  It was boot-tested on an OMAP35xx
Beagleboard.
> Further testing assistance is, of course, appreciated.

I found these abort on my 4430SDP. The below changes I found
are needed for it to bootup..
I tested the 'integration-2.6.39' branch of
git://git.pwsan.com/linux-integration and the patch is
based on this branch.

---

^ permalink raw reply

* [PATCH V3 0/5] sdhci-esdhc-imx: use gpio for write protection and card detection
From: Arnaud Patard (Rtp) @ 2011-02-24 11:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>

Wolfram Sang <w.sang@pengutronix.de> writes:

Hi,

> Take #3, changes:
>
> * also intercept calls to SDHCI_SIGNAL_ENABLE (needed on mx25)
> * remove unconditional BROKEN_CARD_DETECTION (leftover)
> * improved kernel-doc about unused GPIO
> * added tags from Eric
>
> Tested now by me and Marc on mx35, Eric on mx25/35/51. Arnaud, did you have a
> chance to retest on mx51? What about the FSL guys? :)

I'm getting a hard freeze on my efika sb and mx once I remove the
unconditional BROKEN_CARD_DETECTION flag. I'm still investigating the
issue. I'll keep you informed if I find something.

Arnaud

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Felipe Balbi @ 2011-02-24 11:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTinh_a81sELdF19ob0A0KbLR+9MUnb0+283NxO2b@mail.gmail.com>

On Thu, Feb 24, 2011 at 01:26:05PM +0200, David Cohen wrote:
> On Thu, Feb 24, 2011 at 10:35 AM, Felipe Balbi <balbi@ti.com> wrote:
> > Hi,
> >
> > On Wed, Feb 23, 2011 at 10:09:05PM +0200, Sakari Ailus wrote:
> >> > In OMAP4 the cortex M3 is a double core processor and as each core is
> >> > running they own version of the RTOS we threat them independently. So
> >> > our driver which controls the remote processor sees two processor but
> >> > both use the same iommu hw. When a iommu fault happens, at this
> >> > moment, it is consider as a faltal error and it is no managed to
> >> > recover and continue, instead a restart of the processor is needed, if
> >> > the fault happens in core0 we need to reset core1 too and vice versa.
> >> > if the iommu would support several user callbacks, we can register the
> >> > callback which resets core0 and also the callback which resets core1
> >> > and treat them as totally independent processors. Also we have an
> >> > error event notifier driver, which is only in charge of notifying
> >> > error events to userspace, so we would have multiple callbacks we
> >> > could do this
> >>
> >> The original purpose of the patch, as far as I understand, is to allow
> >> getting useful information for debugging purposes should an iommu fault
> >> happen.
> >>
> >> Also, I'm not sure it's necessarily a good idea to just go and reset
> >> the M3 cores in case an iommu fault happens --- this is very probably a
> >> grave bug in the software running on those M3s. It should be fixed
> >> instead of just hiding it. There will be consequences to host side as
> >
> > I have to agree here. Besides the fact that multiple callbacks is
> > outside the scope of this patch.
> 
> This patch is already acked. What about leave it as it is and discuss
> multiple callbacks before release a new patch to support it?

fine by me ;-)

-- 
balbi

^ permalink raw reply

* [PATCH 1/1] davinci: changed SRAM allocator to shared ram.
From: Nori, Sekhar @ 2011-02-24 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <886E26C48DE446C3937D89ECF86030B2@subhasishg>

Hi Subhasish,

On Thu, Feb 24, 2011 at 15:54:56, Subhasish Ghosh wrote:
> --------------------------------------------------
> From: "Nori, Sekhar" <nsekhar@ti.com>
> Sent: Wednesday, February 23, 2011 9:00 PM
> To: "Subhasish Ghosh" <subhasish@mistralsolutions.com>; 
> <davinci-linux-open-source@linux.davincidsp.com>
> Cc: <linux-arm-kernel@lists.infradead.org>; "Watkins, Melissa" 
> <m-watkins@ti.com>; <sachi@mistralsolutions.com>; "Kevin Hilman" 
> <khilman@deeprootsystems.com>; "Russell King" <linux@arm.linux.org.uk>; 
> "Michael Williamson" <michael.williamson@criticallink.com>; "Chemparathy, 
> Cyril" <cyril@ti.com>; "Sergei Shtylyov" <sshtylyov@ru.mvista.com>; "open 
> list" <linux-kernel@vger.kernel.org>
> Subject: RE: [PATCH 1/1] davinci: changed SRAM allocator to shared ram.
> 
> > Hi Subhasish,
> >
> > On Fri, Feb 11, 2011 at 19:51:28, Subhasish Ghosh wrote:
> >> This patch modifies the sram allocator to allocate memory
> >> from the DA8XX shared RAM.
> >
> > It will be nice to know if you tried suspend-to-RAM
> > after this change and found it to be working.
> >
> 
> SG -- My file system is currently mounted from MMC.
>           Suspend to RAM seems to have bug with MMC.
>            (http://processors.wiki.ti.com/index.php/OMAP-L1_Linux_Drivers_Usage#Suspend-to-RAM)

You can try Kevin's suggestion here:

http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2011-January/021807.html

>           I had tried NFS earlier, but I think there is some problem with 
> NFS boot and udev with this kernel.

Anyway there are some problems reported with Ethernet
driver and suspend on the latest kernel. Folks inside
TI are working on it.

>            So, currently I will not be able to do it, but will try if I get 
> a chance.

How about using ramdisk?

Thanks,
Sekhar

> > Thanks,
> > Sekhar
> >
> >>
> >> Signed-off-by: Subhasish Ghosh <subhasish@mistralsolutions.com>
> >> ---
> >>  arch/arm/mach-davinci/da850.c              |    6 +++---
> >>  arch/arm/mach-davinci/include/mach/da8xx.h |    1 +
> >>  2 files changed, 4 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/arch/arm/mach-davinci/da850.c 
> >> b/arch/arm/mach-davinci/da850.c
> >> index 3443d97..8a4de97 100644
> >> --- a/arch/arm/mach-davinci/da850.c
> >> +++ b/arch/arm/mach-davinci/da850.c
> >> @@ -711,7 +711,7 @@ static struct map_desc da850_io_desc[] = {
> >>  },
> >>  {
> >>  .virtual = SRAM_VIRT,
> >> - .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
> >> + .pfn = __phys_to_pfn(DA8XX_SHARED_RAM_BASE),
> >>  .length = SZ_8K,
> >>  .type = MT_DEVICE
> >>  },
> >> @@ -1083,8 +1083,8 @@ static struct davinci_soc_info 
> >> davinci_soc_info_da850 = {
> >>  .gpio_irq = IRQ_DA8XX_GPIO0,
> >>  .serial_dev = &da8xx_serial_device,
> >>  .emac_pdata = &da8xx_emac_pdata,
> >> - .sram_dma = DA8XX_ARM_RAM_BASE,
> >> - .sram_len = SZ_8K,
> >> + .sram_dma = DA8XX_SHARED_RAM_BASE,
> >> + .sram_len = SZ_128K,
> >>  .reset_device = &da8xx_wdt_device,
> >>  };
> >>
> >> diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h 
> >> b/arch/arm/mach-davinci/include/mach/da8xx.h
> >> index cfcb223..c3c3339 100644
> >> --- a/arch/arm/mach-davinci/include/mach/da8xx.h
> >> +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
> >> @@ -70,6 +70,7 @@ extern unsigned int da850_max_speed;
> >>  #define DA8XX_AEMIF_CTL_BASE 0x68000000
> >>  #define DA8XX_DDR2_CTL_BASE 0xb0000000
> >>  #define DA8XX_ARM_RAM_BASE 0xffff0000
> >> +#define DA8XX_SHARED_RAM_BASE 0x80000000
> >>
> >>  void __init da830_init(void);
> >>  void __init da850_init(void);
> >> -- 
> >> 1.7.2.3
> >>
> >>
> > 
> 

^ permalink raw reply

* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: David Cohen @ 2011-02-24 11:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110224083518.GC3528@legolas.emea.dhcp.ti.com>

On Thu, Feb 24, 2011 at 10:35 AM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Wed, Feb 23, 2011 at 10:09:05PM +0200, Sakari Ailus wrote:
>> > In OMAP4 the cortex M3 is a double core processor and as each core is
>> > running they own version of the RTOS we threat them independently. So
>> > our driver which controls the remote processor sees two processor but
>> > both use the same iommu hw. When a iommu fault happens, at this
>> > moment, it is consider as a faltal error and it is no managed to
>> > recover and continue, instead a restart of the processor is needed, if
>> > the fault happens in core0 we need to reset core1 too and vice versa.
>> > if the iommu would support several user callbacks, we can register the
>> > callback which resets core0 and also the callback which resets core1
>> > and treat them as totally independent processors. Also we have an
>> > error event notifier driver, which is only in charge of notifying
>> > error events to userspace, so we would have multiple callbacks we
>> > could do this
>>
>> The original purpose of the patch, as far as I understand, is to allow
>> getting useful information for debugging purposes should an iommu fault
>> happen.
>>
>> Also, I'm not sure it's necessarily a good idea to just go and reset
>> the M3 cores in case an iommu fault happens --- this is very probably a
>> grave bug in the software running on those M3s. It should be fixed
>> instead of just hiding it. There will be consequences to host side as
>
> I have to agree here. Besides the fact that multiple callbacks is
> outside the scope of this patch.

This patch is already acked. What about leave it as it is and discuss
multiple callbacks before release a new patch to support it?

Br,

David

>
> --
> balbi
>

^ permalink raw reply

* [PATCH] OMAP4: voltage: Populate missing .vp/.vc_common pointers
From: Rajendra Nayak @ 2011-02-24 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

The common_data for vp and vc on OMAP4 is defined
but not hooked up with the corresponding
vp/vc_data.
This causes an abort at bootup on OMAP4, as the
framework api's assumes these to be present.

While here, also rename omap4_vp_data to
omap4_vp_common and omap4_vc_data to
omap4_vc_common to maintain consistency in
naming structs across all OMAPs.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/vc44xx_data.c |    5 ++++-
 arch/arm/mach-omap2/vp44xx_data.c |    5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/vc44xx_data.c
b/arch/arm/mach-omap2/vc44xx_data.c
index 548cb06..a98da8d 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -30,7 +30,7 @@
  * VC data common to 44xx chips
  * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
  */
-static const struct omap_vc_common_data omap4_vc_data = {
+static const struct omap_vc_common_data omap4_vc_common = {
 	.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
 	.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
 	.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
@@ -47,6 +47,7 @@ static const struct omap_vc_common_data omap4_vc_data =
{

 /* VC instance data for each controllable voltage line */
 struct omap_vc_instance_data omap4_vc_mpu_data = {
+	.vc_common = &omap4_vc_common,
 	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
 	.smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
 	.smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
@@ -55,6 +56,7 @@ struct omap_vc_instance_data omap4_vc_mpu_data = {
 };

 struct omap_vc_instance_data omap4_vc_iva_data = {
+	.vc_common = &omap4_vc_common,
 	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
 	.smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
 	.smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
@@ -63,6 +65,7 @@ struct omap_vc_instance_data omap4_vc_iva_data = {
 };

 struct omap_vc_instance_data omap4_vc_core_data = {
+	.vc_common = &omap4_vc_common,
 	.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
 	.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
 	.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
diff --git a/arch/arm/mach-omap2/vp44xx_data.c
b/arch/arm/mach-omap2/vp44xx_data.c
index 7b26f75..65d1ad6 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -31,7 +31,7 @@
  * VP data common to 44xx chips
  * XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
  */
-static const struct omap_vp_common_data omap4_vp_data = {
+static const struct omap_vp_common_data omap4_vp_common = {
 	.vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
 	.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
 	.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
@@ -56,6 +56,7 @@ static const struct omap_vp_prm_irqst_data
omap4_vp_mpu_prm_irqst_data = {
 };

 struct omap_vp_instance_data omap4_vp_mpu_data = {
+	.vp_common = &omap4_vp_common,
 	.vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
 	.vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
 	.vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
@@ -71,6 +72,7 @@ static const struct omap_vp_prm_irqst_data
omap4_vp_iva_prm_irqst_data = {
 };

 struct omap_vp_instance_data omap4_vp_iva_data = {
+	.vp_common = &omap4_vp_common,
 	.vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
 	.vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
 	.vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
@@ -86,6 +88,7 @@ static const struct omap_vp_prm_irqst_data
omap4_vp_core_prm_irqst_data = {
 };

 struct omap_vp_instance_data omap4_vp_core_data = {
+	.vp_common = &omap4_vp_common,
 	.vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
 	.vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
 	.vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
-- 
1.7.0.4

>
> This series is available from git://git.pwsan.com/linux-2.6 in the
> 'voltage_split_2.6.39' branch.
>
>
> - Paul
>
>
> ---
>
> voltage_split_2.6.39
>    text	   data	    bss	    dec	    hex	filename
> 5766071	 488104	5596920	11851095	 b4d557
vmlinux.omap2plus_defconfig.orig
> 5765631	 487848	5596920	11850399	 b4d29f
vmlinux.omap2plus_defconfig
>
>
> Paul Walmsley (3):
>       OMAP: smartreflex: move plat/smartreflex.h to
mach-omap2/smartreflex.h
>       OMAP: voltage: move plat/voltage.h to mach-omap2/voltage.h
>       OMAP2+: voltage: reorganize, split code from data
>
>
>  arch/arm/mach-omap2/Makefile                  |   20
>  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c    |    2
>  arch/arm/mach-omap2/omap_opp_data.h           |   12
>  arch/arm/mach-omap2/omap_twl.c                |    2
>  arch/arm/mach-omap2/opp3xxx_data.c            |   44 +
>  arch/arm/mach-omap2/opp4xxx_data.c            |   30 +
>  arch/arm/mach-omap2/pm.c                      |    2
>  arch/arm/mach-omap2/smartreflex-class3.c      |    2
>  arch/arm/mach-omap2/smartreflex.c             |    2
>  arch/arm/mach-omap2/smartreflex.h             |    3
>  arch/arm/mach-omap2/sr_device.c               |    4
>  arch/arm/mach-omap2/vc.h                      |   83 ++
>  arch/arm/mach-omap2/vc3xxx_data.c             |   63 ++
>  arch/arm/mach-omap2/vc44xx_data.c             |   72 ++
>  arch/arm/mach-omap2/voltage.c                 | 1019
+++++++------------------
>  arch/arm/mach-omap2/voltage.h                 |   66 ++
>  arch/arm/mach-omap2/voltagedomains3xxx_data.c |  104 +++
>  arch/arm/mach-omap2/voltagedomains44xx_data.c |  108 +++
>  arch/arm/mach-omap2/vp.h                      |  143 ++++
>  arch/arm/mach-omap2/vp3xxx_data.c             |   82 ++
>  arch/arm/mach-omap2/vp44xx_data.c             |   97 ++
>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    1
>  22 files changed, 1203 insertions(+), 758 deletions(-)
>  rename arch/arm/{plat-omap/include/plat/smartreflex.h =>
mach-omap2/smartreflex.h} (99%)
>  create mode 100644 arch/arm/mach-omap2/vc.h
>  create mode 100644 arch/arm/mach-omap2/vc3xxx_data.c
>  create mode 100644 arch/arm/mach-omap2/vc44xx_data.c
>  rename arch/arm/{plat-omap/include/plat/voltage.h =>
mach-omap2/voltage.h} (68%)
>  create mode 100644 arch/arm/mach-omap2/voltagedomains3xxx_data.c
>  create mode 100644 arch/arm/mach-omap2/voltagedomains44xx_data.c
>  create mode 100644 arch/arm/mach-omap2/vp.h
>  create mode 100644 arch/arm/mach-omap2/vp3xxx_data.c
>  create mode 100644 arch/arm/mach-omap2/vp44xx_data.c
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

--20cf30433eeccc95c2049d05ecaa
Content-Type: application/octet-stream; 
	name="0001-OMAP4-voltage-Populate-missing-.vp-.vc_common-pointe.patch"
Content-Disposition: attachment; 
	filename="0001-OMAP4-voltage-Populate-missing-.vp-.vc_common-pointe.patch"
Content-Transfer-Encoding: base64
X-Attachment-Id: 1b3fedf59da6051c_0.1

RnJvbSBlM2Q1ZTJiYjA5ZWNiN2E5NThjMWY3OWI4NmQxOTE3ZjBiZWNiOGQyIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBSYWplbmRyYSBOYXlhayA8cm5heWFrQHRpLmNvbT4KRGF0ZTog
VGh1LCAyNCBGZWIgMjAxMSAxNjo0MjoyNSArMDUzMApTdWJqZWN0OiBbUEFUQ0hdIE9NQVA0OiB2
b2x0YWdlOiBQb3B1bGF0ZSBtaXNzaW5nIC52cC8udmNfY29tbW9uIHBvaW50ZXJzCgpUaGUgY29t
bW9uX2RhdGEgZm9yIHZwIGFuZCB2YyBvbiBPTUFQNCBpcyBkZWZpbmVkCmJ1dCBub3QgaG9va2Vk
IHVwIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcKdnAvdmNfZGF0YS4KVGhpcyBjYXVzZXMgYW4gYWJv
cnQgYXQgYm9vdHVwIG9uIE9NQVA0LCBhcyB0aGUKZnJhbWV3b3JrIGFwaSdzIGFzc3VtZXMgdGhl
c2UgdG8gYmUgcHJlc2VudC4KCldoaWxlIGhlcmUsIGFsc28gcmVuYW1lIG9tYXA0X3ZwX2RhdGEg
dG8Kb21hcDRfdnBfY29tbW9uIGFuZCBvbWFwNF92Y19kYXRhIHRvCm9tYXA0X3ZjX2NvbW1vbiB0
byBtYWludGFpbiBjb25zaXN0ZW5jeSBpbgpuYW1pbmcgc3RydWN0cyBhY3Jvc3MgYWxsIE9NQVBz
LgoKU2lnbmVkLW9mZi1ieTogUmFqZW5kcmEgTmF5YWsgPHJuYXlha0B0aS5jb20+Ci0tLQogYXJj
aC9hcm0vbWFjaC1vbWFwMi92YzQ0eHhfZGF0YS5jIHwgICAgNSArKysrLQogYXJjaC9hcm0vbWFj
aC1vbWFwMi92cDQ0eHhfZGF0YS5jIHwgICAgNSArKysrLQogMiBmaWxlcyBjaGFuZ2VkLCA4IGlu
c2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvYXJjaC9hcm0vbWFjaC1v
bWFwMi92YzQ0eHhfZGF0YS5jIGIvYXJjaC9hcm0vbWFjaC1vbWFwMi92YzQ0eHhfZGF0YS5jCmlu
ZGV4IDU0OGNiMDYuLmE5OGRhOGQgMTAwNjQ0Ci0tLSBhL2FyY2gvYXJtL21hY2gtb21hcDIvdmM0
NHh4X2RhdGEuYworKysgYi9hcmNoL2FybS9tYWNoLW9tYXAyL3ZjNDR4eF9kYXRhLmMKQEAgLTMw
LDcgKzMwLDcgQEAKICAqIFZDIGRhdGEgY29tbW9uIHRvIDQ0eHggY2hpcHMKICAqIFhYWCBUaGlz
IHN0dWZmIHByZXN1bWFibHkgYmVsb25ncyBpbiB0aGUgdmMzeHh4LmMgb3IgdmMuYyBmaWxlLgog
ICovCi1zdGF0aWMgY29uc3Qgc3RydWN0IG9tYXBfdmNfY29tbW9uX2RhdGEgb21hcDRfdmNfZGF0
YSA9IHsKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb21hcF92Y19jb21tb25fZGF0YSBvbWFwNF92Y19j
b21tb24gPSB7CiAJLnNtcHNfc2FfcmVnID0gT01BUDRfUFJNX1ZDX1NNUFNfU0FfT0ZGU0VULAog
CS5zbXBzX3ZvbHJhX3JlZyA9IE9NQVA0X1BSTV9WQ19WQUxfU01QU19SQV9WT0xfT0ZGU0VULAog
CS5ieXBhc3NfdmFsX3JlZyA9IE9NQVA0X1BSTV9WQ19WQUxfQllQQVNTX09GRlNFVCwKQEAgLTQ3
LDYgKzQ3LDcgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBvbWFwX3ZjX2NvbW1vbl9kYXRhIG9tYXA0
X3ZjX2RhdGEgPSB7CiAKIC8qIFZDIGluc3RhbmNlIGRhdGEgZm9yIGVhY2ggY29udHJvbGxhYmxl
IHZvbHRhZ2UgbGluZSAqLwogc3RydWN0IG9tYXBfdmNfaW5zdGFuY2VfZGF0YSBvbWFwNF92Y19t
cHVfZGF0YSA9IHsKKwkudmNfY29tbW9uID0gJm9tYXA0X3ZjX2NvbW1vbiwKIAkuY21kdmFsX3Jl
ZyA9IE9NQVA0X1BSTV9WQ19WQUxfQ01EX1ZERF9NUFVfTF9PRkZTRVQsCiAJLnNtcHNfc2Ffc2hp
ZnQgPSBPTUFQNDQzMF9TQV9WRERfTVBVX0xfUFJNX1ZDX1NNUFNfU0FfU0hJRlQsCiAJLnNtcHNf
c2FfbWFzayA9IE9NQVA0NDMwX1NBX1ZERF9NUFVfTF9QUk1fVkNfU01QU19TQV9NQVNLLApAQCAt
NTUsNiArNTYsNyBAQCBzdHJ1Y3Qgb21hcF92Y19pbnN0YW5jZV9kYXRhIG9tYXA0X3ZjX21wdV9k
YXRhID0gewogfTsKIAogc3RydWN0IG9tYXBfdmNfaW5zdGFuY2VfZGF0YSBvbWFwNF92Y19pdmFf
ZGF0YSA9IHsKKwkudmNfY29tbW9uID0gJm9tYXA0X3ZjX2NvbW1vbiwKIAkuY21kdmFsX3JlZyA9
IE9NQVA0X1BSTV9WQ19WQUxfQ01EX1ZERF9JVkFfTF9PRkZTRVQsCiAJLnNtcHNfc2Ffc2hpZnQg
PSBPTUFQNDQzMF9TQV9WRERfSVZBX0xfUFJNX1ZDX1NNUFNfU0FfU0hJRlQsCiAJLnNtcHNfc2Ff
bWFzayA9IE9NQVA0NDMwX1NBX1ZERF9JVkFfTF9QUk1fVkNfU01QU19TQV9NQVNLLApAQCAtNjMs
NiArNjUsNyBAQCBzdHJ1Y3Qgb21hcF92Y19pbnN0YW5jZV9kYXRhIG9tYXA0X3ZjX2l2YV9kYXRh
ID0gewogfTsKIAogc3RydWN0IG9tYXBfdmNfaW5zdGFuY2VfZGF0YSBvbWFwNF92Y19jb3JlX2Rh
dGEgPSB7CisJLnZjX2NvbW1vbiA9ICZvbWFwNF92Y19jb21tb24sCiAJLmNtZHZhbF9yZWcgPSBP
TUFQNF9QUk1fVkNfVkFMX0NNRF9WRERfQ09SRV9MX09GRlNFVCwKIAkuc21wc19zYV9zaGlmdCA9
IE9NQVA0NDMwX1NBX1ZERF9DT1JFX0xfMF82X1NISUZULAogCS5zbXBzX3NhX21hc2sgPSBPTUFQ
NDQzMF9TQV9WRERfQ09SRV9MXzBfNl9NQVNLLApkaWZmIC0tZ2l0IGEvYXJjaC9hcm0vbWFjaC1v
bWFwMi92cDQ0eHhfZGF0YS5jIGIvYXJjaC9hcm0vbWFjaC1vbWFwMi92cDQ0eHhfZGF0YS5jCmlu
ZGV4IDdiMjZmNzUuLjY1ZDFhZDYgMTAwNjQ0Ci0tLSBhL2FyY2gvYXJtL21hY2gtb21hcDIvdnA0
NHh4X2RhdGEuYworKysgYi9hcmNoL2FybS9tYWNoLW9tYXAyL3ZwNDR4eF9kYXRhLmMKQEAgLTMx
LDcgKzMxLDcgQEAKICAqIFZQIGRhdGEgY29tbW9uIHRvIDQ0eHggY2hpcHMKICAqIFhYWCBUaGlz
IHN0dWZmIHByZXN1bWFibHkgYmVsb25ncyBpbiB0aGUgdnA0NHh4LmMgb3IgdnAuYyBmaWxlLgog
ICovCi1zdGF0aWMgY29uc3Qgc3RydWN0IG9tYXBfdnBfY29tbW9uX2RhdGEgb21hcDRfdnBfZGF0
YSA9IHsKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb21hcF92cF9jb21tb25fZGF0YSBvbWFwNF92cF9j
b21tb24gPSB7CiAJLnZwY29uZmlnX2Vycm9yb2Zmc2V0X3NoaWZ0ID0gT01BUDQ0MzBfRVJST1JP
RkZTRVRfU0hJRlQsCiAJLnZwY29uZmlnX2Vycm9yZ2Fpbl9tYXNrID0gT01BUDQ0MzBfRVJST1JH
QUlOX01BU0ssCiAJLnZwY29uZmlnX2Vycm9yZ2Fpbl9zaGlmdCA9IE9NQVA0NDMwX0VSUk9SR0FJ
Tl9TSElGVCwKQEAgLTU2LDYgKzU2LDcgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBvbWFwX3ZwX3By
bV9pcnFzdF9kYXRhIG9tYXA0X3ZwX21wdV9wcm1faXJxc3RfZGF0YSA9IHsKIH07CiAKIHN0cnVj
dCBvbWFwX3ZwX2luc3RhbmNlX2RhdGEgb21hcDRfdnBfbXB1X2RhdGEgPSB7CisJLnZwX2NvbW1v
biA9ICZvbWFwNF92cF9jb21tb24sCiAJLnZwY29uZmlnID0gT01BUDRfUFJNX1ZQX01QVV9DT05G
SUdfT0ZGU0VULAogCS52c3RlcG1pbiA9IE9NQVA0X1BSTV9WUF9NUFVfVlNURVBNSU5fT0ZGU0VU
LAogCS52c3RlcG1heCA9IE9NQVA0X1BSTV9WUF9NUFVfVlNURVBNQVhfT0ZGU0VULApAQCAtNzEs
NiArNzIsNyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IG9tYXBfdnBfcHJtX2lycXN0X2RhdGEgb21h
cDRfdnBfaXZhX3BybV9pcnFzdF9kYXRhID0gewogfTsKIAogc3RydWN0IG9tYXBfdnBfaW5zdGFu
Y2VfZGF0YSBvbWFwNF92cF9pdmFfZGF0YSA9IHsKKwkudnBfY29tbW9uID0gJm9tYXA0X3ZwX2Nv
bW1vbiwKIAkudnBjb25maWcgPSBPTUFQNF9QUk1fVlBfSVZBX0NPTkZJR19PRkZTRVQsCiAJLnZz
dGVwbWluID0gT01BUDRfUFJNX1ZQX0lWQV9WU1RFUE1JTl9PRkZTRVQsCiAJLnZzdGVwbWF4ID0g
T01BUDRfUFJNX1ZQX0lWQV9WU1RFUE1BWF9PRkZTRVQsCkBAIC04Niw2ICs4OCw3IEBAIHN0YXRp
YyBjb25zdCBzdHJ1Y3Qgb21hcF92cF9wcm1faXJxc3RfZGF0YSBvbWFwNF92cF9jb3JlX3BybV9p
cnFzdF9kYXRhID0gewogfTsKIAogc3RydWN0IG9tYXBfdnBfaW5zdGFuY2VfZGF0YSBvbWFwNF92
cF9jb3JlX2RhdGEgPSB7CisJLnZwX2NvbW1vbiA9ICZvbWFwNF92cF9jb21tb24sCiAJLnZwY29u
ZmlnID0gT01BUDRfUFJNX1ZQX0NPUkVfQ09ORklHX09GRlNFVCwKIAkudnN0ZXBtaW4gPSBPTUFQ
NF9QUk1fVlBfQ09SRV9WU1RFUE1JTl9PRkZTRVQsCiAJLnZzdGVwbWF4ID0gT01BUDRfUFJNX1ZQ
X0NPUkVfVlNURVBNQVhfT0ZGU0VULAotLSAKMS43LjAuNAoK
--20cf30433eeccc95c2049d05ecaa--

^ permalink raw reply related

* [PATCH v2] ARM: Thumb-2: Reflect ARM/Thumb-2 configuration in module vermagic
From: Dave Martin @ 2011-02-24 11:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D657B12.8070702@ru.mvista.com>

On Wed, Feb 23, 2011 at 9:24 PM, Sergei Shtylyov <sshtylyov@mvista.com> wrote:
> Hello.
>
> On 23-02-2011 14:53, Dave Martin wrote:
>
>> Loading Thumb-2 modules into an ARM kernel or vice-versa isn't
>> guaranteed to work safely, since the kernel is not interworking-
>> aware everywhere.
>
>> This patch adds "thumb2" to the module vermagic when
>> CONFIG_THUMB2_KERNEL is enabled, to help avoid accidental loading
>> of modules into the wrong kernel.
>
>> v2: modified to apply consistently on top of rmk's p2v branch.
>
> ? Patch changelog should follow the -- tearline.
>
>> Signed-off-by: Dave Martin<dave.martin@linaro.org>
>> Acked-by: Nicolas Pitre<nicolas.pitre@linaro.org>
>
> WBR, Sergei
>

Opinions seem to differ... I have no strong opinion on this myself.

Cheers
---Dave

^ permalink raw reply

* [PATCH 3/3] ASoC: correct pxa AC97 DAI names
From: Mark Brown @ 2011-02-24 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298417351-24727-3-git-send-email-dbaryshkov@gmail.com>

On Wed, Feb 23, 2011 at 02:29:11AM +0300, Dmitry Eremin-Solenikov wrote:
> Correct names for pxa AC97 DAI are pxa2xx-ac97 and pxa2xx-ac97-aux. Fix
> that for all PXA platforms.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Applied, thanks.  Others

Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

^ permalink raw reply

* [PATCH v2 13/13] tty: pruss SUART driver
From: Subhasish Ghosh @ 2011-02-24 10:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201102221734.15582.arnd@arndb.de>

Hello,

Ok, have implemented the test_and_clear_bit.


> On Tuesday 22 February 2011, Subhasish Ghosh wrote:
>
>> @@ -122,13 +122,10 @@ static void omapl_pru_tx_chars(struct 
>> omapl_pru_suart
>> *soft_uart, u32 uart_no)
>>         if (!(suart_get_duplex(soft_uart, uart_no) & ePRU_SUART_HALF_TX))
>>                 return;
>>
>> -       if (down_trylock(&soft_uart->port_sem[uart_no]))
>> -               return;
>> -
>>         if (uart_circ_empty(xmit) ||
>>                         uart_tx_stopped(&soft_uart->port[uart_no])) {
>>                 pruss_suart_stop_tx(&soft_uart->port[uart_no]);
>> -               up(&soft_uart->port_sem[uart_no]);
>> +               soft_uart->tx_empty[uart_no] = true;
>>                 return;
>>         }
>>
>> @@ -259,7 +256,6 @@ static irqreturn_t pruss_suart_interrupt(s32 irq, 
>> void
>> *dev_id)
>>                         pru_intr_clr_isrstatus(dev, uart_num, 
>> PRU_TX_INTR);
>>                         pru_softuart_clr_tx_status(dev, 
>> &soft_uart->suart_hdl
>>                                                  [port->line]);
>> -                       up(&soft_uart->port_sem[port->line]);
>>                         omapl_pru_tx_chars(soft_uart, port->line);
>>                 }
>>         } while (txrx_flag & (PRU_RX_INTR | PRU_TX_INTR));
>> @@ -294,7 +290,10 @@ static void pruss_suart_start_tx(struct uart_port
>> *port)
>>
>>         suart_intr_setmask(dev, 
>> soft_uart->suart_hdl[port->line].uart_num,
>>                            PRU_TX_INTR, CHN_TXRX_IE_MASK_CMPLT);
>> -       omapl_pru_tx_chars(soft_uart, port->line);
>> +       if (soft_uart->tx_empty[port->line] == true) {
>> +               soft_uart->tx_empty[port->line] = false;
>> +               omapl_pru_tx_chars(soft_uart, port->line);
>> +       }
>>  }
>
> This looks racy, and I think you at least need to take the spinlock in
> pruss_suart_start_tx(), but I don't fully understand the intention of the
> code.
>
> I guess you could also use a bitmask for tx_empty and use 
> test_and_clear_bit()
> on that to guarantee atomicity.
>
> Arnd 

^ permalink raw reply

* [PATCH 1/1] da830: macro rename DA8XX_LPSC0_DMAX to DA8XX_LPSC0_PRUSS.
From: Subhasish Ghosh @ 2011-02-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB593024BE4916D@dbde02.ent.ti.com>

> Hi Subhasish,
>
> Please add a "davinci: " prefix to the subject line of
> mach-davinci patches. The patch is not really specific
> to DA830.

SG -- OK, Will do

>
> On Fri, Feb 11, 2011 at 19:48:25, Subhasish Ghosh wrote:
>> The PRUSS was named as DMAX on da830 platform.
>> This patch resolves the naming conflict by replacing the macro
>> DA8XX_LPSC0_DMAX with DA8XX_LPSC0_PRUSS.
>
> This description is inaccurate. Firstly, there is no naming
> conflict. DMAX is an internal name for the module which is
> known as PRUSS in TI public documentation. This patch just
> gets the code in sync with TI documentation.
>
> Can you please update the subject and re-spin this patch?

SG - OK, Will do.


>
> Thanks,
> Sekhar
>
>>
>> Signed-off-by: Subhasish Ghosh <subhasish@mistralsolutions.com>
>> ---
>>  arch/arm/mach-davinci/da830.c            |    2 +-
>>  arch/arm/mach-davinci/include/mach/psc.h |    2 +-
>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-davinci/da830.c 
>> b/arch/arm/mach-davinci/da830.c
>> index ec23ab4..0577a5d 100644
>> --- a/arch/arm/mach-davinci/da830.c
>> +++ b/arch/arm/mach-davinci/da830.c
>> @@ -148,7 +148,7 @@ static struct clk scr2_ss_clk = {
>>  static struct clk dmax_clk = {
>>  .name = "dmax",
>>  .parent = &pll0_sysclk2,
>> - .lpsc = DA8XX_LPSC0_DMAX,
>> + .lpsc = DA8XX_LPSC0_PRUSS,
>>  .flags = ALWAYS_ENABLED,
>>  };
>>
>> diff --git a/arch/arm/mach-davinci/include/mach/psc.h 
>> b/arch/arm/mach-davinci/include/mach/psc.h
>> index 62b0858..a47e6f2 100644
>> --- a/arch/arm/mach-davinci/include/mach/psc.h
>> +++ b/arch/arm/mach-davinci/include/mach/psc.h
>> @@ -150,7 +150,7 @@
>>  #define DA8XX_LPSC0_SCR0_SS 10
>>  #define DA8XX_LPSC0_SCR1_SS 11
>>  #define DA8XX_LPSC0_SCR2_SS 12
>> -#define DA8XX_LPSC0_DMAX 13
>> +#define DA8XX_LPSC0_PRUSS 13
>>  #define DA8XX_LPSC0_ARM 14
>>  #define DA8XX_LPSC0_GEM 15
>>
>> -- 
>> 1.7.2.3
>>
>>
> 

^ permalink raw reply

* [PATCH 1/1] davinci: changed SRAM allocator to shared ram.
From: Subhasish Ghosh @ 2011-02-24 10:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB593024BE49175@dbde02.ent.ti.com>

--------------------------------------------------
From: "Nori, Sekhar" <nsekhar@ti.com>
Sent: Wednesday, February 23, 2011 9:00 PM
To: "Subhasish Ghosh" <subhasish@mistralsolutions.com>; 
<davinci-linux-open-source@linux.davincidsp.com>
Cc: <linux-arm-kernel@lists.infradead.org>; "Watkins, Melissa" 
<m-watkins@ti.com>; <sachi@mistralsolutions.com>; "Kevin Hilman" 
<khilman@deeprootsystems.com>; "Russell King" <linux@arm.linux.org.uk>; 
"Michael Williamson" <michael.williamson@criticallink.com>; "Chemparathy, 
Cyril" <cyril@ti.com>; "Sergei Shtylyov" <sshtylyov@ru.mvista.com>; "open 
list" <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH 1/1] davinci: changed SRAM allocator to shared ram.

> Hi Subhasish,
>
> On Fri, Feb 11, 2011 at 19:51:28, Subhasish Ghosh wrote:
>> This patch modifies the sram allocator to allocate memory
>> from the DA8XX shared RAM.
>
> It will be nice to know if you tried suspend-to-RAM
> after this change and found it to be working.
>

SG -- My file system is currently mounted from MMC.
          Suspend to RAM seems to have bug with MMC.
           (http://processors.wiki.ti.com/index.php/OMAP-L1_Linux_Drivers_Usage#Suspend-to-RAM)
          I had tried NFS earlier, but I think there is some problem with 
NFS boot and udev with this kernel.
           So, currently I will not be able to do it, but will try if I get 
a chance.

> Thanks,
> Sekhar
>
>>
>> Signed-off-by: Subhasish Ghosh <subhasish@mistralsolutions.com>
>> ---
>>  arch/arm/mach-davinci/da850.c              |    6 +++---
>>  arch/arm/mach-davinci/include/mach/da8xx.h |    1 +
>>  2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/mach-davinci/da850.c 
>> b/arch/arm/mach-davinci/da850.c
>> index 3443d97..8a4de97 100644
>> --- a/arch/arm/mach-davinci/da850.c
>> +++ b/arch/arm/mach-davinci/da850.c
>> @@ -711,7 +711,7 @@ static struct map_desc da850_io_desc[] = {
>>  },
>>  {
>>  .virtual = SRAM_VIRT,
>> - .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
>> + .pfn = __phys_to_pfn(DA8XX_SHARED_RAM_BASE),
>>  .length = SZ_8K,
>>  .type = MT_DEVICE
>>  },
>> @@ -1083,8 +1083,8 @@ static struct davinci_soc_info 
>> davinci_soc_info_da850 = {
>>  .gpio_irq = IRQ_DA8XX_GPIO0,
>>  .serial_dev = &da8xx_serial_device,
>>  .emac_pdata = &da8xx_emac_pdata,
>> - .sram_dma = DA8XX_ARM_RAM_BASE,
>> - .sram_len = SZ_8K,
>> + .sram_dma = DA8XX_SHARED_RAM_BASE,
>> + .sram_len = SZ_128K,
>>  .reset_device = &da8xx_wdt_device,
>>  };
>>
>> diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h 
>> b/arch/arm/mach-davinci/include/mach/da8xx.h
>> index cfcb223..c3c3339 100644
>> --- a/arch/arm/mach-davinci/include/mach/da8xx.h
>> +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
>> @@ -70,6 +70,7 @@ extern unsigned int da850_max_speed;
>>  #define DA8XX_AEMIF_CTL_BASE 0x68000000
>>  #define DA8XX_DDR2_CTL_BASE 0xb0000000
>>  #define DA8XX_ARM_RAM_BASE 0xffff0000
>> +#define DA8XX_SHARED_RAM_BASE 0x80000000
>>
>>  void __init da830_init(void);
>>  void __init da850_init(void);
>> -- 
>> 1.7.2.3
>>
>>
> 

^ permalink raw reply

* [PATCH 3/3] OMAP: PM: DMA: Enable runtime pm
From: G, Manjunath Kondaiah @ 2011-02-24 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298542475-1460-1-git-send-email-manjugk@ti.com>

From: Manjunath G Kondaiah <manjugk@ti.com>

Enable runtime pm and use pm_runtime_get_sync and pm_runtime_put_autosuspend
for OMAP DMA driver.

The DMA driver uses auto suspend feature of runtime pm framework through
which the clock gets disabled automatically if there is no activity for
more than one second.

Testing:
Compile: omap1_defconfig and omap2plus_defconfig
Boot: OMAP1710(H3), OMAP2420(H4), OMAP3430LDP(Zoom2), OMAP3630(Zoom3), OMAP4(Blaze)

The DMA tests(including chaining) are executed and tested for suspend state
after each test cases.

On zoom2 core retention is tested with following steps:
echo 1 > /debug/pm_debug/sleep_while_idle
echo 1 > /debug/pm_debug/enable_off_mode
echo 5 > /sys/devices/platform/omap/omap_uart.0/sleep_timeout
echo 5 > /sys/devices/platform/omap/omap_uart.1/sleep_timeout
echo 5 > /sys/devices/platform/omap/omap_uart.2/sleep_timeout
echo 5 > /sys/devices/platform/omap/omap_uart.3/sleep_timeout

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
---
 arch/arm/plat-omap/dma.c |  150 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 141 insertions(+), 9 deletions(-)

diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 84879eb..92e18e3 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -35,6 +35,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
@@ -60,6 +61,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 
 static struct omap_system_dma_plat_info *p;
 static struct omap_dma_dev_attr *d;
+static struct device *dev;
 
 static int enable_1510_mode;
 static u32 errata;
@@ -172,6 +174,7 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
 	unsigned long reg;
 	u32 l;
 
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap1()) {
 		switch (dst_port) {
 		case OMAP_DMA_PORT_OCP_T1:	/* FFFECC00 */
@@ -188,6 +191,7 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
 			break;
 		default:
 			BUG();
+			pm_runtime_put_autosuspend(dev);
 			return;
 		}
 		l = omap_readl(reg);
@@ -206,6 +210,7 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
 			ccr &= ~(1 << 6);
 		p->dma_write(ccr, CCR, lch);
 	}
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_priority);
 
@@ -215,6 +220,8 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
+
 	l = p->dma_read(CSDP, lch);
 	l &= ~0x03;
 	l |= data_type;
@@ -269,6 +276,7 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 
 	p->dma_write(elem_count, CEN, lch);
 	p->dma_write(frame_count, CFN, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
 
@@ -276,6 +284,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 {
 	BUG_ON(omap_dma_in_1510_mode());
 
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
@@ -329,11 +338,13 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 		color &= 0xffffff;
 		p->dma_write(color, COLOR, lch);
 	}
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_color_mode);
 
 void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
 {
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap2()) {
 		u32 csdp;
 
@@ -342,11 +353,13 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
 		csdp |= (mode << 16);
 		p->dma_write(csdp, CSDP, lch);
 	}
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_write_mode);
 
 void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
 {
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
 		u32 l;
 
@@ -355,6 +368,7 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
 		l |= mode;
 		p->dma_write(l, LCH_CTRL, lch);
 	}
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_channel_mode);
 
@@ -365,6 +379,8 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
+
 	if (cpu_class_is_omap1()) {
 		u16 w;
 
@@ -383,11 +399,13 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 
 	p->dma_write(src_ei, CSEI, lch);
 	p->dma_write(src_fi, CSFI, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_src_params);
 
 void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
 {
+	pm_runtime_get_sync(dev);
 	omap_set_dma_transfer_params(lch, params->data_type,
 				     params->elem_count, params->frame_count,
 				     params->sync_mode, params->trigger,
@@ -402,6 +420,7 @@ void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
 	if (params->read_prio || params->write_prio)
 		omap_dma_set_prio_lch(lch, params->read_prio,
 				      params->write_prio);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_params);
 
@@ -410,8 +429,10 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
 	if (cpu_class_is_omap2())
 		return;
 
+	pm_runtime_get_sync(dev);
 	p->dma_write(eidx, CSEI, lch);
 	p->dma_write(fidx, CSFI, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_src_index);
 
@@ -419,11 +440,13 @@ void omap_set_dma_src_data_pack(int lch, int enable)
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
 	l = p->dma_read(CSDP, lch);
 	l &= ~(1 << 6);
 	if (enable)
 		l |= (1 << 6);
 	p->dma_write(l, CSDP, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_src_data_pack);
 
@@ -432,6 +455,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	unsigned int burst = 0;
 	u32 l;
 
+	pm_runtime_get_sync(dev);
 	l = p->dma_read(CSDP, lch);
 	l &= ~(0x03 << 7);
 
@@ -469,6 +493,7 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 
 	l |= (burst << 7);
 	p->dma_write(l, CSDP, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
 
@@ -478,6 +503,7 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 			      int dst_ei, int dst_fi)
 {
 	u32 l;
+	pm_runtime_get_sync(dev);
 
 	if (cpu_class_is_omap1()) {
 		l = p->dma_read(CSDP, lch);
@@ -495,6 +521,7 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 
 	p->dma_write(dst_ei, CDEI, lch);
 	p->dma_write(dst_fi, CDFI, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_params);
 
@@ -502,21 +529,25 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
 {
 	if (cpu_class_is_omap2())
 		return;
+	pm_runtime_get_sync(dev);
 
 	p->dma_write(eidx, CDEI, lch);
 	p->dma_write(fidx, CDFI, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_index);
 
 void omap_set_dma_dest_data_pack(int lch, int enable)
 {
 	u32 l;
+	pm_runtime_get_sync(dev);
 
 	l = p->dma_read(CSDP, lch);
 	l &= ~(1 << 13);
 	if (enable)
 		l |= 1 << 13;
 	p->dma_write(l, CSDP, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
 
@@ -524,6 +555,7 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 {
 	unsigned int burst = 0;
 	u32 l;
+	pm_runtime_get_sync(dev);
 
 	l = p->dma_read(CSDP, lch);
 	l &= ~(0x03 << 14);
@@ -555,10 +587,12 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 	default:
 		printk(KERN_ERR "Invalid DMA burst mode\n");
 		BUG();
+		pm_runtime_put_autosuspend(dev);
 		return;
 	}
 	l |= (burst << 14);
 	p->dma_write(l, CSDP, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
 
@@ -566,6 +600,7 @@ static inline void omap_enable_channel_irq(int lch)
 {
 	u32 status;
 
+	pm_runtime_get_sync(dev);
 	/* Clear CSR */
 	if (cpu_class_is_omap1())
 		status = p->dma_read(CSR, lch);
@@ -574,12 +609,15 @@ static inline void omap_enable_channel_irq(int lch)
 
 	/* Enable some nice interrupts. */
 	p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 
 static void omap_disable_channel_irq(int lch)
 {
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap2())
 		p->dma_write(0, CICR, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 
 void omap_enable_dma_irq(int lch, u16 bits)
@@ -597,6 +635,7 @@ EXPORT_SYMBOL(omap_disable_dma_irq);
 static inline void enable_lnk(int lch)
 {
 	u32 l;
+	pm_runtime_get_sync(dev);
 
 	l = p->dma_read(CLNK_CTRL, lch);
 
@@ -614,12 +653,14 @@ static inline void enable_lnk(int lch)
 #endif
 
 	p->dma_write(l, CLNK_CTRL, lch);
+	pm_runtime_put_autosuspend(dev);
 }
 
 static inline void disable_lnk(int lch)
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
 	l = p->dma_read(CLNK_CTRL, lch);
 
 	/* Disable interrupts */
@@ -637,6 +678,7 @@ static inline void disable_lnk(int lch)
 
 	p->dma_write(l, CLNK_CTRL, lch);
 	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+	pm_runtime_put_autosuspend(dev);
 }
 
 static inline void omap2_enable_irq_lch(int lch)
@@ -647,11 +689,13 @@ static inline void omap2_enable_irq_lch(int lch)
 	if (!cpu_class_is_omap2())
 		return;
 
+	pm_runtime_get_sync(dev);
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	val = p->dma_read(IRQENABLE_L0, lch);
 	val |= 1 << lch;
 	p->dma_write(val, IRQENABLE_L0, lch);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
+	pm_runtime_put_autosuspend(dev);
 }
 
 static inline void omap2_disable_irq_lch(int lch)
@@ -662,11 +706,13 @@ static inline void omap2_disable_irq_lch(int lch)
 	if (!cpu_class_is_omap2())
 		return;
 
+	pm_runtime_get_sync(dev);
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	val = p->dma_read(IRQENABLE_L0, lch);
 	val &= ~(1 << lch);
 	p->dma_write(val, IRQENABLE_L0, lch);
 	spin_unlock_irqrestore(&dma_chan_lock, flags);
+	pm_runtime_put_autosuspend(dev);
 }
 
 int omap_request_dma(int dev_id, const char *dev_name,
@@ -677,6 +723,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
 	unsigned long flags;
 	struct omap_dma_lch *chan;
 
+	pm_runtime_get_sync(dev);
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	for (ch = 0; ch < dma_chan_count; ch++) {
 		if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
@@ -687,6 +734,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
 	}
 	if (free_ch == -1) {
 		spin_unlock_irqrestore(&dma_chan_lock, flags);
+		pm_runtime_put_autosuspend(dev);
 		return -EBUSY;
 	}
 	chan = dma_chan + free_ch;
@@ -744,6 +792,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
 	}
 
 	*dma_ch_out = free_ch;
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
@@ -758,7 +807,7 @@ void omap_free_dma(int lch)
 		       lch);
 		return;
 	}
-
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap1()) {
 		/* Disable all DMA interrupts for the channel. */
 		p->dma_write(0, CICR, lch);
@@ -780,7 +829,7 @@ void omap_free_dma(int lch)
 		p->dma_write(0, CCR, lch);
 		omap_clear_dma(lch);
 	}
-
+	pm_runtime_put_autosuspend(dev);
 	spin_lock_irqsave(&dma_chan_lock, flags);
 	dma_chan[lch].dev_id = -1;
 	dma_chan[lch].next_lch = -1;
@@ -818,7 +867,9 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
 	reg |= (0x3 & tparams) << 12;
 	reg |= (arb_rate & 0xff) << 16;
 
+	pm_runtime_get_sync(dev);
 	p->dma_write(reg, GCR, 0);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_dma_set_global_params);
 
@@ -841,6 +892,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
 		printk(KERN_ERR "Invalid channel id\n");
 		return -EINVAL;
 	}
+	pm_runtime_get_sync(dev);
 	l = p->dma_read(CCR, lch);
 	l &= ~((1 << 6) | (1 << 26));
 	if (cpu_is_omap2430() || cpu_is_omap34xx() ||  cpu_is_omap44xx())
@@ -849,6 +901,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
 		l |= ((read_prio & 0x1) << 6);
 
 	p->dma_write(l, CCR, lch);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
@@ -862,9 +915,11 @@ void omap_clear_dma(int lch)
 {
 	unsigned long flags;
 
+	pm_runtime_get_sync(dev);
 	local_irq_save(flags);
 	p->clear_dma(lch);
 	local_irq_restore(flags);
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_clear_dma);
 
@@ -872,6 +927,8 @@ void omap_start_dma(int lch)
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
+
 	/*
 	 * The CPC/CDAC register needs to be initialized to zero
 	 * before starting dma transfer.
@@ -927,6 +984,7 @@ void omap_stop_dma(int lch)
 	u32 l;
 	unsigned long flags;
 
+	pm_runtime_get_sync(dev);
 	/* Disable all interrupts on the channel */
 	if (cpu_class_is_omap1())
 		p->dma_write(0, CICR, lch);
@@ -989,6 +1047,7 @@ void omap_stop_dma(int lch)
 	}
 
 	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_stop_dma);
 
@@ -1031,6 +1090,7 @@ dma_addr_t omap_get_dma_src_pos(int lch)
 {
 	dma_addr_t offset = 0;
 
+	pm_runtime_get_sync(dev);
 	if (cpu_is_omap15xx())
 		offset = p->dma_read(CPC, lch);
 	else
@@ -1042,6 +1102,7 @@ dma_addr_t omap_get_dma_src_pos(int lch)
 	if (cpu_class_is_omap1())
 		offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
 
+	pm_runtime_put_autosuspend(dev);
 	return offset;
 }
 EXPORT_SYMBOL(omap_get_dma_src_pos);
@@ -1058,6 +1119,7 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
 {
 	dma_addr_t offset = 0;
 
+	pm_runtime_get_sync(dev);
 	if (cpu_is_omap15xx())
 		offset = p->dma_read(CPC, lch);
 	else
@@ -1073,13 +1135,20 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
 	if (cpu_class_is_omap1())
 		offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
 
+	pm_runtime_put_autosuspend(dev);
 	return offset;
 }
 EXPORT_SYMBOL(omap_get_dma_dst_pos);
 
 int omap_get_dma_active_status(int lch)
 {
-	return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
+	u32 reg_data;
+
+	pm_runtime_get_sync(dev);
+	reg_data = p->dma_read(CCR, lch);
+	pm_runtime_put_autosuspend(dev);
+	reg_data &= reg_data & OMAP_DMA_CCR_EN;
+	return ((reg_data != 0) ? 1 : 0);
 }
 EXPORT_SYMBOL(omap_get_dma_active_status);
 
@@ -1087,14 +1156,20 @@ int omap_dma_running(void)
 {
 	int lch;
 
+	pm_runtime_get_sync(dev);
 	if (cpu_class_is_omap1())
-		if (omap_lcd_dma_running())
+		if (omap_lcd_dma_running()) {
+			pm_runtime_put_autosuspend(dev);
 			return 1;
+		}
 
 	for (lch = 0; lch < dma_chan_count; lch++)
-		if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
+		if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) {
+			pm_runtime_put_autosuspend(dev);
 			return 1;
+		}
 
+	pm_runtime_put_autosuspend(dev);
 	return 0;
 }
 
@@ -1105,12 +1180,15 @@ int omap_dma_running(void)
  */
 void omap_dma_link_lch(int lch_head, int lch_queue)
 {
+	pm_runtime_get_sync(dev);
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
 			p->dma_write(p->dma_read(CCR, lch_head) | (3 << 8),
 								CCR, lch_head);
+			pm_runtime_put_autosuspend(dev);
 			return;
 		}
+		pm_runtime_put_autosuspend(dev);
 		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
 		BUG();
 		return;
@@ -1124,6 +1202,7 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
 	}
 
 	dma_chan[lch_head].next_lch = lch_queue;
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_dma_link_lch);
 
@@ -1132,12 +1211,15 @@ EXPORT_SYMBOL(omap_dma_link_lch);
  */
 void omap_dma_unlink_lch(int lch_head, int lch_queue)
 {
+	pm_runtime_get_sync(dev);
 	if (omap_dma_in_1510_mode()) {
 		if (lch_head == lch_queue) {
 			p->dma_write(p->dma_read(CCR, lch_head) & ~(3 << 8),
 								CCR, lch_head);
+			pm_runtime_put_autosuspend(dev);
 			return;
 		}
+		pm_runtime_put_autosuspend(dev);
 		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
 		BUG();
 		return;
@@ -1158,6 +1240,7 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
 	}
 
 	dma_chan[lch_head].next_lch = -1;
+	pm_runtime_put_autosuspend(dev);
 }
 EXPORT_SYMBOL(omap_dma_unlink_lch);
 
@@ -1167,6 +1250,7 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
 {
 	u32 l;
 
+	pm_runtime_get_sync(dev);
 	/* Check if this is the first link in chain */
 	if (dma_chan[lch_head].next_linked_ch == -1) {
 		dma_chan[lch_head].next_linked_ch = lch_queue;
@@ -1194,6 +1278,7 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
 	l &= ~(0x1f);
 	l |= (dma_chan[lch_queue].next_linked_ch);
 	p->dma_write(l, CLNK_CTRL, lch_queue);
+	pm_runtime_put_autosuspend(dev);
 }
 
 /**
@@ -1467,6 +1552,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 	/* Increment the q_tail */
 	OMAP_DMA_CHAIN_INCQTAIL(chain_id);
 
+	pm_runtime_get_sync(dev);
 	/* Set the params to the free channel */
 	if (src_start != 0)
 		p->dma_write(src_start, CSSA, lch);
@@ -1546,6 +1632,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
 			dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 		}
 	}
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
@@ -1586,6 +1673,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 		omap_enable_channel_irq(channels[0]);
 	}
 
+	pm_runtime_get_sync(dev);
 	l = p->dma_read(CCR, channels[0]);
 	l |= (1 << 7);
 	dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
@@ -1599,6 +1687,7 @@ int omap_start_dma_chain_transfers(int chain_id)
 
 	dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
 
+	pm_runtime_put_autosuspend(dev);
 	return 0;
 }
 EXPORT_SYMBOL(omap_start_dma_chain_transfers);
@@ -1630,6 +1719,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	}
 	channels = dma_linked_lch[chain_id].linked_dmach_q;
 
+	pm_runtime_get_sync(dev);
 	if (IS_DMA_ERRATA(DMA_ERRATA_i88) && p->midlemode) {
 		spin_lock_irqsave(&dma_chan_lock, flags);
 		p->midlemode(true);
@@ -1658,6 +1748,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 		p->midlemode(false);
 		spin_unlock_irqrestore(&dma_chan_lock, flags);
 	}
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
@@ -1691,16 +1782,19 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
 		printk(KERN_ERR "Chain doesn't exists\n");
 		return -EINVAL;
 	}
-	if ((!ei) || (!fi))
+	if ((!ei) || (!fi)) {
 		return -EINVAL;
+	}
 
 	channels = dma_linked_lch[chain_id].linked_dmach_q;
 
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
+	pm_runtime_get_sync(dev);
 	*ei = p->dma_read(CCEN, lch);
 	*fi = p->dma_read(CCFN, lch);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
@@ -1719,6 +1813,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
 {
 	int lch;
 	int *channels;
+	int reg_data;
 
 	/* Check for input params */
 	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1737,7 +1832,10 @@ int omap_get_dma_chain_dst_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return p->dma_read(CDAC, lch);
+	pm_runtime_get_sync(dev);
+	reg_data = p->dma_read(CDAC, lch);
+	pm_runtime_put_autosuspend(dev);
+	return reg_data;
 }
 EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
 
@@ -1753,6 +1851,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
 {
 	int lch;
 	int *channels;
+	int reg_data;
 
 	/* Check for input params */
 	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1771,7 +1870,10 @@ int omap_get_dma_chain_src_pos(int chain_id)
 	/* Get the current channel */
 	lch = channels[dma_linked_lch[chain_id].q_head];
 
-	return p->dma_read(CSAC, lch);
+	pm_runtime_get_sync(dev);
+	reg_data = p->dma_read(CSAC, lch);
+	pm_runtime_put_autosuspend(dev);
+	return reg_data;
 }
 EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
 #endif	/* ifndef CONFIG_ARCH_OMAP1 */
@@ -1811,6 +1913,8 @@ static int omap1_dma_handle_ch(int ch)
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
 
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 	return 1;
 }
 
@@ -1895,8 +1999,11 @@ static int omap2_dma_handle_ch(int ch)
 						OMAP_DMA_DYNAMIC_CHAIN)
 			disable_lnk(ch);
 
-		if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
+		if (!OMAP_DMA_CHAIN_QEMPTY(chain_id)) {
 			OMAP_DMA_CHAIN_INCQHEAD(chain_id);
+			pm_runtime_get_sync(dev);
+		}
+
 
 		status = p->dma_read(CSR, ch);
 		p->dma_write(status, CSR, ch);
@@ -1905,6 +2012,8 @@ static int omap2_dma_handle_ch(int ch)
 	if (likely(dma_chan[ch].callback != NULL))
 		dma_chan[ch].callback(ch, status, dma_chan[ch].data);
 
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 	return 0;
 }
 
@@ -1945,17 +2054,20 @@ static struct irqaction omap24xx_dma_irq;
 
 void omap_dma_global_context_save(void)
 {
+	pm_runtime_get_sync(dev);
 	omap_dma_global_context.dma_irqenable_l0 =
 		p->dma_read(IRQENABLE_L0, 0);
 	omap_dma_global_context.dma_ocp_sysconfig =
 		p->dma_read(OCP_SYSCONFIG, 0);
 	omap_dma_global_context.dma_gcr = p->dma_read(GCR, 0);
+	pm_runtime_put_autosuspend(dev);
 }
 
 void omap_dma_global_context_restore(void)
 {
 	int ch;
 
+	pm_runtime_get_sync(dev);
 	p->dma_write(omap_dma_global_context.dma_gcr, GCR, 0);
 	p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
 		OCP_SYSCONFIG, 0);
@@ -1968,6 +2080,7 @@ void omap_dma_global_context_restore(void)
 	for (ch = 0; ch < dma_chan_count; ch++)
 		if (dma_chan[ch].dev_id != -1)
 			omap_clear_dma(ch);
+	pm_runtime_put_autosuspend(dev);
 }
 
 static int __devinit omap_system_dma_probe(struct platform_device *pdev)
@@ -1984,6 +2097,7 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	dev			= &pdev->dev;
 	d			= p->dma_attr;
 	errata			= p->errata;
 
@@ -2005,6 +2119,11 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 		}
 	}
 
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_autosuspend_delay(dev, 1000);
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
 	spin_lock_init(&dma_chan_lock);
 	for (ch = 0; ch < dma_chan_count; ch++) {
 		omap_clear_dma(ch);
@@ -2070,6 +2189,16 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
 		dma_chan[1].dev_id = 1;
 	}
 	p->show_dma_caps();
+
+	/*
+	 * Note: If dma channels are reserved through boot paramters,
+	 * then dma device is always enabled.
+	 */
+	if (omap_dma_reserve_channels)
+		pm_runtime_get(dev);
+
+	pm_runtime_put_autosuspend(dev);
+
 	return 0;
 
 exit_dma_irq_fail:
@@ -2091,6 +2220,9 @@ static int __devexit omap_system_dma_remove(struct platform_device *pdev)
 {
 	int dma_irq;
 
+	if (omap_dma_reserve_channels)
+		pm_runtime_put_autosuspend(dev);
+
 	if (cpu_class_is_omap2()) {
 		char irq_name[4];
 		strcpy(irq_name, "0");
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/3] OMAP2+: DMA: prevent races while setting M idle mode to nostandby
From: G, Manjunath Kondaiah @ 2011-02-24 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298542475-1460-1-git-send-email-manjugk@ti.com>

If two DMA users tries to set no mstandby mode at the same time, a race
condition would arise. Prevent that by using a spin lock and counting
up/down the number of times nostandby is set/reset.

Initial patch is created by Adrian Hunter <adrian.hunter@nokia.com>
https://patchwork.kernel.org/patch/366831/

Patch reworked to use API implemented at hwmod layer.

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
---
 arch/arm/mach-omap1/dma.c             |    1 +
 arch/arm/mach-omap2/dma.c             |   16 +++++++++++++
 arch/arm/plat-omap/dma.c              |   40 +++++++++++++++++++--------------
 arch/arm/plat-omap/include/plat/dma.h |    1 +
 4 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index d855934..fa2d1b0 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -351,6 +351,7 @@ static int __init omap1_system_dma_init(void)
 	p->dma_write		= dma_write;
 	p->dma_read		= dma_read;
 	p->disable_irq_lch	= NULL;
+	p->midlemode		= NULL;
 
 	p->errata = configure_dma_errata();
 
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 34922b2..6e12e71 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -36,7 +36,9 @@
 
 static u32 errata;
 static u8 dma_stride;
+static u32 midlemode_save_cnt;
 
+static struct platform_device *pdev;
 static struct omap_dma_dev_attr *d;
 
 static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
@@ -117,6 +119,18 @@ static inline u32 dma_read(int reg, int lch)
 	return val;
 }
 
+static void midlemode_nostandby(bool nostandby)
+{
+	/* TODO: midlemode_save_cnt can be moved to hwmod layer? */
+	if (nostandby) {
+		omap_device_require_no_mstandby(pdev);
+		midlemode_save_cnt += 1;
+	} else {
+		omap_device_release_no_mstandby(pdev);
+		midlemode_save_cnt -= 1;
+	}
+}
+
 static inline void omap2_disable_irq_lch(int lch)
 {
 	u32 val;
@@ -253,6 +267,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 	p->clear_dma		= omap2_clear_dma;
 	p->dma_write		= dma_write;
 	p->dma_read		= dma_read;
+	p->midlemode		= midlemode_nostandby;
 
 	p->clear_lch_regs	= NULL;
 
@@ -286,6 +301,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 		dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
 		return -ENOMEM;
 	}
+	pdev = &od->pdev;
 	return 0;
 }
 
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 8536308..84879eb 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -38,8 +38,9 @@
 
 #include <asm/system.h>
 #include <mach/hardware.h>
-#include <plat/dma.h>
 
+#include <plat/dma.h>
+#include <plat/omap_device.h>
 #include <plat/tc.h>
 
 #undef DEBUG
@@ -924,6 +925,7 @@ EXPORT_SYMBOL(omap_start_dma);
 void omap_stop_dma(int lch)
 {
 	u32 l;
+	unsigned long flags;
 
 	/* Disable all interrupts on the channel */
 	if (cpu_class_is_omap1())
@@ -933,14 +935,13 @@ void omap_stop_dma(int lch)
 	if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
 			(l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
 		int i = 0;
-		u32 sys_cf;
 
 		/* Configure No-Standby */
-		l = p->dma_read(OCP_SYSCONFIG, lch);
-		sys_cf = l;
-		l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
-		l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
-		p->dma_write(l , OCP_SYSCONFIG, 0);
+		if (p->midlemode) {
+			spin_lock_irqsave(&dma_chan_lock, flags);
+			p->midlemode(true);
+			spin_unlock_irqrestore(&dma_chan_lock, flags);
+		}
 
 		l = p->dma_read(CCR, lch);
 		l &= ~OMAP_DMA_CCR_EN;
@@ -958,7 +959,11 @@ void omap_stop_dma(int lch)
 			printk(KERN_ERR "DMA drain did not complete on "
 					"lch %d\n", lch);
 		/* Restore OCP_SYSCONFIG */
-		p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
+		if (p->midlemode) {
+			spin_lock_irqsave(&dma_chan_lock, flags);
+			p->midlemode(false);
+			spin_unlock_irqrestore(&dma_chan_lock, flags);
+		}
 	} else {
 		l &= ~OMAP_DMA_CCR_EN;
 		p->dma_write(l, CCR, lch);
@@ -1610,7 +1615,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
 {
 	int *channels;
 	u32 l, i;
-	u32 sys_cf = 0;
+	unsigned long flags;
 
 	/* Check for input params */
 	if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
@@ -1625,12 +1630,10 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	}
 	channels = dma_linked_lch[chain_id].linked_dmach_q;
 
-	if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
-		sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
-		l = sys_cf;
-		/* Middle mode reg set no Standby */
-		l &= ~((1 << 12)|(1 << 13));
-		p->dma_write(l, OCP_SYSCONFIG, 0);
+	if (IS_DMA_ERRATA(DMA_ERRATA_i88) && p->midlemode) {
+		spin_lock_irqsave(&dma_chan_lock, flags);
+		p->midlemode(true);
+		spin_unlock_irqrestore(&dma_chan_lock, flags);
 	}
 
 	for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
@@ -1650,8 +1653,11 @@ int omap_stop_dma_chain_transfers(int chain_id)
 	/* Reset the Queue pointers */
 	OMAP_DMA_CHAIN_QINIT(chain_id);
 
-	if (IS_DMA_ERRATA(DMA_ERRATA_i88))
-		p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
+	if (IS_DMA_ERRATA(DMA_ERRATA_i88 && p->midlemode)) {
+		spin_lock_irqsave(&dma_chan_lock, flags);
+		p->midlemode(false);
+		spin_unlock_irqrestore(&dma_chan_lock, flags);
+	}
 
 	return 0;
 }
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index d1c916f..b20dc5e 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -435,6 +435,7 @@ struct omap_system_dma_plat_info {
 	void (*clear_dma)(int lch);
 	void (*dma_write)(u32 val, int reg, int lch);
 	u32 (*dma_read)(int reg, int lch);
+	void (*midlemode)(bool nostandby);
 };
 
 extern void omap_set_dma_priority(int lch, int dst_port, int priority);
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/3] OMAP2+: PM: omap device: API's for handling mstandby mode
From: G, Manjunath Kondaiah @ 2011-02-24 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298542475-1460-1-git-send-email-manjugk@ti.com>

Certain errata in OMAP2+ processors will require forcing
master standby to "no standby" mode before completing on going
operation. Without this, the results will be unpredictable.

Since current implementation of PM run time framework does not support
changing sysconfig settings during middle of the on going operation,
these API's will support the same. One API will force the device's
sysconfig mstandby mode settings to "no standby" and other API will
release "no standby" mode and sets it to "smart standby" or "no
standby? depending on HWMOD_SWSUP_MSTANDBY value.

These API's should be used by device drivers only incase of
erratum applicable to their modules if there is no other methods
to resolve.

These API's are required for multiple DMA errata which require
putting DMA controller in no mstandby mode before stopping dma.

The applicable errata:
1. Erratum ID: i557(Applicable for omap36xx all ES versions)
The channel hangs when the Pause bit (DMA4_CDPi [7] ) is cleared
through config port while in Standby.

2. Erratum ID: i541
sDMA FIFO draining does not finish. Applicable to all omap2+ except
omap4.

3. Erratum ID:i88
The sDMA to be put in no mstandby mode before disabling the channel
after completing the data transfer operation.
Applicable only for OMAP3430 ES1.0

Also fixes typo HWMOD_SWSUP_MSTDBY to HWMOD_SWSUP_MSTANDBY in
omap_hwmod.h

Signed-off-by: G, Manjunath Kondaiah <manjugk@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c              |   42 ++++++++++++++++
 arch/arm/plat-omap/include/plat/omap_device.h |    2 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h  |    4 +-
 arch/arm/plat-omap/omap_device.c              |   64 +++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e282e35..27eb845 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1537,6 +1537,48 @@ int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
 }
 
 /**
+ * omap_hwmod_set_master_standbymode - set the hwmod's OCP mstandby mode
+ * @oh: struct omap_hwmod *
+ * @midlemode: flag to set mstandby to either "no standby" or "smart standby"
+ *
+ * Sets the IP block's OCP mstandby mode in hardware, and updates our
+ * local copy.  Intended to be used by drivers that have some erratum
+ * that requires direct manipulation of the MIDLEMODE bits.  Returns
+ * -EINVAL if @oh is null, or passes along the return value from
+ * _set_master_standbymode().
+ *
+ * Any users of this function should be scrutinized carefully.
+ */
+int omap_hwmod_set_master_standbymode(struct omap_hwmod *oh, u8 idlemode)
+{
+	u32 v;
+	u8 sf;
+	int retval = 0;
+
+	if (!oh)
+		return -EINVAL;
+
+	if (!oh->class->sysc)
+		return -EINVAL;
+
+	v = oh->_sysc_cache;
+	sf = oh->class->sysc->sysc_flags;
+
+	if (sf & SYSC_HAS_MIDLEMODE) {
+		if (idlemode)
+			idlemode = HWMOD_IDLEMODE_NO;
+		else
+			idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
+				HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+	}
+	retval = _set_master_standbymode(oh, idlemode, &v);
+	if (!retval)
+		_write_sysconfig(v, oh);
+
+	return retval;
+}
+
+/**
  * omap_hwmod_lookup - look up a registered omap_hwmod by name
  * @name: name of the omap_hwmod to look up
  *
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..42e0186 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -117,6 +117,8 @@ int omap_device_enable_hwmods(struct omap_device *od);
 int omap_device_disable_clocks(struct omap_device *od);
 int omap_device_enable_clocks(struct omap_device *od);
 
+int omap_device_require_no_mstandby(struct platform_device *pdev);
+int omap_device_release_no_mstandby(struct platform_device *pdev);
 
 /*
  * Entries should be kept in latency order ascending
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1eee85a..8a37c6e 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -366,7 +366,7 @@ struct omap_hwmod_omap4_prcm {
  *
  * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
  *     of idle, rather than relying on module smart-idle
- * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
+ * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and out
  *     of standby, rather than relying on module smart-standby
  * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
  *     SDRAM controller, etc. XXX probably belongs outside the main hwmod file
@@ -556,6 +556,8 @@ int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
 
 int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
 
+int omap_hwmod_set_master_standbymode(struct omap_hwmod *oh, u8 idlemode);
+
 int omap_hwmod_reset(struct omap_hwmod *oh);
 void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
 
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 57adb27..125cbef 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -612,6 +612,70 @@ int omap_device_idle(struct platform_device *pdev)
 }
 
 /**
+ * omap_device_require_no_mstandby - set no mstandby mode of an omap_device
+ * @od: struct omap_device * to idle
+ *
+ * Sets the IP block's OCP master standby to no mstandby mode in hardware.
+ *
+ * Intended to be used by drivers that have some erratum that requires direct
+ * manipulation of the MSTANDBYMODE bits. Returns -EINVAL if the
+ * omap_device is not currently enabled or passes along the return value
+ * of omap_hwmod_set_master_standbymode().
+ */
+int omap_device_require_no_mstandby(struct platform_device *pdev)
+{
+	int ret  = 0, i;
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+
+	od = _find_by_pdev(pdev);
+	if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
+		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+		     od->pdev.name, od->pdev.id, __func__, od->_state);
+		return -EINVAL;
+	}
+
+	oh = *od->hwmods;
+	for (i = 0; i < od->hwmods_cnt; i++)
+		ret = omap_hwmod_set_master_standbymode(oh, true);
+
+	return ret;
+}
+
+/**
+ * omap_device_release_no_mstandby - releases no mstandby mode of an omap_device
+ * @od: struct omap_device * to idle
+ *
+ * Release no mstandby mode and sets the master standby to either no standby or
+ * smart standby in IP block's OCP in hardware depending on status of the flag
+ * HWMOD_SWSUP_MSTANDBY.
+ *
+ * Intended to be used by drivers that have some erratum that requires direct
+ * manipulation of the MSTANDBYMODE bits. Returns -EINVAL if the
+ * omap_device is not currently enabled or passes along the return value
+ * of omap_hwmod_set_master_standbymode().
+ */
+int omap_device_release_no_mstandby(struct platform_device *pdev)
+{
+	int ret  = 0, i;
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+
+	od = _find_by_pdev(pdev);
+	if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
+		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+		     od->pdev.name, od->pdev.id, __func__, od->_state);
+		return -EINVAL;
+	}
+
+	oh = *od->hwmods;
+	for (i = 0; i < od->hwmods_cnt; i++)
+		ret = omap_hwmod_set_master_standbymode(oh, false);
+
+	return ret;
+}
+
+/**
  * omap_device_shutdown - shut down an omap_device
  * @od: struct omap_device * to shut down
  *
-- 
1.7.1

^ permalink raw reply related

* [PATCH 0/3] OMAP: DMA: mstandby mode and runtime pm support
From: G, Manjunath Kondaiah @ 2011-02-24 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is remaining part of dma hwmod to support pm runtime 
and for handling mstandby mode for all applicable DMA mstandby mode errata.

The alignment for pm runtime API's usage is at:
http://thread.gmane.org/gmane.linux.ports.arm.omap/51588/focus=52493
http://thread.gmane.org/gmane.linux.ports.arm.omap/50762/focus=50840

The alignment for handling mstandby mode errata handling is at:
http://thread.gmane.org/gmane.linux.ports.arm.omap/47398/focus=47426
http://thread.gmane.org/gmane.linux.ports.arm.omap/47479/focus=47537

Testing:
Compile tested for
 - omap1_defconfig
 - omap2plus_defconfig

Boot test on:
 - OMAP1710-H3
 - OMAP2420-H4
 - OMAP3430-LDP
 - OMAP3630-Zoom3
 - OMAP4430-Blaze

DMA memory to memory test cases(including chaining) are executed for
all the above boards and for each test case, 
/sys/devices/platform/omap/omap_dma_system.0/power/runtime_status
was verified and after completion of the tests, runtime_status will be 
always suspended.

Apart from that, offmode testing is done for OMAP3430-LDP using the procedure:
echo 1 > /debug/pm_debug/sleep_while_idle
echo 1 > /debug/pm_debug/enable_off_mode
echo 5 > /sys/devices/platform/omap/omap_uart.0/sleep_timeout
echo 5 > /sys/devices/platform/omap/omap_uart.1/sleep_timeout
echo 5 > /sys/devices/platform/omap/omap_uart.2/sleep_timeout

With the above steps, core off mode count gets increasing if the the board
is idle for more than 5 seconds.

Baseline:
Applies cleanly on top of mainline 2.6.38-rc6:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
commit f5412be599602124d2bdd49947b231dd77c0bf99
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Mon Feb 21 17:25:52 2011 -0800

    Linux 2.6.38-rc6

Note: OMAP1 is tested on top of 2.6.38-rc5 since rc6 is broken for omap1 build

Patch Summary:
==============
G, Manjunath Kondaiah (2):
  OMAP2+: PM: omap device: API's for handling mstandby mode
  OMAP2+: DMA: prevent races while setting M idle mode to nostandby

Manjunath G Kondaiah (1):
  OMAP: PM: DMA: Enable runtime pm

 arch/arm/mach-omap1/dma.c                     |    1 +
 arch/arm/mach-omap2/dma.c                     |   16 ++
 arch/arm/mach-omap2/omap_hwmod.c              |   42 ++++++
 arch/arm/plat-omap/dma.c                      |  190 +++++++++++++++++++++----
 arch/arm/plat-omap/include/plat/dma.h         |    1 +
 arch/arm/plat-omap/include/plat/omap_device.h |    2 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h  |    4 +-
 arch/arm/plat-omap/omap_device.c              |   64 +++++++++
 8 files changed, 293 insertions(+), 27 deletions(-)

^ permalink raw reply

* [PATCH v10 05/18] OMAP2,3 DSS2 Change driver name to omap_display
From: Tomi Valkeinen @ 2011-02-24  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1295850125-21405-6-git-send-email-sumit.semwal@ti.com>

Hi,

On Mon, 2011-01-24 at 11:51 +0530, ext Sumit Semwal wrote:
> From: Senthilvadivu Guruswamy <svadivu@ti.com>
> 
> Change the driver name from omapdss to omap_display as the driver takes care of
> the display devices ie number of panels, type of panels available in the
> platform.  Change the device name in the board files and 2420,2430,3xxx clock
> files from omapdss to omap_display to match the driver name.

I just realized that changing the driver name will break all scripts and
applications using omapdss sysfs files.

How does this sound:

Let's leave the omapdss device name as it is. It represents a "super"
device, containing the dss sysfs files and upper level dss management.

Name the HW module platform drivers as: omapdss_dss, omapdss_venc,
omapdss_dispc, etc. This would indicate them to be clearly parts of DSS,
and would also prevent any possible name conflict if there would happen
to be a, say, "dsi" block in some other HW component.

 Tomi

^ permalink raw reply


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