SUPERH platform development
 help / color / mirror / Atom feed
* [PATCH] ARM: mach-shmobile: sh7372 A4S Mackerel debug hack
From: Magnus Damm @ 2011-12-18 17:03 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add some quick debugging code on top of the A4S power domain
patch to allow serial printouts before and soon after the power
has been cut/restored. Duplicates the context restore code
located in the SCIF driver in a board specific fashion. Will
only work on Mackerel. Not for upstream inclusion.

Not-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/pm-sh7372.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

--- 0004/arch/arm/mach-shmobile/pm-sh7372.c
+++ work/arch/arm/mach-shmobile/pm-sh7372.c	2011-12-19 01:50:11.000000000 +0900
@@ -7,7 +7,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
-
+#define DEBUG
 #include <linux/pm.h>
 #include <linux/suspend.h>
 #include <linux/cpuidle.h>
@@ -323,7 +323,9 @@ static int sh7372_sysc_valid(unsigned lo
 	mstpsr2 = __raw_readl(MSTPSR2);
 	if ((mstpsr2 & 0x000741ff) != 0x000741ff) {
 		pr_debug("sh7372 mstpsr2 0x%08lx\n", mstpsr2);
+#if 0 /* SCIF console clock will be on, ignore to debug low level A4S code */
 		return 0;
+#endif
 	}
 
 	mstpsr3 = __raw_readl(MSTPSR3);
@@ -475,11 +477,22 @@ static int sh7372_enter_suspend(suspend_
 		/* convert INTC mask and sense to SYSC mask and sense */
 		sh7372_setup_sysc(msk, msk2);
 
-		if (!sh7372_a3sp.stay_on &&
+		if (/*!sh7372_a3sp.stay_on && */
 		    sh7372_a4s.genpd.status = GPD_STATE_POWER_OFF) {
 			/* enter A4S sleep with PLLC0 off */
 			pr_debug("entering A4S\n");
 			sh7372_enter_a4s_common(0);
+
+			/* power up A3SP and setup SCIF console */
+			if (sh7372_a3sp.stay_on) {
+				sh7372_a3sp.stay_on = 0;
+				pd_power_up(&sh7372_a3sp.genpd);
+				sh7372_a3sp.stay_on = 1;
+				__raw_writew(0, 0xE6C40000); /* setup SCIF */
+				__raw_writeb(0x19, 0xE6C40004);
+				__raw_writew(0x0030, 0xE6C40008);
+				pr_debug("SCIF alive and kicking!\n");
+			}
 		} else {
 			/* enter A3SM sleep with PLLC0 off */
 			pr_debug("entering A3SM\n");

^ permalink raw reply

* Re: [PATCH 24/57] fbdev: sh_mobile_lcdc: Return display connection state in display_on
From: Laurent Pinchart @ 2011-12-19  0:21 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-25-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Guennadi,

On Thursday 15 December 2011 18:11:03 Guennadi Liakhovetski wrote:
> On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > Return true if the display is connected and false otherwise. Set the fb
> > info state to FBINFO_STATE_SUSPENDED in the sh_mobile_lcdc driver when
> > the display is not connected.
> 
> Hmm... I'm not sure I like functions, that return either a negative error,
> or _several_ non-negative success values. How about returning -ENODEV?

That would be returning a negative error on success. Is that better ? :-)


-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 12/57] arm: mach-shmobile: Add LCDC tx_dev field to
From: Guennadi Liakhovetski @ 2011-12-19  0:27 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-13-git-send-email-laurent.pinchart@ideasonboard.com>

On Fri, 16 Dec 2011, Laurent Pinchart wrote:

> Hi Guennadi,
> 
> On Thursday 15 December 2011 15:01:27 Guennadi Liakhovetski wrote:
> > On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > > Make sure the transmitter devices get registered before the associated
> > > LCDC devices.
> > > 
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> [snip]
> 
> > > diff --git a/arch/arm/mach-shmobile/board-ap4evb.c
> > > b/arch/arm/mach-shmobile/board-ap4evb.c index dca4860..e0a6b3d 100644
> > > --- a/arch/arm/mach-shmobile/board-ap4evb.c
> > > +++ b/arch/arm/mach-shmobile/board-ap4evb.c
> 
> [snip]
> 
> > > @@ -627,6 +553,86 @@ static struct platform_device *qhd_devices[]
> > > __initdata = {
> > > 
> > >  };
> > >  #endif /* CONFIG_AP4EVB_QHD */
> > > 
> > > +/* LCDC0 */
> > > +static const struct fb_videomode ap4evb_lcdc_modes[] = {
> > 
> > Hm, I must be missing something. I thought you were moving all the structs
> > around to make them available for reference _without_ forward
> > declarations. But you _do_ end up using a forward declaration anyway. Here
> > and for HDMI below too. So, what's the point? Why not just forward declare
> > that one struct, that's needed and leave the rest where it currently is
> > in the file?
> 
> As we have circular dependencies forward declaration can't be avoided. I found 
> it cleaner to have devices data in registration order in the board file, but I 
> can remove this if you prefer.

As a _general_ guidline I find smaller patches more pleasant than 
bigger;-) but if you really see an important advantage in moving these 
structs around - I can live with that too:-)

> > > +	{
> > > +#ifdef CONFIG_AP4EVB_QHD
> > > +		.name		= "R63302(QHD)",
> > > +		.xres		= 544,
> > > +		.yres		= 961,
> > > +		.left_margin	= 72,
> > > +		.right_margin	= 600,
> > > +		.hsync_len	= 16,
> > > +		.upper_margin	= 8,
> > > +		.lower_margin	= 8,
> > > +		.vsync_len	= 2,
> > > +		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
> > > +#else
> > > +		.name		= "WVGA Panel",
> > > +		.xres		= 800,
> > > +		.yres		= 480,
> > > +		.left_margin	= 220,
> > > +		.right_margin	= 110,
> > > +		.hsync_len	= 70,
> > > +		.upper_margin	= 20,
> > > +		.lower_margin	= 5,
> > > +		.vsync_len	= 5,
> > > +		.sync		= 0,
> > > +#endif
> > > +	},
> > > +};
> 
> [snip]
> 
> > > diff --git a/arch/arm/mach-shmobile/board-mackerel.c
> > > b/arch/arm/mach-shmobile/board-mackerel.c index 4ed0138..ccdd9fc 100644
> > > --- a/arch/arm/mach-shmobile/board-mackerel.c
> > > +++ b/arch/arm/mach-shmobile/board-mackerel.c
> 
> [snip]
> 
> > > @@ -1313,8 +1317,8 @@ static struct platform_device *mackerel_devices[]
> > > __initdata = {
> > >  	&sh_mmcif_device,
> > >  	&ceu_device,
> > >  	&mackerel_camera,
> > > -	&hdmi_lcdc_device,
> > >  	&hdmi_device,
> > > +	&hdmi_lcdc_device,
> > >  	&meram_device,
> > >  };
> > 
> > Sorry, could you elaborate, why this is needed? If this is really
> > important, then I'd prefer to test this before committing. If OTOH this is
> > unimportant, and my assumption, that normally it's the platform driver
> > registration order, that's important, not device registration order, is
> > correct, then you don't have to swap the order?
> 
> If both the transmitter and LCDC drivers are built-in, the device probe order 
> is the device registration order. As we need the transmitter to be probed 
> first, it needs to be registered first.

Even there I'm not quite sure about - I do remember having to fiddle with 
the Makefiles to change the probe order, which followed the linkage order. 
Could be, that this has changed since I last checked, but I'd really 
double-check this.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [PATCH 27/57] fbdev: sh_mobile_lcdc: Pass a video mode to the notify callback
From: Laurent Pinchart @ 2011-12-19  1:29 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-28-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Guennadi,

On Friday 16 December 2011 11:33:55 Guennadi Liakhovetski wrote:
> On Fri, 16 Dec 2011, Laurent Pinchart wrote:
> > On Thursday 15 December 2011 20:01:54 Guennadi Liakhovetski wrote:
> > > On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > > > Pass pointers to struct fb_videomode and struct fb_monspecs instead
> > > > of struct fb_var_screeninfo to the notify callback.
> > > > 
> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > > ---
> > > > 
> > > >  drivers/video/sh_mobile_hdmi.c   |   59
> > > >  +++++++++++++++++--------------------
> > > >  drivers/video/sh_mobile_lcdcfb.c
> > > >  
> > > >  |   40 ++++++++++++++----------- drivers/video/sh_mobile_lcdcfb.h |
> > > >  
> > > >  3 +-
> > > >  3 files changed, 51 insertions(+), 51 deletions(-)
> > > 
> > > [snip]
> > > 
> > > > diff --git a/drivers/video/sh_mobile_lcdcfb.c
> > > > b/drivers/video/sh_mobile_lcdcfb.c index 21e5f10..4ec216e 100644
> > > > --- a/drivers/video/sh_mobile_lcdcfb.c
> > > > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > > 
> > > [ditto]
> > > 
> > > > @@ -433,12 +432,17 @@ static int sh_mobile_lcdc_display_notify(struct
> > > > sh_mobile_lcdc_chan *ch,
> > > > 
> > > >  		}
> > > >  		break;
> > > > 
> > > > -	case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE:
> > > > +	case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE: {
> > > > +		struct fb_var_screeninfo var;
> > > > +
> > > > 
> > > >  		/* Validate a proposed new mode */
> > > > 
> > > > -		var->bits_per_pixel = info->var.bits_per_pixel;
> > > > -		ret = info->fbops->fb_check_var(var, info);
> > > > +		fb_videomode_to_var(&var, mode);
> > > > +		var.bits_per_pixel = info->var.bits_per_pixel;
> > > > +		var.grayscale = info->var.grayscale;
> > > > +		ret = info->fbops->fb_check_var(&var, info);
> > > > 
> > > >  		break;
> > > >  	
> > > >  	}
> > > > 
> > > > +	}
> > > 
> > > nitpick - please, realign:-)
> > 
> > It's common in driver code not to increase the identation level twice in
> > a case statement if braces are needed. However, those "braced"
> > statements are usually not the last ones in the switch. In this
> > particular case this creates an alignment issue at the end, as your
> > correctly pointed out. However, I'd like to avoid increasing the
> > indentation of the whole block. Increasing the indentation of the
> > closing brace only also causes an alignment issue. I can add a default
> > case that returns an error to fix this, but that's adding code to fix a
> > cosmetic problem :-) What's your preference.
> 
> Personally, I don't like just using braces without a related statement
> like "if," "do," etc. In such "case" cases I usually avoid adding own
> braces and just put any declarations, that are needed there in the
> enclosing block, e.g., the function.

Using braces with case statements is a common practice in the kernel, without 
adding an extra indentation level.

In this particular case I can move the variable declaration at the top of the 
function, as the generated code on ARM (at least with gcc ('cs2009q3-67-hard-
sb4') 4.4.1) doesn't differ.

> If you really don't want either, I would probably prefer a style like
> 
> 	switch (x) {
> 	case X:
> 		{
> 			int y;
> 			my_statement(y);
> 			break;
> 		}
> 	}
> 
> You could also do
> 
> 	switch (x) {
> 	case X:
> 		do {
> 			int y;
> 			my_statement(y);
> 			break;
> 		} while (0);
> 	}
> 
> So, choose your poison:-)


-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Ulf Hansson @ 2011-12-19 12:17 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Rafael J. Wysocki, linux-mmc@vger.kernel.org,
	linux-pm@vger.kernel.org, Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <Pine.LNX.4.64.1112160954030.6572@axis700.grange>

Guennadi Liakhovetski wrote:
> On Wed, 14 Dec 2011, Rafael J. Wysocki wrote:
> 
>> On Wednesday, December 14, 2011, Ulf Hansson wrote:
> 
> [snip]
> 
>>> 2.
>>> When executing mmc/sd commands/requests the host must always be claimed 
>>> (and thus the host is always enabled).
> 
> Why? Why cannot we save some power between IO operations - if we can do 
> this quickly and safely without affecting functionality and throughput?
> 
>>> But more important some mmc/sd 
>>> commands must be executed as a sequence, without the host being disabled 
>>> in between the commands (since a disable might mean that the clock to 
>>> card gets disabled).
> 
> Ok, there might well be such command sequences, but my question is: who 
> knows about them? Is this mandated by the MMC(/SD/SDIO/...) standard or is 
> it host-specific? Also "might mean" is actually interesting here. I think 
> we eventually need a combination of timing-oriented PM constraints and 
> "stateful" ones. During such a command sequence you would require the card 
> clock to stay on.

MMC/SD/SDIO standard sets the requirement and must somehow "notify" the 
host about how to act in certain scenarios.

Just for information, I think one interesting host driver to look at is 
omap_hsmmc. For it's enable function is does pm_runtime_get_sync and for 
it's disable function it does pm_runtime_put_autosuspend, this to make 
sure the clock is enabled when it is needed.


> 
>>> To solve this, the mmc_claim_host is used, to make 
>>> sure the host is enabled during the complete command sequence.
>>>
>>> I happily continue this discussion, to see if someone more can break the 
>>> idea about having get_sync in mmc_host_enable. :-)
>> I'll leave this one to Guennadi, if you don't mind. :-)
> 
> As I said above, I think, we need both - to be able to require a certain 
> responsiveness / throughput and specific interface parameters like 
> supplying clock, power, etc.
> 
> Also notice, that setting a constraint doesn't affect in principle, when 
> the device is allowed to suspend. This is done as usual per 
> pm_runtime_get*() and _put*(). I think, a reasonable solution to use PM 
> QoS to impose timing constraints but at the same time to not disable the 
> hardware, when this is disallowed, is to tie pm_runtime_get() and _put() 
> calls to driver's .set_ios() method, like tmio_mmc and sh_mmcif drivers 
> currently do. Those drivers only call pm_runtime_put() when the interface 
> clock is gated. So, as long as the core is aware, that that IO sequence 
> has to run uninterrupted without stopping the clock between single 
> transfers, it just has to avoid gating the clock for that period and the 
> interface will not enter any power-saving mode.
> 
> So, I don't think we need to enforce pm_runtime_get_sync() in 
> mmc_claim_host().

You might be right; but still we need a way for the mmc framework to 
prevent the host driver from disabling clock etc to the card for some 
command sequences. As the omap driver solves it is to implement the 
enable/disable function and then call for get_sync and put in these 
functions, maybe that is the way how to solve this!?

Br
Ulf Hansson


^ permalink raw reply

* Dear Sir/Madam,
From:  I am Dr. Joe working in a pharmaceutical company based in London @ 2011-12-19 14:57 UTC (permalink / raw)


I am Dr. Joe working in a pharmaceutical company based in London,
United Kingdom.based on our company's urgent need to
establish a mutual business relationship with a company or an individual in
India; contact me through my private email
address mentioned below: {joe_moore@w.cn} for more detail


^ permalink raw reply

* [GIT PULL] sh fixes for 3.2-rc7
From: Paul Mundt @ 2011-12-20  8:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-sh, linux-kernel

Please pull from:

        git://github.com/pmundt/linux-sh.git sh-fixes-for-linus

Which contains:

Yoshihiro Shimoda (1):
      sh: fix build warning in board-sh7757lcr

 arch/sh/boards/board-sh7757lcr.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

^ permalink raw reply

* [GIT PULL] rmobile fixes for 3.2-rc7
From: Paul Mundt @ 2011-12-20  8:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-sh, linux-kernel

Please pull from:

        git://github.com/pmundt/linux-sh.git rmobile-fixes-for-linus

Which contains:

Magnus Damm (5):
      ARM: mach-shmobile: Kota2 PINT fix
      ARM: mach-shmobile: Kota2 GIC Sparse IRQ fix
      ARM: mach-shmobile: Kota2 TPU LED platform data
      ARM: mach-shmobile: AG5EVM GIC Sparse IRQ fix
      ARM: mach-shmobile: SH73A0 external Ethernet fix

 arch/arm/mach-shmobile/board-ag5evm.c |    1 +
 arch/arm/mach-shmobile/board-kota2.c  |  139 ++++++++++++++++++++++++++++----
 arch/arm/mach-shmobile/clock-sh73a0.c |   18 ++++-
 3 files changed, 139 insertions(+), 19 deletions(-)

^ permalink raw reply

* [PATCH v2] sh: sh2a: Optimise cache functions.
From: Phil Edworthy @ 2011-12-20  8:40 UTC (permalink / raw)
  To: linux-sh

When invalidating a large address range, it's better to invalidate
the entire cache rather than individual addresses.

Also, when the operand cache is set to write-though mode, there is
no need to flush data.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
---
 arch/sh/mm/cache-sh2a.c |   74 +++++++++++++++++++++++++++++------------------
 1 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 1f51225..b1bdef1 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,8 +15,20 @@
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
+/*
+ * The maximum number of pages we support up to when doing ranged cache
+ * flushing. Anything exceeding this will simply flush the cache in its
+ * entirety.
+ */
+#define MAX_OCACHE_PAGES	32
+#define MAX_ICACHE_PAGES	32
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ */
 static void sh2a__flush_wback_region(void *start, int size)
 {
+#ifdef CONFIG_CACHE_WRITEBACK
 	unsigned long v;
 	unsigned long begin, end;
 	unsigned long flags;
@@ -42,8 +54,12 @@ static void sh2a__flush_wback_region(void *start, int size)
 
 	back_to_cached();
 	local_irq_restore(flags);
+#endif
 }
 
+/*
+ * Write back the dirty D-caches and invalidate them.
+ */
 static void sh2a__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
@@ -61,10 +77,14 @@ static void sh2a__flush_purge_region(void *start, int size)
 		__raw_writel((v & CACHE_PHYSADDR_MASK),
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
 	}
+
 	back_to_cached();
 	local_irq_restore(flags);
 }
 
+/*
+ * Invalidate the D-caches, but no write back please
+ */
 static void sh2a__flush_invalidate_region(void *start, int size)
 {
 	unsigned long v;
@@ -74,29 +94,27 @@ static void sh2a__flush_invalidate_region(void *start, int size)
 	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
 	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
 		& ~(L1_CACHE_BYTES-1);
+
 	local_irq_save(flags);
 	jump_to_uncached();
 
-#ifdef CONFIG_CACHE_WRITEBACK
-	__raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
-	/* I-cache invalidate */
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		__raw_writel((v & CACHE_PHYSADDR_MASK),
-			  CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
-	}
-#else
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		__raw_writel((v & CACHE_PHYSADDR_MASK),
-			  CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
-		__raw_writel((v & CACHE_PHYSADDR_MASK),
-			  CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
+	/* If there are too many pages then just blow the cache */
+	if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
+		__raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
+	} else {
+		for (v = begin; v < end; v+=L1_CACHE_BYTES) {
+			__raw_writel((v & CACHE_PHYSADDR_MASK),
+				  CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
+		}
 	}
-#endif
+
 	back_to_cached();
 	local_irq_restore(flags);
 }
 
-/* WBack O-Cache and flush I-Cache */
+/*
+ * Write back the range of D-cache, and purge the I-cache.
+ */
 static void sh2a_flush_icache_range(void *args)
 {
 	struct flusher_data *data = args;
@@ -107,23 +125,23 @@ static void sh2a_flush_icache_range(void *args)
 	start = data->addr1 & ~(L1_CACHE_BYTES-1);
 	end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
 
+#ifdef CONFIG_CACHE_WRITEBACK
+	sh2a__flush_wback_region((void *)start, end-start);
+#endif
+
 	local_irq_save(flags);
 	jump_to_uncached();
 
-	for (v = start; v < end; v+=L1_CACHE_BYTES) {
-		unsigned long addr = (v & 0x000007f0);
-		int way;
-		/* O-Cache writeback */
-		for (way = 0; way < 4; way++) {
-			unsigned long data =  __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
-			if ((data & CACHE_PHYSADDR_MASK) = (v & CACHE_PHYSADDR_MASK)) {
-				data &= ~SH_CACHE_UPDATED;
-				__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
-			}
+	/* I-Cache invalidate */
+	/* If there are too many pages then just blow the cache */
+	if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
+		__raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR);
+	} else {
+		for (v = start; v < end; v+=L1_CACHE_BYTES) {
+			unsigned long addr = (v & 0x000007f0);
+			__raw_writel(addr,
+				  CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
 		}
-		/* I-Cache invalidate */
-		__raw_writel(addr,
-			  CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
 	}
 
 	back_to_cached();
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/2] ARM: mach-shmobile: clock-r8a7779: patches
From: Kuninori Morimoto @ 2011-12-20  8:46 UTC (permalink / raw)
  To: linux-sh


Hi Paul, Magnus

These are r8a7779 clock update patches which depends on Magnus's
[ARM: mach-shmobile: r8a7779 and Marzen V2] patches

Kuninori Morimoto (2):
      ARM: mach-shmobile: clock-r8a7779: add DIV4 clock support
      ARM: mach-shmobile: clock-r8a7779: clkz/clkzs support

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* [PATCH 1/2] ARM: mach-shmobile: clock-r8a7779: add DIV4 clock support
From: Kuninori Morimoto @ 2011-12-20  8:52 UTC (permalink / raw)
  To: linux-sh

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 arch/arm/mach-shmobile/clock-r8a7779.c |   76 ++++++++++++++++++++++++-------
 1 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 8a90106..29c3306 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -45,36 +45,75 @@ static struct clk_mapping cpg_mapping = {
 	.len	= 0x80,
 };
 
-static struct clk clkp = {
-	.rate	= 62500000, /* FIXME: shortcut */
-	.flags	= CLK_ENABLE_ON_INIT,
-	.mapping = &cpg_mapping,
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk plla_clk = {
+	.rate		= 1500000000,
+	.mapping	= &cpg_mapping,
 };
 
 static struct clk *main_clks[] = {
-	&clkp,
+	&plla_clk,
+};
+
+static int divisors[] = { 0, 0, 0, 6, 8, 12, 16, 0, 24, 32, 36, 0, 0, 0, 0, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = divisors,
+	.nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
+enum { DIV4_S, DIV4_OUT, DIV4_S4, DIV4_S3, DIV4_S1, DIV4_P, DIV4_NR };
+
+static struct clk div4_clks[DIV4_NR] = {
+	[DIV4_S]	= SH_CLK_DIV4(&plla_clk, FRQMR, 20,
+				      0x0018, CLK_ENABLE_ON_INIT),
+	[DIV4_OUT]	= SH_CLK_DIV4(&plla_clk, FRQMR, 16,
+				      0x0700, CLK_ENABLE_ON_INIT),
+	[DIV4_S4]	= SH_CLK_DIV4(&plla_clk, FRQMR, 12,
+				      0x0040, CLK_ENABLE_ON_INIT),
+	[DIV4_S3]	= SH_CLK_DIV4(&plla_clk, FRQMR, 8,
+				      0x0010, CLK_ENABLE_ON_INIT),
+	[DIV4_S1]	= SH_CLK_DIV4(&plla_clk, FRQMR, 4,
+				      0x0060, CLK_ENABLE_ON_INIT),
+	[DIV4_P]	= SH_CLK_DIV4(&plla_clk, FRQMR, 0,
+				      0x0300, CLK_ENABLE_ON_INIT),
 };
 
 enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
 	MSTP016, MSTP015, MSTP014,
 	MSTP_NR };
 
-#define MSTP(_parent, _reg, _bit, _flags) \
-	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
-
 static struct clk mstp_clks[MSTP_NR] = {
-	[MSTP026] = MSTP(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
-	[MSTP025] = MSTP(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
-	[MSTP024] = MSTP(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
-	[MSTP023] = MSTP(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
-	[MSTP022] = MSTP(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
-	[MSTP021] = MSTP(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
-	[MSTP016] = MSTP(&clkp, MSTPCR0, 16, 0), /* TMU0 */
-	[MSTP015] = MSTP(&clkp, MSTPCR0, 15, 0), /* TMU1 */
-	[MSTP014] = MSTP(&clkp, MSTPCR0, 14, 0), /* TMU2 */
+	[MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */
+	[MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */
+	[MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */
+	[MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0), /* SCIF3 */
+	[MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0), /* SCIF4 */
+	[MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), /* SCIF5 */
+	[MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), /* TMU0 */
+	[MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), /* TMU1 */
+	[MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), /* TMU2 */
 };
 
 static struct clk_lookup lookups[] = {
+	/* main clocks */
+	CLKDEV_CON_ID("plla_clk", &plla_clk),
+
+	/* DIV4 clocks */
+	CLKDEV_CON_ID("shyway_clk",	&div4_clks[DIV4_S]),
+	CLKDEV_CON_ID("bus_clk",	&div4_clks[DIV4_OUT]),
+	CLKDEV_CON_ID("shyway4_clk",	&div4_clks[DIV4_S4]),
+	CLKDEV_CON_ID("shyway3_clk",	&div4_clks[DIV4_S3]),
+	CLKDEV_CON_ID("shyway1_clk",	&div4_clks[DIV4_S1]),
+	CLKDEV_CON_ID("peripheral_clk",	&div4_clks[DIV4_P]),
+
 	/* MSTP32 clocks */
 	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
 	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
@@ -94,6 +133,9 @@ void __init r8a7779_clock_init(void)
 		ret = clk_register(main_clks[k]);
 
 	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+	if (!ret)
 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 2/2] ARM: mach-shmobile: clock-r8a7779: clkz/clkzs support
From: Kuninori Morimoto @ 2011-12-20  8:53 UTC (permalink / raw)
  To: linux-sh

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 arch/arm/mach-shmobile/clock-r8a7779.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 29c3306..b4b0e8c 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -102,9 +102,35 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), /* TMU2 */
 };
 
+static unsigned long mul4_recalc(struct clk *clk)
+{
+	return clk->parent->rate * 4;
+}
+
+static struct clk_ops mul4_clk_ops = {
+	.recalc		= mul4_recalc,
+};
+
+struct clk clkz_clk = {
+	.ops		= &mul4_clk_ops,
+	.parent		= &div4_clks[DIV4_S],
+};
+
+struct clk clkzs_clk = {
+	/* clks x 4 / 4 = clks */
+	.parent		= &div4_clks[DIV4_S],
+};
+
+static struct clk *late_main_clks[] = {
+	&clkz_clk,
+	&clkzs_clk,
+};
+
 static struct clk_lookup lookups[] = {
 	/* main clocks */
 	CLKDEV_CON_ID("plla_clk", &plla_clk),
+	CLKDEV_CON_ID("clkz_clk", &clkz_clk),
+	CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
 
 	/* DIV4 clocks */
 	CLKDEV_CON_ID("shyway_clk",	&div4_clks[DIV4_S]),
@@ -138,6 +164,9 @@ void __init r8a7779_clock_init(void)
 	if (!ret)
 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
+	for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+		ret = clk_register(late_main_clks[k]);
+
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	if (!ret)
-- 
1.7.5.4


^ permalink raw reply related

* Re: [GIT PULL] rmobile fixes for 3.2-rc7
From: Linus Torvalds @ 2011-12-20 19:39 UTC (permalink / raw)
  To: Paul Mundt; +Cc: linux-sh, linux-kernel
In-Reply-To: <20111220082416.GA21727@linux-sh.org>

On Tue, Dec 20, 2011 at 12:24 AM, Paul Mundt <lethal@linux-sh.org> wrote:
> Please pull from:
>
>        git://github.com/pmundt/linux-sh.git rmobile-fixes-for-linus

Ugh. Since git does it so well these days, I'd really like to pull
signed tags only from places like github.

I pulled this, but it would really be quite easy to just have the pull
request be for a signed tag you upload instead of a branch, and then I
wouldn't have to worry about it.

                   Linus

^ permalink raw reply

* [PATCH] ARM: mach-shmobile: r8a7779 power domain support
From: Magnus Damm @ 2011-12-22  8:12 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add power domain control support for the r8a7779 SoC.

This adds support for 4 power domains for I/O Devices
together with code that can be used for CPU cores as well.

The only out of the ordinary experience is the need for
ioremap() of SYSC registers. Because of that we need to
execute some init function before setting up the domains.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Built on top of linux-3.2-rc + r8a7779 patches for now.
 Needs to be reworked to fit on top of the linux-pm tree.

 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/include/mach/common.h  |    1 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |   35 +++
 arch/arm/mach-shmobile/pm-r8a7779.c           |  235 +++++++++++++++++++++++++
 arch/arm/mach-shmobile/setup-r8a7779.c        |    8 
 5 files changed, 280 insertions(+)

--- 0015/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-22 16:21:03.000000000 +0900
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_R8A7779)	+= entry-gic.
 obj-$(CONFIG_SUSPEND)		+= suspend.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 obj-$(CONFIG_ARCH_SH7372)	+= pm-sh7372.o sleep-sh7372.o
+obj-$(CONFIG_ARCH_R8A7779)	+= pm-r8a7779.o
 
 # Board objects
 obj-$(CONFIG_MACH_G3EVM)	+= board-g3evm.o
--- 0015/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-22 16:21:03.000000000 +0900
@@ -58,5 +58,6 @@ extern void r8a7779_add_early_devices(vo
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
+extern void r8a7779_pm_init(void);
 
 #endif /* __ARCH_MACH_COMMON_H */
--- 0016/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-22 16:22:01.000000000 +0900
@@ -1,6 +1,9 @@
 #ifndef __ASM_R8A7779_H__
 #define __ASM_R8A7779_H__
 
+#include <linux/sh_clk.h>
+#include <linux/pm_domain.h>
+
 /* Pin Function Controller:
  * GPIO_FN_xx - GPIO used to select pin function
  * GPIO_GP_x_x - GPIO mapped to real I/O pin on CPU
@@ -322,4 +325,36 @@ enum {
 	GPIO_FN_GPS_MAG, GPIO_FN_FCE, GPIO_FN_SCK4_B,
 };
 
+struct platform_device;
+
+struct r8a7779_pm_ch {
+	unsigned long chan_offs;
+	unsigned int chan_bit;
+	unsigned int isr_bit;
+};
+
+struct r8a7779_pm_domain {
+	struct generic_pm_domain genpd;
+	struct r8a7779_pm_ch ch;
+};
+
+static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d)
+{
+	return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
+}
+
+#ifdef CONFIG_PM
+extern struct r8a7779_pm_domain r8a7779_sh4a;
+extern struct r8a7779_pm_domain r8a7779_sgx;
+extern struct r8a7779_pm_domain r8a7779_vdp1;
+extern struct r8a7779_pm_domain r8a7779_impx3;
+
+extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd);
+extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
+					struct platform_device *pdev);
+#else
+#define r8a7779_init_pm_domain(pd) do { } while (0)
+#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
+#endif /* CONFIG_PM */
+
 #endif /* __ASM_R8A7779_H__ */
--- /dev/null
+++ work/arch/arm/mach-shmobile/pm-r8a7779.c	2011-12-22 16:21:44.000000000 +0900
@@ -0,0 +1,235 @@
+/*
+ * r8a7779 Power management support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <mach/common.h>
+#include <mach/r8a7779.h>
+
+static void __iomem *r8a7779_sysc_base;
+
+/* SYSC */
+#define SYSCSR 0x00
+#define SYSCISR 0x04
+#define SYSCISCR 0x08
+#define SYSCIER 0x0c
+#define SYSCIMR 0x10
+#define PWRSR0 0x40
+#define PWRSR1 0x80
+#define PWRSR2 0xc0
+#define PWRSR3 0x100
+#define PWRSR4 0x140
+
+#define PWRSR_OFFS 0x00
+#define PWROFFCR_OFFS 0x04
+#define PWRONCR_OFFS 0x0c
+#define PWRER_OFFS 0x14
+
+#define SYSCSR_RETRIES 100
+#define SYSCSR_DELAY_US 1
+
+#define SYSCISR_RETRIES 1000
+#define SYSCISR_DELAY_US 1
+
+#ifdef CONFIG_PM
+
+static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch,
+				   int sr_bit, int reg_offs)
+{
+	int k;
+
+	for (k = 0; k < SYSCSR_RETRIES; k++) {
+		if (ioread32(r8a7779_sysc_base + SYSCSR) & (1 << sr_bit))
+			break;
+		udelay(SYSCSR_DELAY_US);
+	}
+
+	if (k = SYSCSR_RETRIES)
+		return -EAGAIN;
+
+	iowrite32(1 << r8a7779_ch->chan_bit,
+		  r8a7779_sysc_base + r8a7779_ch->chan_offs + reg_offs);
+
+	return 0;
+}
+
+static int r8a7779_sysc_pwr_off(struct r8a7779_pm_ch *r8a7779_ch)
+{
+	return r8a7779_sysc_pwr_on_off(r8a7779_ch, 0, PWROFFCR_OFFS);
+}
+
+static int r8a7779_sysc_pwr_on(struct r8a7779_pm_ch *r8a7779_ch)
+{
+	return r8a7779_sysc_pwr_on_off(r8a7779_ch, 1, PWRONCR_OFFS);
+}
+
+static int r8a7779_sysc_update(struct r8a7779_pm_ch *r8a7779_ch,
+			       int (*on_off_fn)(struct r8a7779_pm_ch *))
+{
+	unsigned int isr_mask = 1 << r8a7779_ch->isr_bit;
+	unsigned int chan_mask = 1 << r8a7779_ch->chan_bit;
+	unsigned int status;
+	int ret = 0;
+	int k;
+
+	iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
+
+	do {
+		ret = on_off_fn(r8a7779_ch);
+		if (ret)
+			goto out;
+
+		status = ioread32(r8a7779_sysc_base +
+				  r8a7779_ch->chan_offs + PWRER_OFFS);
+	} while (status & chan_mask);
+
+	for (k = 0; k < SYSCISR_RETRIES; k++) {
+		if (ioread32(r8a7779_sysc_base + SYSCISR) & isr_mask)
+			break;
+		udelay(SYSCISR_DELAY_US);
+	}
+
+	if (k = SYSCISR_RETRIES)
+		ret = -EIO;
+
+	iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
+
+ out:
+	pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n",
+		 r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0),
+		 ioread32(r8a7779_sysc_base + PWRSR1),
+		 ioread32(r8a7779_sysc_base + PWRSR2),
+		 ioread32(r8a7779_sysc_base + PWRSR3),
+		 ioread32(r8a7779_sysc_base + PWRSR4), ret);
+	return ret;
+}
+
+static int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
+{
+	return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
+}
+
+static int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
+{
+	return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
+}
+
+static void __init r8a7779_sysc_init(void)
+{
+	r8a7779_sysc_base = ioremap_nocache(0xffd85000, PAGE_SIZE);
+	if (!r8a7779_sysc_base)
+		panic("unable to ioremap r8a7779 SYSC hardware block\n");
+
+	/* enable all interrupt sources, but do not use interrupt handler */
+	iowrite32(0x0131000e, r8a7779_sysc_base + SYSCIER);
+	iowrite32(0, r8a7779_sysc_base + SYSCIMR);
+}
+
+static int pd_power_down(struct generic_pm_domain *genpd)
+{
+	return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
+}
+
+static int pd_power_up(struct generic_pm_domain *genpd)
+{
+	return r8a7779_sysc_power_up(to_r8a7779_ch(genpd));
+}
+
+static bool pd_is_off(struct generic_pm_domain *genpd)
+{
+	struct r8a7779_pm_ch *r8a7779_ch = to_r8a7779_ch(genpd);
+	unsigned int st;
+
+	st = ioread32(r8a7779_sysc_base + r8a7779_ch->chan_offs + PWRSR_OFFS);
+	if (st & (1 << r8a7779_ch->chan_bit))
+		return true;
+
+	return false;
+}
+
+static bool pd_active_wakeup(struct device *dev)
+{
+	return true;
+}
+
+void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
+{
+	struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
+
+	pm_genpd_init(genpd, NULL, false);
+	genpd->stop_device = pm_clk_suspend;
+	genpd->start_device = pm_clk_resume;
+	genpd->dev_irq_safe = true;
+	genpd->active_wakeup = pd_active_wakeup;
+	genpd->power_off = pd_power_down;
+	genpd->power_on = pd_power_up;
+
+	if (pd_is_off(&r8a7779_pd->genpd))
+		pd_power_up(&r8a7779_pd->genpd);
+}
+
+void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
+				 struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	pm_genpd_add_device(&r8a7779_pd->genpd, dev);
+	if (pm_clk_no_clocks(dev))
+		pm_clk_add(dev, NULL);
+}
+
+struct r8a7779_pm_domain r8a7779_sh4a = {
+	.ch = {
+		.chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
+		.isr_bit = 16, /* SH4A */
+	}
+};
+
+struct r8a7779_pm_domain r8a7779_sgx = {
+	.ch = {
+		.chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
+		.isr_bit = 20, /* SGX */
+	}
+};
+
+struct r8a7779_pm_domain r8a7779_vdp1 = {
+	.ch = {
+		.chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
+		.isr_bit = 21, /* VDP */
+	}
+};
+
+struct r8a7779_pm_domain r8a7779_impx3 = {
+	.ch = {
+		.chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
+		.isr_bit = 24, /* IMP */
+	}
+};
+
+#else /* CONFIG_PM */
+
+static inline void r8a7779_sysc_init(void) {}
+
+#endif /* CONFIG_PM */
+
+void __init r8a7779_pm_init(void)
+{
+	r8a7779_sysc_init();
+}
--- 0021/arch/arm/mach-shmobile/setup-r8a7779.c
+++ work/arch/arm/mach-shmobile/setup-r8a7779.c	2011-12-22 16:21:03.000000000 +0900
@@ -30,6 +30,7 @@
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
+#include <mach/common.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -218,6 +219,13 @@ static struct platform_device *r8a7779_l
 
 void __init r8a7779_add_standard_devices(void)
 {
+	r8a7779_pm_init();
+
+	r8a7779_init_pm_domain(&r8a7779_sh4a);
+	r8a7779_init_pm_domain(&r8a7779_sgx);
+	r8a7779_init_pm_domain(&r8a7779_vdp1);
+	r8a7779_init_pm_domain(&r8a7779_impx3);
+
 	platform_add_devices(r8a7779_early_devices,
 			    ARRAY_SIZE(r8a7779_early_devices));
 	platform_add_devices(r8a7779_late_devices,

^ permalink raw reply

* [PATCH] ARM: mach-shmobile: r8a7779 SMP support
From: Magnus Damm @ 2011-12-22  8:17 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

This patch ties in the r8a7779 power domain code together with
SMP glue code to add SMP support. The SMP code allows us to
control the power domains via CPU hotplug, but this feature
is not fully implemented yet. At this point the kernel boots
with the 4 Cortex-A9 cores in SMP mode.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Depends on the r8a7779 base plus the power domain code:
 [PATCH] ARM: mach-shmobile: r8a7779 power domain support

 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/include/mach/common.h  |    5 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |    3 
 arch/arm/mach-shmobile/platsmp.c              |   13 ++
 arch/arm/mach-shmobile/pm-r8a7779.c           |   30 ++++-
 arch/arm/mach-shmobile/smp-r8a7779.c          |  131 +++++++++++++++++++++++++
 6 files changed, 175 insertions(+), 8 deletions(-)

--- 0022/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-22 16:49:45.000000000 +0900
@@ -17,6 +17,7 @@ smp-y				:= platsmp.o headsmp.o
 smp-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 smp-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
 smp-$(CONFIG_ARCH_SH73A0)	+= smp-sh73a0.o
+smp-$(CONFIG_ARCH_R8A7779)	+= smp-r8a7779.o
 
 # Pinmux setup
 pfc-y				:--- 0022/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-22 16:49:45.000000000 +0900
@@ -60,4 +60,9 @@ extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
 
+extern unsigned int r8a7779_get_core_count(void);
+extern void r8a7779_secondary_init(unsigned int cpu);
+extern int r8a7779_boot_secondary(unsigned int cpu);
+extern void r8a7779_smp_prepare_cpus(void);
+
 #endif /* __ARCH_MACH_COMMON_H */
--- 0022/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-22 16:49:45.000000000 +0900
@@ -343,6 +343,9 @@ static inline struct r8a7779_pm_ch *to_r
 	return &container_of(d, struct r8a7779_pm_domain, genpd)->ch;
 }
 
+extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch);
+extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch);
+
 #ifdef CONFIG_PM
 extern struct r8a7779_pm_domain r8a7779_sh4a;
 extern struct r8a7779_pm_domain r8a7779_sgx;
--- 0001/arch/arm/mach-shmobile/platsmp.c
+++ work/arch/arm/mach-shmobile/platsmp.c	2011-12-22 16:49:45.000000000 +0900
@@ -22,12 +22,16 @@
 #include <mach/common.h>
 
 #define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2())
+#define is_r8a7779() machine_is_marzen()
 
 static unsigned int __init shmobile_smp_get_core_count(void)
 {
 	if (is_sh73a0())
 		return sh73a0_get_core_count();
 
+	if (is_r8a7779())
+		return r8a7779_get_core_count();
+
 	return 1;
 }
 
@@ -35,6 +39,9 @@ static void __init shmobile_smp_prepare_
 {
 	if (is_sh73a0())
 		sh73a0_smp_prepare_cpus();
+
+	if (is_r8a7779())
+		r8a7779_smp_prepare_cpus();
 }
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -43,6 +50,9 @@ void __cpuinit platform_secondary_init(u
 
 	if (is_sh73a0())
 		sh73a0_secondary_init(cpu);
+
+	if (is_r8a7779())
+		r8a7779_secondary_init(cpu);
 }
 
 int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -50,6 +60,9 @@ int __cpuinit boot_secondary(unsigned in
 	if (is_sh73a0())
 		return sh73a0_boot_secondary(cpu);
 
+	if (is_r8a7779())
+		return r8a7779_boot_secondary(cpu);
+
 	return -ENOSYS;
 }
 
--- 0022/arch/arm/mach-shmobile/pm-r8a7779.c
+++ work/arch/arm/mach-shmobile/pm-r8a7779.c	2011-12-22 16:55:47.000000000 +0900
@@ -48,7 +48,9 @@ static void __iomem *r8a7779_sysc_base;
 #define SYSCISR_RETRIES 1000
 #define SYSCISR_DELAY_US 1
 
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) || defined(CONFIG_SMP)
+
+static DEFINE_SPINLOCK(r8a7779_sysc_lock); /* SMP CPUs + I/O devices */
 
 static int r8a7779_sysc_pwr_on_off(struct r8a7779_pm_ch *r8a7779_ch,
 				   int sr_bit, int reg_offs)
@@ -86,9 +88,12 @@ static int r8a7779_sysc_update(struct r8
 	unsigned int isr_mask = 1 << r8a7779_ch->isr_bit;
 	unsigned int chan_mask = 1 << r8a7779_ch->chan_bit;
 	unsigned int status;
+	unsigned long flags;
 	int ret = 0;
 	int k;
 
+	spin_lock_irqsave(&r8a7779_sysc_lock, flags);
+
 	iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
 
 	do {
@@ -112,6 +117,8 @@ static int r8a7779_sysc_update(struct r8
 	iowrite32(isr_mask, r8a7779_sysc_base + SYSCISCR);
 
  out:
+	spin_unlock_irqrestore(&r8a7779_sysc_lock, flags);
+
 	pr_debug("r8a7779 power domain %d: %02x %02x %02x %02x %02x -> %d\n",
 		 r8a7779_ch->isr_bit, ioread32(r8a7779_sysc_base + PWRSR0),
 		 ioread32(r8a7779_sysc_base + PWRSR1),
@@ -121,12 +128,12 @@ static int r8a7779_sysc_update(struct r8
 	return ret;
 }
 
-static int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
+int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch)
 {
 	return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_off);
 }
 
-static int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
+int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch)
 {
 	return r8a7779_sysc_update(r8a7779_ch, r8a7779_sysc_pwr_on);
 }
@@ -142,6 +149,14 @@ static void __init r8a7779_sysc_init(voi
 	iowrite32(0, r8a7779_sysc_base + SYSCIMR);
 }
 
+#else /* CONFIG_PM || CONFIG_SMP */
+
+static inline void r8a7779_sysc_init(void) {}
+
+#endif /* CONFIG_PM || CONFIG_SMP */
+
+#ifdef CONFIG_PM
+
 static int pd_power_down(struct generic_pm_domain *genpd)
 {
 	return r8a7779_sysc_power_down(to_r8a7779_ch(genpd));
@@ -223,13 +238,12 @@ struct r8a7779_pm_domain r8a7779_impx3  	}
 };
 
-#else /* CONFIG_PM */
-
-static inline void r8a7779_sysc_init(void) {}
-
 #endif /* CONFIG_PM */
 
 void __init r8a7779_pm_init(void)
 {
-	r8a7779_sysc_init();
+	static int once;
+
+	if (!once++)
+		r8a7779_sysc_init();
 }
--- /dev/null
+++ work/arch/arm/mach-shmobile/smp-r8a7779.c	2011-12-22 16:49:46.000000000 +0900
@@ -0,0 +1,131 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile - r8a7779 portion
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/common.h>
+#include <mach/r8a7779.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
+
+#define AVECR 0xfe700040
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu1 = {
+	.chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+	.chan_bit = 1, /* ARM1 */
+	.isr_bit = 1, /* ARM1 */
+};
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu2 = {
+	.chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+	.chan_bit = 2, /* ARM2 */
+	.isr_bit = 2, /* ARM2 */
+};
+
+static struct r8a7779_pm_ch r8a7779_ch_cpu3 = {
+	.chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
+	.chan_bit = 3, /* ARM3 */
+	.isr_bit = 3, /* ARM3 */
+};
+
+static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = {
+	[1] = &r8a7779_ch_cpu1,
+	[2] = &r8a7779_ch_cpu2,
+	[3] = &r8a7779_ch_cpu3,
+};
+
+static void __iomem *scu_base_addr(void)
+{
+	return (void __iomem *)0xf0000000;
+}
+
+static DEFINE_SPINLOCK(scu_lock);
+static unsigned long tmp;
+
+static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
+{
+	void __iomem *scu_base = scu_base_addr();
+
+	spin_lock(&scu_lock);
+	tmp = __raw_readl(scu_base + 8);
+	tmp &= ~clr;
+	tmp |= set;
+	spin_unlock(&scu_lock);
+
+	/* disable cache coherency after releasing the lock */
+	__raw_writel(tmp, scu_base + 8);
+}
+
+unsigned int __init r8a7779_get_core_count(void)
+{
+	void __iomem *scu_base = scu_base_addr();
+
+#ifdef CONFIG_HAVE_ARM_TWD
+	/* twd_base needs to be initialized before percpu_timer_setup() */
+	twd_base = (void __iomem *)0xf0000600;
+#endif
+
+	return scu_get_core_count(scu_base);
+}
+
+void __cpuinit r8a7779_secondary_init(unsigned int cpu)
+{
+	gic_secondary_init(0);
+}
+
+int __cpuinit r8a7779_boot_secondary(unsigned int cpu)
+{
+	struct r8a7779_pm_ch *ch = NULL;
+	int ret = -EIO;
+
+	cpu = cpu_logical_map(cpu);
+
+	/* enable cache coherency */
+	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+	if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
+		ch = r8a7779_ch_cpu[cpu];
+
+	if (ch) {
+		r8a7779_sysc_power_down(ch);
+		ret = r8a7779_sysc_power_up(ch);
+	}
+
+	return ret;
+}
+
+void __init r8a7779_smp_prepare_cpus(void)
+{
+	int cpu = cpu_logical_map(0);
+
+	scu_enable(scu_base_addr());
+
+	/* Map the reset vector (in headsmp.S) */
+	__raw_writel(__pa(shmobile_secondary_vector), __io(AVECR));
+
+	/* enable cache coherency on CPU0 */
+	modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+	r8a7779_pm_init();
+}

^ permalink raw reply

* [PATCH] ARM: mach-shmobile: r8a7779 SGX-over-UIO test code
From: Magnus Damm @ 2011-12-22  8:21 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

This prototype code exports the SGX hardware block in r8a7779
to user space via UIO. Clocks are associated with the device
as well as a power domain. By adding a #define DEBUG in the
pm-r8a7779.c file it is possible to watch the power domain
going on and off when starting a user space UIO driver.

Submitted to the mailing list as a test bench.
Not for upstream merge.

Never-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Depends on the r8a7779 base plus the power domain code:
 [PATCH] ARM: mach-shmobile: r8a7779 power domain support

 Should be rebased on top of Morimoto-san's clock patches.

 arch/arm/mach-shmobile/clock-r8a7779.c |    6 +++++
 arch/arm/mach-shmobile/setup-r8a7779.c |   38 ++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

--- 0014/arch/arm/mach-shmobile/clock-r8a7779.c
+++ work/arch/arm/mach-shmobile/clock-r8a7779.c	2011-12-21 15:39:59.000000000 +0900
@@ -57,6 +57,7 @@ static struct clk *main_clks[] = {
 
 enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
 	MSTP016, MSTP015, MSTP014,
+       MSTP105, MSTP319,
 	MSTP_NR };
 
 #define MSTP(_parent, _reg, _bit, _flags) \
@@ -72,6 +73,8 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP016] = MSTP(&clkp, MSTPCR0, 16, 0), /* TMU0 */
 	[MSTP015] = MSTP(&clkp, MSTPCR0, 15, 0), /* TMU1 */
 	[MSTP014] = MSTP(&clkp, MSTPCR0, 14, 0), /* TMU2 */
+	[MSTP105] = MSTP(&clkp, MSTPCR1, 5, 0), /* SGX */
+	[MSTP319] = MSTP(&clkp, MSTPCR3, 19, 0), /* SGX */
 };
 
 static struct clk_lookup lookups[] = {
@@ -84,6 +87,9 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+
+	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP105]), /* SGX */
+	CLKDEV_ICK_ID("scr", "uio_pdrv_genirq.0", &mstp_clks[MSTP319]),
 };
 
 void __init r8a7779_clock_init(void)
--- 0022/arch/arm/mach-shmobile/setup-r8a7779.c
+++ work/arch/arm/mach-shmobile/setup-r8a7779.c	2011-12-21 15:41:31.000000000 +0900
@@ -22,12 +22,14 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/uio_driver.h>
 #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
+#include <linux/pm_clock.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
@@ -203,6 +205,38 @@ static struct platform_device tmu01_devi
 	.num_resources	= ARRAY_SIZE(tmu01_resources),
 };
 
+/* SGX */
+static struct uio_info sgx_platform_data = {
+	.name = "SGX",
+	.version = "0",
+	.irq = UIO_IRQ_NONE,
+};
+
+static struct resource sgx_resources[] = {
+	[0] = {
+		.name	= "SGX",
+		.start	= 0xfff12000,
+		.end	= 0xfff12fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "SGX",
+		.start	= 0xfce00000,
+		.end	= 0xfcffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device sgx_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &sgx_platform_data,
+	},
+	.resource	= sgx_resources,
+	.num_resources	= ARRAY_SIZE(sgx_resources),
+};
+
 static struct platform_device *r8a7779_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -215,6 +249,7 @@ static struct platform_device *r8a7779_e
 };
 
 static struct platform_device *r8a7779_late_devices[] __initdata = {
+	&sgx_device,
 };
 
 void __init r8a7779_add_standard_devices(void)
@@ -230,6 +265,9 @@ void __init r8a7779_add_standard_devices
 			    ARRAY_SIZE(r8a7779_early_devices));
 	platform_add_devices(r8a7779_late_devices,
 			    ARRAY_SIZE(r8a7779_late_devices));
+
+	r8a7779_add_device_to_domain(&r8a7779_sgx, &sgx_device);
+	pm_clk_add(&sgx_device.dev, "scr");
 }
 
 void __init r8a7779_add_early_devices(void)

^ permalink raw reply

* Re: [PATCH (sh-2.6)] sh: do not export syscalls that are actually
From: Carmelo AMOROSO @ 2011-12-22 16:11 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <1322685809-15587-1-git-send-email-carmelo.amoroso@st.com>

On 13/12/2011 3.22, Paul Mundt wrote:
> On Mon, Dec 12, 2011 at 11:58:39AM +0100, Carmelo AMOROSO wrote:
>> On 30/11/2011 21.56, Mike Frysinger wrote:
>>> On Wednesday 30 November 2011 15:43:29 Carmelo AMOROSO wrote:
>>>> Avoid user space to erroneously assume that a syscall is
>>>> implemented by picking __NR_xxx from kernel headers that are
>>>> actually mapped to sys_ni_syscall.
>>>
>>> Acked-by: Mike Frysinger <vapier@gentoo.org> -mike
>>
>> Paul,
>> anu chance to include it ? to avoid any doubts, patch was done against
>> HEAD, the subject sh-2.6 was due to a old git setting.
>>
> It's on my review list, just haven't had a chance to go through it yet.
> 

Thanks. Just to be sure that it wasn't filtered-out due to wrong subject :-)

cheers,
carmelo


^ permalink raw reply

* Re: [PATCH] ARM: mach-shmobile: fix AP4EVB A3SP domain PM
From: Guennadi Liakhovetski @ 2011-12-23 11:06 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <Pine.LNX.4.64.1112131208520.17205@axis700.grange>

On Tue, 13 Dec 2011, Guennadi Liakhovetski wrote:

> On SH7372 it is important to stop MSTP clock of all registered USB host
> devices. Otherwise powering down the A3SP domain will become impossible:
> the domain-specific bit in SPDCR will remain set. Subsequently, any attempt
> to power down any further domains will fail in the same way. To fix this
> problem the USB1 host device has to be added to the A3SP domain on AP4EVB,
> similarly as it is done on mackerel.
> While not that critical, this patch also adds the HDMI device to the A4LC
> domain.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Ok, upon closer inspection it turned out, that this patch is not so 
urgently needed, the reason for my problem was different. Please, drop for 
now.

Thanks
Guennadi

> ---
>  arch/arm/mach-shmobile/board-ap4evb.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
> index 7e90d06..15a210a 100644
> --- a/arch/arm/mach-shmobile/board-ap4evb.c
> +++ b/arch/arm/mach-shmobile/board-ap4evb.c
> @@ -1412,6 +1412,8 @@ static void __init ap4evb_init(void)
>  	sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
>  	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
>  	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
> +	sh7372_add_device_to_domain(&sh7372_a3sp, &usb1_host_device);
> +	sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_device);
>  	sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device);
>  
>  	hdmi_init_pm_clock();
> -- 
> 1.7.2.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sh" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH 00/14] DMA-mapping framework redesign preparation
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz

Hello eveyone,

On Linaro Memory Management meeting in Budapest (May 2011) we have
discussed about the design of DMA mapping framework. We tried to
identify the drawbacks and limitations as well as to provide some a
solution for them. The discussion was mainly about ARM architecture, but
some of the conclusions need to be applied to cross-architecture code.

The first issue we identified is the fact that on some platform (again,
mainly ARM) there are several functions for allocating DMA buffers:
dma_alloc_coherent, dma_alloc_writecombine and dma_alloc_noncoherent
(not functional now). For each of them there is a match dma_free_*
function. This gives us quite a lot of functions in the public API and
complicates things when we need to have several different
implementations for different devices selected in runtime (if IOMMU
controller is available only for a few devices in the system). Also the
drivers which use less common variants are less portable because of the
lacks of dma_alloc_writecombine on other architectures.

The solution we found is to introduce a new public dma mapping functions
with additional attributes argument: dma_alloc_attrs and
dma_free_attrs(). This way all different kinds of architecture specific
buffer mappings can be hidden behind the attributes without the need of
creating several versions of dma_alloc_ function.

dma_alloc_coherent() can be wrapped on top of new dma_alloc_attrs() with
NULL attrs parameter. dma_alloc_writecombine and dma_alloc_noncoherent
can be implemented as a simple wrappers which sets attributes to
DMA_ATTRS_WRITECOMBINE or DMA_ATTRS_NON_CONSISTENT respectively. These
new attributes will be implemented only on the architectures that really
support them, the others will simply ignore them defaulting to the
dma_alloc_coherent equivalent.

The next step in dma mapping framework update is the introduction of
dma_mmap/dma_mmap_attrs() function. There are a number of drivers
(mainly V4L2 and ALSA) that only exports the DMA buffers to user space.
Creating a userspace mapping with correct page attributes is not an easy
task for the driver. Also the DMA-mapping framework is the only place
where the complete information about the allocated pages is available,
especially if the implementation uses IOMMU controller to provide a
contiguous buffer in DMA address space which is scattered in physical
memory space.

Usually these drivers don't touch the buffer data at all, so the mapping
in kernel virtual address space is not needed. We can introduce
DMA_ATTRIB_NO_KERNEL_MAPPING attribute which lets kernel to skip/ignore
creation of kernel virtual mapping. This way we can save previous
vmalloc area and simply some mapping operation on a few architectures.

This patch series is a preparation for the above changes in the public
dma mapping API. The main goal is to modify dma_map_ops structure and
let all users to use for implementation of the new public funtions.

The proof-of-concept patches for ARM architecture have been already
posted a few times and now they are working resonably well. They perform
conversion to dma_map_ops based implementation and add support for
generic IOMMU-based dma mapping implementation. To get them merged we
first need to get acceptance for the changes in the common,
cross-architecture structures. More information about these patches can
be found in the following threads:

http://www.spinics.net/lists/linux-mm/msg19856.html
http://www.spinics.net/lists/linux-mm/msg21241.html
http://lists.linaro.org/pipermail/linaro-mm-sig/2011-September/000571.html
http://lists.linaro.org/pipermail/linaro-mm-sig/2011-September/000577.html
http://www.spinics.net/lists/linux-mm/msg25490.html

The patches are prepared on top of Linux Kernel v3.2-rc6. I would
appreciate any comments and help with getting this patch series into
linux-next tree.

The idea apllied in this patch set have been also presented during the
Kernel Summit 2011 and ELC-E 2011 in Prague, in the presentation 'ARM
DMA-Mapping Framework Redesign and IOMMU integration'.

I'm really sorry if I missed any of the relevant architecture mailing
lists. I've did my best to include everyone. Feel free to forward this
patchset to all interested developers and maintainers. I've already feel
like a nasty spammer.

Best regards
Marek Szyprowski
Samsung Poland R&D Center


Patch summary:

Andrzej Pietrasiewicz (9):
  X86: adapt for dma_map_ops changes
  MIPS: adapt for dma_map_ops changes
  PowerPC: adapt for dma_map_ops changes
  IA64: adapt for dma_map_ops changes
  SPARC: adapt for dma_map_ops changes
  Alpha: adapt for dma_map_ops changes
  SH: adapt for dma_map_ops changes
  Microblaze: adapt for dma_map_ops changes
  Unicore32: adapt for dma_map_ops changes

Marek Szyprowski (5):
  common: dma-mapping: introduce alloc_attrs and free_attrs methods
  common: dma-mapping: remove old alloc_coherent and free_coherent
    methods
  common: dma-mapping: introduce mmap method
  common: DMA-mapping: add WRITE_COMBINE attribute
  common: DMA-mapping: add NON-CONSISTENT attribute

 Documentation/DMA-attributes.txt          |   19 +++++++++++++++++++
 arch/alpha/include/asm/dma-mapping.h      |   18 ++++++++++++------
 arch/alpha/kernel/pci-noop.c              |   10 ++++++----
 arch/alpha/kernel/pci_iommu.c             |   10 ++++++----
 arch/ia64/hp/common/sba_iommu.c           |   11 ++++++-----
 arch/ia64/include/asm/dma-mapping.h       |   18 ++++++++++++------
 arch/ia64/kernel/pci-swiotlb.c            |    9 +++++----
 arch/ia64/sn/pci/pci_dma.c                |    9 +++++----
 arch/microblaze/include/asm/dma-mapping.h |   18 ++++++++++++------
 arch/microblaze/kernel/dma.c              |   10 ++++++----
 arch/mips/include/asm/dma-mapping.h       |   18 ++++++++++++------
 arch/mips/mm/dma-default.c                |    8 ++++----
 arch/powerpc/include/asm/dma-mapping.h    |   24 ++++++++++++++++--------
 arch/powerpc/kernel/dma-iommu.c           |   10 ++++++----
 arch/powerpc/kernel/dma-swiotlb.c         |    4 ++--
 arch/powerpc/kernel/dma.c                 |   10 ++++++----
 arch/powerpc/kernel/ibmebus.c             |   10 ++++++----
 arch/powerpc/platforms/cell/iommu.c       |   16 +++++++++-------
 arch/powerpc/platforms/ps3/system-bus.c   |   13 +++++++------
 arch/sh/include/asm/dma-mapping.h         |   28 ++++++++++++++++++----------
 arch/sh/kernel/dma-nommu.c                |    4 ++--
 arch/sh/mm/consistent.c                   |    6 ++++--
 arch/sparc/include/asm/dma-mapping.h      |   18 ++++++++++++------
 arch/sparc/kernel/iommu.c                 |   10 ++++++----
 arch/sparc/kernel/ioport.c                |   18 ++++++++++--------
 arch/sparc/kernel/pci_sun4v.c             |    9 +++++----
 arch/unicore32/include/asm/dma-mapping.h  |   18 ++++++++++++------
 arch/unicore32/mm/dma-swiotlb.c           |    4 ++--
 arch/x86/include/asm/dma-mapping.h        |   26 ++++++++++++++++----------
 arch/x86/kernel/amd_gart_64.c             |   11 ++++++-----
 arch/x86/kernel/pci-calgary_64.c          |    9 +++++----
 arch/x86/kernel/pci-dma.c                 |    3 ++-
 arch/x86/kernel/pci-nommu.c               |    6 +++---
 arch/x86/kernel/pci-swiotlb.c             |   12 +++++++-----
 arch/x86/xen/pci-swiotlb-xen.c            |    4 ++--
 drivers/iommu/amd_iommu.c                 |   10 ++++++----
 drivers/iommu/intel-iommu.c               |    9 +++++----
 drivers/xen/swiotlb-xen.c                 |    5 +++--
 include/linux/dma-attrs.h                 |    2 ++
 include/linux/dma-mapping.h               |   13 +++++++++----
 include/linux/swiotlb.h                   |    6 ++++--
 include/xen/swiotlb-xen.h                 |    6 ++++--
 lib/swiotlb.c                             |    5 +++--
 43 files changed, 305 insertions(+), 182 deletions(-)

-- 
1.7.1.569.g6f426


^ permalink raw reply

* [PATCH 01/14] common: dma-mapping: introduce alloc_attrs and
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

Introduce new generic alloc and free methods with attributes argument.

Existing alloc_coherent and free_coherent can be implemented on top of the
new calls with NULL attributes argument. Later also dma_alloc_non_coherent
can be implemented using DMA_ATTR_NONCOHERENT attribute as well as
dma_alloc_writecombine with separate DMA_ATTR_WRITECOMBINE attribute.

This way the drivers will get more generic, platform independent way of
allocating dma buffers with specific parameters.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 include/linux/dma-mapping.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index e13117c..8cc7f95 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -13,6 +13,12 @@ struct dma_map_ops {
 				dma_addr_t *dma_handle, gfp_t gfp);
 	void (*free_coherent)(struct device *dev, size_t size,
 			      void *vaddr, dma_addr_t dma_handle);
+	void* (*alloc)(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, gfp_t gfp,
+				struct dma_attrs *attrs);
+	void (*free)(struct device *dev, size_t size,
+			      void *vaddr, dma_addr_t dma_handle,
+			      struct dma_attrs *attrs);
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
-- 
1.7.1.569.g6f426


^ permalink raw reply related

* [PATCH 02/14] X86: adapt for dma_map_ops changes
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>

Adapt core X86 architecture code for dma_map_ops changes: replace
alloc/free_coherent with generic alloc/free methods.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/x86/include/asm/dma-mapping.h |   26 ++++++++++++++++----------
 arch/x86/kernel/amd_gart_64.c      |   11 ++++++-----
 arch/x86/kernel/pci-calgary_64.c   |    9 +++++----
 arch/x86/kernel/pci-dma.c          |    3 ++-
 arch/x86/kernel/pci-nommu.c        |    6 +++---
 arch/x86/kernel/pci-swiotlb.c      |   12 +++++++-----
 arch/x86/xen/pci-swiotlb-xen.c     |    4 ++--
 drivers/iommu/amd_iommu.c          |   10 ++++++----
 drivers/iommu/intel-iommu.c        |    9 +++++----
 drivers/xen/swiotlb-xen.c          |    5 +++--
 include/linux/swiotlb.h            |    6 ++++--
 include/xen/swiotlb-xen.h          |    6 ++++--
 lib/swiotlb.c                      |    5 +++--
 13 files changed, 66 insertions(+), 46 deletions(-)

diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index ed3065f..4b4331d 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -59,7 +59,8 @@ extern int dma_supported(struct device *hwdev, u64 mask);
 extern int dma_set_mask(struct device *dev, u64 mask);
 
 extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_addr, gfp_t flag);
+					dma_addr_t *dma_addr, gfp_t flag,
+					struct dma_attrs *attrs);
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
@@ -111,9 +112,11 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
        return gfp;
 }
 
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
 static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		gfp_t gfp)
+dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *memory;
@@ -129,18 +132,21 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	if (!is_device_dma_capable(dev))
 		return NULL;
 
-	if (!ops->alloc_coherent)
+	if (!ops->alloc)
 		return NULL;
 
-	memory = ops->alloc_coherent(dev, size, dma_handle,
-				     dma_alloc_coherent_gfp_flags(dev, gfp));
+	memory = ops->alloc(dev, size, dma_handle,
+			    dma_alloc_coherent_gfp_flags(dev, gfp), attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 
 	return memory;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t bus)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t bus,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -150,8 +156,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 		return;
 
 	debug_dma_free_coherent(dev, size, vaddr, bus);
-	if (ops->free_coherent)
-		ops->free_coherent(dev, size, vaddr, bus);
+	if (ops->free)
+		ops->free(dev, size, vaddr, bus, attrs);
 }
 
 #endif
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index b1e7c7f..e663112 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -477,7 +477,7 @@ error:
 /* allocate and map a coherent mapping */
 static void *
 gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
-		    gfp_t flag)
+		    gfp_t flag, struct dma_attrs *attrs)
 {
 	dma_addr_t paddr;
 	unsigned long align_mask;
@@ -500,7 +500,8 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 		}
 		__free_pages(page, get_order(size));
 	} else
-		return dma_generic_alloc_coherent(dev, size, dma_addr, flag);
+		return dma_generic_alloc_coherent(dev, size, dma_addr, flag,
+						  attrs);
 
 	return NULL;
 }
@@ -508,7 +509,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 /* free a coherent mapping */
 static void
 gart_free_coherent(struct device *dev, size_t size, void *vaddr,
-		   dma_addr_t dma_addr)
+		   dma_addr_t dma_addr, struct dma_attrs *attrs)
 {
 	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
 	free_pages((unsigned long)vaddr, get_order(size));
@@ -700,8 +701,8 @@ static struct dma_map_ops gart_dma_ops = {
 	.unmap_sg			= gart_unmap_sg,
 	.map_page			= gart_map_page,
 	.unmap_page			= gart_unmap_page,
-	.alloc_coherent			= gart_alloc_coherent,
-	.free_coherent			= gart_free_coherent,
+	.alloc				= gart_alloc_coherent,
+	.free				= gart_free_coherent,
 	.mapping_error			= gart_mapping_error,
 };
 
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 726494b..07b587c 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -431,7 +431,7 @@ static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr,
 }
 
 static void* calgary_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t *dma_handle, gfp_t flag)
+	dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
 {
 	void *ret = NULL;
 	dma_addr_t mapping;
@@ -464,7 +464,8 @@ error:
 }
 
 static void calgary_free_coherent(struct device *dev, size_t size,
-				  void *vaddr, dma_addr_t dma_handle)
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	unsigned int npages;
 	struct iommu_table *tbl = find_iommu_table(dev);
@@ -477,8 +478,8 @@ static void calgary_free_coherent(struct device *dev, size_t size,
 }
 
 static struct dma_map_ops calgary_dma_ops = {
-	.alloc_coherent = calgary_alloc_coherent,
-	.free_coherent = calgary_free_coherent,
+	.alloc = calgary_alloc_coherent,
+	.free = calgary_free_coherent,
 	.map_sg = calgary_map_sg,
 	.unmap_sg = calgary_unmap_sg,
 	.map_page = calgary_map_page,
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 80dc793..b8b9e47 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -87,7 +87,8 @@ void __init pci_iommu_alloc(void)
 	}
 }
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-				 dma_addr_t *dma_addr, gfp_t flag)
+				 dma_addr_t *dma_addr, gfp_t flag,
+				 struct dma_attrs *attrs)
 {
 	unsigned long dma_mask;
 	struct page *page;
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 3af4af8..f960506 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -75,7 +75,7 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 }
 
 static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
-				dma_addr_t dma_addr)
+				dma_addr_t dma_addr, struct dma_attrs *attrs)
 {
 	free_pages((unsigned long)vaddr, get_order(size));
 }
@@ -96,8 +96,8 @@ static void nommu_sync_sg_for_device(struct device *dev,
 }
 
 struct dma_map_ops nommu_dma_ops = {
-	.alloc_coherent		= dma_generic_alloc_coherent,
-	.free_coherent		= nommu_free_coherent,
+	.alloc			= dma_generic_alloc_coherent,
+	.free			= nommu_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
 	.sync_single_for_device = nommu_sync_single_for_device,
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 8f972cb..fa462a3 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -15,21 +15,23 @@
 int swiotlb __read_mostly;
 
 static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-					dma_addr_t *dma_handle, gfp_t flags)
+					dma_addr_t *dma_handle, gfp_t flags,
+					struct dma_attrs *attrs)
 {
 	void *vaddr;
 
-	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags);
+	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags,
+					   attrs);
 	if (vaddr)
 		return vaddr;
 
-	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
+	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags, attrs);
 }
 
 static struct dma_map_ops swiotlb_dma_ops = {
 	.mapping_error = swiotlb_dma_mapping_error,
-	.alloc_coherent = x86_swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
+	.alloc = x86_swiotlb_alloc_coherent,
+	.free = swiotlb_free_coherent,
 	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
 	.sync_single_for_device = swiotlb_sync_single_for_device,
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index b480d42..967633a 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -12,8 +12,8 @@ int xen_swiotlb __read_mostly;
 
 static struct dma_map_ops xen_swiotlb_dma_ops = {
 	.mapping_error = xen_swiotlb_dma_mapping_error,
-	.alloc_coherent = xen_swiotlb_alloc_coherent,
-	.free_coherent = xen_swiotlb_free_coherent,
+	.alloc = xen_swiotlb_alloc_coherent,
+	.free = xen_swiotlb_free_coherent,
 	.sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
 	.sync_single_for_device = xen_swiotlb_sync_single_for_device,
 	.sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 4ee277a..fc36f1e 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2335,7 +2335,8 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
  * The exported alloc_coherent function for dma_ops.
  */
 static void *alloc_coherent(struct device *dev, size_t size,
-			    dma_addr_t *dma_addr, gfp_t flag)
+			    dma_addr_t *dma_addr, gfp_t flag,
+			    struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	void *virt_addr;
@@ -2393,7 +2394,8 @@ out_free:
  * The exported free_coherent function for dma_ops.
  */
 static void free_coherent(struct device *dev, size_t size,
-			  void *virt_addr, dma_addr_t dma_addr)
+			  void *virt_addr, dma_addr_t dma_addr,
+			  struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct protection_domain *domain;
@@ -2463,8 +2465,8 @@ static void prealloc_protection_domains(void)
 }
 
 static struct dma_map_ops amd_iommu_dma_ops = {
-	.alloc_coherent = alloc_coherent,
-	.free_coherent = free_coherent,
+	.alloc = alloc_coherent,
+	.free = free_coherent,
 	.map_page = map_page,
 	.unmap_page = unmap_page,
 	.map_sg = map_sg,
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index bdc447f..22982184 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2925,7 +2925,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
 }
 
 static void *intel_alloc_coherent(struct device *hwdev, size_t size,
-				  dma_addr_t *dma_handle, gfp_t flags)
+				  dma_addr_t *dma_handle, gfp_t flags,
+				  struct dma_attrs *attrs)
 {
 	void *vaddr;
 	int order;
@@ -2957,7 +2958,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
 }
 
 static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-				dma_addr_t dma_handle)
+				dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	int order;
 
@@ -3102,8 +3103,8 @@ static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
 }
 
 struct dma_map_ops intel_dma_ops = {
-	.alloc_coherent = intel_alloc_coherent,
-	.free_coherent = intel_free_coherent,
+	.alloc = intel_alloc_coherent,
+	.free = intel_free_coherent,
 	.map_sg = intel_map_sg,
 	.unmap_sg = intel_unmap_sg,
 	.map_page = intel_map_page,
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 284798a..6c67ed4 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -204,7 +204,8 @@ error:
 
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flags)
+			   dma_addr_t *dma_handle, gfp_t flags,
+			   struct dma_attrs *attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -253,7 +254,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr)
+			  dma_addr_t dev_addr, struct dma_attrs *attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 445702c..769f8bc 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -50,11 +50,13 @@ extern void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size,
 
 extern void
 *swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			dma_addr_t *dma_handle, gfp_t flags);
+			dma_addr_t *dma_handle, gfp_t flags,
+			struct dma_attrs *attrs);
 
 extern void
 swiotlb_free_coherent(struct device *hwdev, size_t size,
-		      void *vaddr, dma_addr_t dma_handle);
+		      void *vaddr, dma_addr_t dma_handle,
+		      struct dma_attrs *attrs);
 
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 2ea2fdc..4f4d449 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -7,11 +7,13 @@ extern void xen_swiotlb_init(int verbose);
 
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t flags);
+			    dma_addr_t *dma_handle, gfp_t flags,
+			    struct dma_attrs *attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
-			  void *vaddr, dma_addr_t dma_handle);
+			  void *vaddr, dma_addr_t dma_handle,
+			  struct dma_attrs *attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 99093b3..10a4f68 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -565,7 +565,8 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_sync_single);
 
 void *
 swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-		       dma_addr_t *dma_handle, gfp_t flags)
+		       dma_addr_t *dma_handle, gfp_t flags,
+		       struct dma_attrs *attrs)
 {
 	dma_addr_t dev_addr;
 	void *ret;
@@ -614,7 +615,7 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent);
 
 void
 swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-		      dma_addr_t dev_addr)
+		      dma_addr_t dev_addr, struct dma_attrs *attrs)
 {
 	phys_addr_t paddr = dma_to_phys(hwdev, dev_addr);
 
-- 
1.7.1.569.g6f426


^ permalink raw reply related

* [PATCH 03/14] MIPS: adapt for dma_map_ops changes
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>

Adapt core MIPS architecture code for dma_map_ops changes: replace
alloc/free_coherent with generic alloc/free methods.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/mips/include/asm/dma-mapping.h |   18 ++++++++++++------
 arch/mips/mm/dma-default.c          |    8 ++++----
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index 7aa37dd..cbd41f5 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask)
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
 	void *ret;
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+	ret = ops->alloc(dev, size, dma_handle, gfp, NULL);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
 
 	return ret;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ops->free_coherent(dev, size, vaddr, dma_handle);
+	ops->free(dev, size, vaddr, dma_handle, NULL);
 
 	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
 }
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4608491..3fab204 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -98,7 +98,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
 EXPORT_SYMBOL(dma_alloc_noncoherent);
 
 static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t * dma_handle, gfp_t gfp)
+	dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -132,7 +132,7 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 EXPORT_SYMBOL(dma_free_noncoherent);
 
 static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-	dma_addr_t dma_handle)
+	dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	unsigned long addr = (unsigned long) vaddr;
 	int order = get_order(size);
@@ -323,8 +323,8 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 EXPORT_SYMBOL(dma_cache_sync);
 
 static struct dma_map_ops mips_default_dma_map_ops = {
-	.alloc_coherent = mips_dma_alloc_coherent,
-	.free_coherent = mips_dma_free_coherent,
+	.alloc = mips_dma_alloc_coherent,
+	.free = mips_dma_free_coherent,
 	.map_page = mips_dma_map_page,
 	.unmap_page = mips_dma_unmap_page,
 	.map_sg = mips_dma_map_sg,
-- 
1.7.1.569.g6f426


^ permalink raw reply related

* [PATCH 04/14] PowerPC: adapt for dma_map_ops changes
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>

Adapt core PowerPC architecture code for dma_map_ops changes: replace
alloc/free_coherent with generic alloc/free methods.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/powerpc/include/asm/dma-mapping.h  |   24 ++++++++++++++++--------
 arch/powerpc/kernel/dma-iommu.c         |   10 ++++++----
 arch/powerpc/kernel/dma-swiotlb.c       |    4 ++--
 arch/powerpc/kernel/dma.c               |   10 ++++++----
 arch/powerpc/kernel/ibmebus.c           |   10 ++++++----
 arch/powerpc/platforms/cell/iommu.c     |   16 +++++++++-------
 arch/powerpc/platforms/ps3/system-bus.c |   13 +++++++------
 7 files changed, 52 insertions(+), 35 deletions(-)

diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index dd70fac..62678e3 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -22,9 +22,11 @@
 
 /* Some dma direct funcs must be visible for use in other dma_ops */
 extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag);
+				       dma_addr_t *dma_handle, gfp_t flag,
+				       struct dma_attrs *attrs);
 extern void dma_direct_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle);
+				     void *vaddr, dma_addr_t dma_handle,
+				     struct dma_attrs *attrs);
 
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -130,23 +132,29 @@ static inline int dma_supported(struct device *dev, u64 mask)
 
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 	void *cpu_addr;
 
 	BUG_ON(!dma_ops);
 
-	cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+	cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
 
 	return cpu_addr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
@@ -154,7 +162,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
 
-	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 3f6464b..bcfdcd2 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -17,7 +17,8 @@
  * to the dma address (mapping) of the first page.
  */
 static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				      dma_addr_t *dma_handle, gfp_t flag,
+				      struct dma_attrs *attrs)
 {
 	return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
 				    dma_handle, dev->coherent_dma_mask, flag,
@@ -25,7 +26,8 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void dma_iommu_free_coherent(struct device *dev, size_t size,
-				    void *vaddr, dma_addr_t dma_handle)
+				    void *vaddr, dma_addr_t dma_handle,
+				    struct dma_attrs *attrs)
 {
 	iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
 }
@@ -105,8 +107,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev)
 }
 
 struct dma_map_ops dma_iommu_ops = {
-	.alloc_coherent		= dma_iommu_alloc_coherent,
-	.free_coherent		= dma_iommu_free_coherent,
+	.alloc			= dma_iommu_alloc_coherent,
+	.free			= dma_iommu_free_coherent,
 	.map_sg			= dma_iommu_map_sg,
 	.unmap_sg		= dma_iommu_unmap_sg,
 	.dma_supported		= dma_iommu_dma_supported,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 1ebc918..4ab88da 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -47,8 +47,8 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)
  * for everything else.
  */
 struct dma_map_ops swiotlb_dma_ops = {
-	.alloc_coherent = dma_direct_alloc_coherent,
-	.free_coherent = dma_direct_free_coherent,
+	.alloc = dma_direct_alloc_coherent,
+	.free = dma_direct_free_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
 	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.dma_supported = swiotlb_dma_supported,
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 7d0233c..b1ec983 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -26,7 +26,8 @@
 
 
 void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t flag)
+				dma_addr_t *dma_handle, gfp_t flag,
+				struct dma_attrs *attrs)
 {
 	void *ret;
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -54,7 +55,8 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
 }
 
 void dma_direct_free_coherent(struct device *dev, size_t size,
-			      void *vaddr, dma_addr_t dma_handle)
+			      void *vaddr, dma_addr_t dma_handle,
+			      struct dma_attrs *attrs)
 {
 #ifdef CONFIG_NOT_COHERENT_CACHE
 	__dma_free_coherent(size, vaddr);
@@ -150,8 +152,8 @@ static inline void dma_direct_sync_single(struct device *dev,
 #endif
 
 struct dma_map_ops dma_direct_ops = {
-	.alloc_coherent			= dma_direct_alloc_coherent,
-	.free_coherent			= dma_direct_free_coherent,
+	.alloc				= dma_direct_alloc_coherent,
+	.free				= dma_direct_free_coherent,
 	.map_sg				= dma_direct_map_sg,
 	.unmap_sg			= dma_direct_unmap_sg,
 	.dma_supported			= dma_direct_dma_supported,
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index d39ae60..716d918 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -65,7 +65,8 @@ static struct of_device_id __initdata ibmebus_matches[] = {
 static void *ibmebus_alloc_coherent(struct device *dev,
 				    size_t size,
 				    dma_addr_t *dma_handle,
-				    gfp_t flag)
+				    gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	void *mem;
 
@@ -77,7 +78,8 @@ static void *ibmebus_alloc_coherent(struct device *dev,
 
 static void ibmebus_free_coherent(struct device *dev,
 				  size_t size, void *vaddr,
-				  dma_addr_t dma_handle)
+				  dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	kfree(vaddr);
 }
@@ -136,8 +138,8 @@ static u64 ibmebus_dma_get_required_mask(struct device *dev)
 }
 
 static struct dma_map_ops ibmebus_dma_ops = {
-	.alloc_coherent     = ibmebus_alloc_coherent,
-	.free_coherent      = ibmebus_free_coherent,
+	.alloc              = ibmebus_alloc_coherent,
+	.free               = ibmebus_free_coherent,
 	.map_sg             = ibmebus_map_sg,
 	.unmap_sg           = ibmebus_unmap_sg,
 	.dma_supported      = ibmebus_dma_supported,
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 592c3d5..471c955 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -564,7 +564,8 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
 /* A coherent allocation implies strong ordering */
 
 static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				      dma_addr_t *dma_handle, gfp_t flag,
+				      struct dma_attrs *attrs)
 {
 	if (iommu_fixed_is_weak)
 		return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
@@ -572,18 +573,19 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
 					    device_to_mask(dev), flag,
 					    dev_to_node(dev));
 	else
-		return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
-						     flag);
+		return dma_direct_ops.alloc(dev, size, dma_handle, flag,
+					    attrs);
 }
 
 static void dma_fixed_free_coherent(struct device *dev, size_t size,
-				    void *vaddr, dma_addr_t dma_handle)
+				    void *vaddr, dma_addr_t dma_handle,
+				    struct dma_attrs *attrs)
 {
 	if (iommu_fixed_is_weak)
 		iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
 				    dma_handle);
 	else
-		dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle);
+		dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs);
 }
 
 static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
@@ -642,8 +644,8 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask)
 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
 
 struct dma_map_ops dma_iommu_fixed_ops = {
-	.alloc_coherent = dma_fixed_alloc_coherent,
-	.free_coherent  = dma_fixed_free_coherent,
+	.alloc          = dma_fixed_alloc_coherent,
+	.free           = dma_fixed_free_coherent,
 	.map_sg         = dma_fixed_map_sg,
 	.unmap_sg       = dma_fixed_unmap_sg,
 	.dma_supported  = dma_fixed_dma_supported,
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 880eb9c..5606fe3 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -515,7 +515,8 @@ core_initcall(ps3_system_bus_init);
  * to the dma address (mapping) of the first page.
  */
 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				 dma_addr_t *dma_handle, gfp_t flag,
+				 struct dma_attrs *attrs)
 {
 	int result;
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
@@ -552,7 +553,7 @@ clean_none:
 }
 
 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
-	dma_addr_t dma_handle)
+			      dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 
@@ -701,8 +702,8 @@ static u64 ps3_dma_get_required_mask(struct device *_dev)
 }
 
 static struct dma_map_ops ps3_sb_dma_ops = {
-	.alloc_coherent = ps3_alloc_coherent,
-	.free_coherent = ps3_free_coherent,
+	.alloc = ps3_alloc_coherent,
+	.free = ps3_free_coherent,
 	.map_sg = ps3_sb_map_sg,
 	.unmap_sg = ps3_sb_unmap_sg,
 	.dma_supported = ps3_dma_supported,
@@ -712,8 +713,8 @@ static struct dma_map_ops ps3_sb_dma_ops = {
 };
 
 static struct dma_map_ops ps3_ioc0_dma_ops = {
-	.alloc_coherent = ps3_alloc_coherent,
-	.free_coherent = ps3_free_coherent,
+	.alloc = ps3_alloc_coherent,
+	.free = ps3_free_coherent,
 	.map_sg = ps3_ioc0_map_sg,
 	.unmap_sg = ps3_ioc0_unmap_sg,
 	.dma_supported = ps3_dma_supported,
-- 
1.7.1.569.g6f426


^ permalink raw reply related

* [PATCH 05/14] IA64: adapt for dma_map_ops changes
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>

Adapt core IA64 architecture code for dma_map_ops changes: replace
alloc/free_coherent with generic alloc/free methods.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/ia64/hp/common/sba_iommu.c     |   11 ++++++-----
 arch/ia64/include/asm/dma-mapping.h |   18 ++++++++++++------
 arch/ia64/kernel/pci-swiotlb.c      |    9 +++++----
 arch/ia64/sn/pci/pci_dma.c          |    9 +++++----
 4 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index f5f4ef1..e5eb9c4 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1130,7 +1130,8 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
  * See Documentation/DMA-API-HOWTO.txt
  */
 static void *
-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
+sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		   gfp_t flags, struct dma_attrs *attrs)
 {
 	struct ioc *ioc;
 	void *addr;
@@ -1192,8 +1193,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp
  *
  * See Documentation/DMA-API-HOWTO.txt
  */
-static void sba_free_coherent (struct device *dev, size_t size, void *vaddr,
-			       dma_addr_t dma_handle)
+static void sba_free_coherent(struct device *dev, size_t size, void *vaddr,
+			      dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL);
 	free_pages((unsigned long) vaddr, get_order(size));
@@ -2213,8 +2214,8 @@ sba_page_override(char *str)
 __setup("sbapagesize=",sba_page_override);
 
 struct dma_map_ops sba_dma_ops = {
-	.alloc_coherent		= sba_alloc_coherent,
-	.free_coherent		= sba_free_coherent,
+	.alloc			= sba_alloc_coherent,
+	.free			= sba_free_coherent,
 	.map_page		= sba_map_page,
 	.unmap_page		= sba_unmap_page,
 	.map_sg			= sba_map_sg_attrs,
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 4336d08..4f5e814 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -23,23 +23,29 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
 extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
 				enum dma_data_direction);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *daddr, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *daddr, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = platform_dma_get_ops(dev);
 	void *caddr;
 
-	caddr = ops->alloc_coherent(dev, size, daddr, gfp);
+	caddr = ops->alloc(dev, size, daddr, gfp, attrs);
 	debug_dma_alloc_coherent(dev, size, *daddr, caddr);
 	return caddr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *caddr, dma_addr_t daddr)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *caddr, dma_addr_t daddr,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = platform_dma_get_ops(dev);
 	debug_dma_free_coherent(dev, size, caddr, daddr);
-	ops->free_coherent(dev, size, caddr, daddr);
+	ops->free(dev, size, caddr, daddr, attrs);
 }
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index d9485d9..cc034c2 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -15,16 +15,17 @@ int swiotlb __read_mostly;
 EXPORT_SYMBOL(swiotlb);
 
 static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
-					 dma_addr_t *dma_handle, gfp_t gfp)
+					 dma_addr_t *dma_handle, gfp_t gfp,
+					 struct dma_attrs *attrs)
 {
 	if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
 		gfp |= GFP_DMA;
-	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs);
 }
 
 struct dma_map_ops swiotlb_dma_ops = {
-	.alloc_coherent = ia64_swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
+	.alloc = ia64_swiotlb_alloc_coherent,
+	.free = swiotlb_free_coherent,
 	.map_page = swiotlb_map_page,
 	.unmap_page = swiotlb_unmap_page,
 	.map_sg = swiotlb_map_sg_attrs,
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index a9d310d..3290d6e 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -76,7 +76,8 @@ EXPORT_SYMBOL(sn_dma_set_mask);
  * more information.
  */
 static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t * dma_handle, gfp_t flags)
+				   dma_addr_t * dma_handle, gfp_t flags,
+				   struct dma_attrs *attrs)
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
@@ -137,7 +138,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
  * any associated IOMMU mappings.
  */
 static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-				 dma_addr_t dma_handle)
+				 dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -466,8 +467,8 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 }
 
 static struct dma_map_ops sn_dma_ops = {
-	.alloc_coherent		= sn_dma_alloc_coherent,
-	.free_coherent		= sn_dma_free_coherent,
+	.alloc			= sn_dma_alloc_coherent,
+	.free			= sn_dma_free_coherent,
 	.map_page		= sn_dma_map_page,
 	.unmap_page		= sn_dma_unmap_page,
 	.map_sg			= sn_dma_map_sg,
-- 
1.7.1.569.g6f426


^ permalink raw reply related

* [PATCH 06/14] SPARC: adapt for dma_map_ops changes
From: Marek Szyprowski @ 2011-12-23 12:27 UTC (permalink / raw)
  To: linux-kernel
  Cc: Benjamin Herrenschmidt, Thomas Gleixner, Andrew Morton,
	Arnd Bergmann, Stephen Rothwell, microblaze-uclinux, linux-arch,
	x86, linux-sh, linux-alpha, sparclinux, linux-ia64, linuxppc-dev,
	linux-mips, discuss, linux-arm-kernel, linux-mm, linaro-mm-sig,
	Jonathan Corbet, Marek Szyprowski, Kyungmin Park,
	Andrzej Pietrasiewicz
In-Reply-To: <1324643253-3024-1-git-send-email-m.szyprowski@samsung.com>

From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>

Adapt core SPARC architecture code for dma_map_ops changes: replace
alloc/free_coherent with generic alloc/free methods.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/sparc/include/asm/dma-mapping.h |   18 ++++++++++++------
 arch/sparc/kernel/iommu.c            |   10 ++++++----
 arch/sparc/kernel/ioport.c           |   18 ++++++++++--------
 arch/sparc/kernel/pci_sun4v.c        |    9 +++++----
 4 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 8c0e4f7..48a7c65 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -26,24 +26,30 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 
 #include <asm-generic/dma-mapping-common.h>
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
 
-	cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag);
+	cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
 	return cpu_addr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
-	ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 4643d68..070ed14 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -280,7 +280,8 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx)
 }
 
 static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t *dma_addrp, gfp_t gfp)
+				   dma_addr_t *dma_addrp, gfp_t gfp,
+				   struct dma_attrs *attrs)
 {
 	unsigned long flags, order, first_page;
 	struct iommu *iommu;
@@ -330,7 +331,8 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void dma_4u_free_coherent(struct device *dev, size_t size,
-				 void *cpu, dma_addr_t dvma)
+				 void *cpu, dma_addr_t dvma,
+				 struct dma_attrs *attrs)
 {
 	struct iommu *iommu;
 	unsigned long flags, order, npages;
@@ -825,8 +827,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
 }
 
 static struct dma_map_ops sun4u_dma_ops = {
-	.alloc_coherent		= dma_4u_alloc_coherent,
-	.free_coherent		= dma_4u_free_coherent,
+	.alloc			= dma_4u_alloc_coherent,
+	.free			= dma_4u_free_coherent,
 	.map_page		= dma_4u_map_page,
 	.unmap_page		= dma_4u_unmap_page,
 	.map_sg			= dma_4u_map_sg,
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index d0479e2..21bd739 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -261,7 +261,8 @@ EXPORT_SYMBOL(sbus_set_sbus64);
  * CPU may access them without any explicit flushing.
  */
 static void *sbus_alloc_coherent(struct device *dev, size_t len,
-				 dma_addr_t *dma_addrp, gfp_t gfp)
+				 dma_addr_t *dma_addrp, gfp_t gfp,
+				 struct dma_attrs *attrs)
 {
 	struct platform_device *op = to_platform_device(dev);
 	unsigned long len_total = PAGE_ALIGN(len);
@@ -315,7 +316,7 @@ err_nopages:
 }
 
 static void sbus_free_coherent(struct device *dev, size_t n, void *p,
-			       dma_addr_t ba)
+			       dma_addr_t ba, struct dma_attrs *attrs)
 {
 	struct resource *res;
 	struct page *pgv;
@@ -407,8 +408,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 }
 
 struct dma_map_ops sbus_dma_ops = {
-	.alloc_coherent		= sbus_alloc_coherent,
-	.free_coherent		= sbus_free_coherent,
+	.alloc			= sbus_alloc_coherent,
+	.free			= sbus_free_coherent,
 	.map_page		= sbus_map_page,
 	.unmap_page		= sbus_unmap_page,
 	.map_sg			= sbus_map_sg,
@@ -436,7 +437,8 @@ arch_initcall(sparc_register_ioport);
  * hwdev should be valid struct pci_dev pointer for PCI devices.
  */
 static void *pci32_alloc_coherent(struct device *dev, size_t len,
-				  dma_addr_t *pba, gfp_t gfp)
+				  dma_addr_t *pba, gfp_t gfp,
+				  struct dma_attrs *attrs)
 {
 	unsigned long len_total = PAGE_ALIGN(len);
 	void *va;
@@ -489,7 +491,7 @@ err_nopages:
  * past this call are illegal.
  */
 static void pci32_free_coherent(struct device *dev, size_t n, void *p,
-				dma_addr_t ba)
+				dma_addr_t ba, struct dma_attrs *attrs)
 {
 	struct resource *res;
 
@@ -645,8 +647,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *
 }
 
 struct dma_map_ops pci32_dma_ops = {
-	.alloc_coherent		= pci32_alloc_coherent,
-	.free_coherent		= pci32_free_coherent,
+	.alloc			= pci32_alloc_coherent,
+	.free			= pci32_free_coherent,
 	.map_page		= pci32_map_page,
 	.unmap_page		= pci32_unmap_page,
 	.map_sg			= pci32_map_sg,
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index b272cda..a8756e3 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -128,7 +128,8 @@ static inline long iommu_batch_end(void)
 }
 
 static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t *dma_addrp, gfp_t gfp)
+				   dma_addr_t *dma_addrp, gfp_t gfp,
+				   struct dma_attrs *attrs)
 {
 	unsigned long flags, order, first_page, npages, n;
 	struct iommu *iommu;
@@ -198,7 +199,7 @@ range_alloc_fail:
 }
 
 static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
-				 dma_addr_t dvma)
+				 dma_addr_t dvma, struct dma_attrs *attrs)
 {
 	struct pci_pbm_info *pbm;
 	struct iommu *iommu;
@@ -527,8 +528,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
 }
 
 static struct dma_map_ops sun4v_dma_ops = {
-	.alloc_coherent			= dma_4v_alloc_coherent,
-	.free_coherent			= dma_4v_free_coherent,
+	.alloc				= dma_4v_alloc_coherent,
+	.free				= dma_4v_free_coherent,
 	.map_page			= dma_4v_map_page,
 	.unmap_page			= dma_4v_unmap_page,
 	.map_sg				= dma_4v_map_sg,
-- 
1.7.1.569.g6f426


^ permalink raw reply related


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