<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Serverphorums.com</title>
        <description>Your source for root discussions!</description>
        <link>http://www.serverphorums.com/index.php</link>
        <lastBuildDate>Tue, 18 Jun 2013 09:24:27 +0200</lastBuildDate>
        <generator>Phorum 5.2.18</generator>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727440,727440#msg-727440</guid>
            <title>[PATCH/RFC] clockevents: Ignore C3STOP when CPUIdle is disabled (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727440,727440#msg-727440</link>
            <description><![CDATA[ From: Magnus Damm &lt;damm@opensource.se&gt;<br />
<br />
Introduce the function tick_device_may_c3stop() that<br />
ignores the C3STOP flag in case CPUIdle is disabled.<br />
<br />
The C3STOP flag tells the system that a clock event<br />
device may be stopped during deep sleep, but if this<br />
will happen or not depends on things like if CPUIdle<br />
is enabled and if a CPUIdle driver is available.<br />
<br />
This patch assumes that if CPUIdle is disabled then<br />
the sleep mode triggering C3STOP will never be entered.<br />
So by ignoring C3STOP when CPUIdle is disabled then it<br />
becomes possible to use high resolution timers with only<br />
per-cpu local timers - regardless if they have the<br />
C3STOP flag set or not.<br />
<br />
Observed on the r8a73a4 SoC that at this point only uses<br />
ARM architected timers for clock event and clock sources.<br />
<br />
Without this patch high resolution timers are run time<br />
disabled on the r8a73a4 SoC - this regardless of CPUIdle<br />
is disabled or not.<br />
<br />
The less short term fix is to add support for more timers<br />
on the r8a73a4 SoC, but until CPUIdle support is enabled<br />
it must be possible to use high resoultion timers without<br />
additional timers.<br />
<br />
I'd like to hear some feedback and also test this on more<br />
systems before merging the code, see the non-SOB below.<br />
<br />
Not-Yet-Signed-off-by: Magnus Damm &lt;damm@opensource.se&gt;<br />
---<br />
<br />
 An earlier ARM arch timer specific version of this patch was<br />
 posted yesterday as:<br />
 &quot;[PATCH/RFC] arm: arch_timer: Do not set C3STOP in case CPU_IDLE=n&quot;<br />
<br />
 Many thanks to Mark Rutland for his kind feedback.<br />
<br />
 kernel/time/tick-broadcast.c |    8 ++++----<br />
 kernel/time/tick-common.c    |    2 +-<br />
 kernel/time/tick-internal.h  |   11 +++++++++++<br />
 3 files changed, 16 insertions(+), 5 deletions(-)<br />
<br />
--- 0001/kernel/time/tick-broadcast.c<br />
+++ work/kernel/time/tick-broadcast.c	2013-06-18 15:36:21.000000000 +0900<br />
@@ -71,7 +71,7 @@ int tick_check_broadcast_device(struct c<br />
 	if ((dev-&gt;features &amp; CLOCK_EVT_FEAT_DUMMY) ||<br />
 	    (tick_broadcast_device.evtdev &amp;&amp;<br />
 	     tick_broadcast_device.evtdev-&gt;rating &gt;= dev-&gt;rating) ||<br />
-	     (dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP))<br />
+	     tick_device_may_c3stop(dev))<br />
 		return 0;<br />
 <br />
 	clockevents_exchange_device(tick_broadcast_device.evtdev, dev);<br />
@@ -146,7 +146,7 @@ int tick_device_uses_broadcast(struct cl<br />
 		 * feature and the cpu is marked in the broadcast mask<br />
 		 * then clear the broadcast bit.<br />
 		 */<br />
-		if (!(dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP)) {<br />
+		if (!tick_device_may_c3stop(dev)) {<br />
 			int cpu = smp_processor_id();<br />
 			cpumask_clear_cpu(cpu, tick_broadcast_mask);<br />
 			tick_broadcast_clear_oneshot(cpu);<br />
@@ -270,7 +270,7 @@ static void tick_do_broadcast_on_off(uns<br />
 	/*<br />
 	 * Is the device not affected by the powerstate ?<br />
 	 */<br />
-	if (!dev || !(dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP))<br />
+	if (!dev || !tick_device_may_c3stop(dev))<br />
 		goto out;<br />
 <br />
 	if (!tick_device_is_functional(dev))<br />
@@ -568,7 +568,7 @@ void tick_broadcast_oneshot_control(unsi<br />
 	td = &amp;per_cpu(tick_cpu_device, cpu);<br />
 	dev = td-&gt;evtdev;<br />
 <br />
-	if (!(dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP))<br />
+	if (!tick_device_may_c3stop(dev))<br />
 		return;<br />
 <br />
 	bc = tick_broadcast_device.evtdev;<br />
--- 0001/kernel/time/tick-common.c<br />
+++ work/kernel/time/tick-common.c	2013-06-18 15:36:29.000000000 +0900<br />
@@ -52,7 +52,7 @@ int tick_is_oneshot_available(void)<br />
 <br />
 	if (!dev || !(dev-&gt;features &amp; CLOCK_EVT_FEAT_ONESHOT))<br />
 		return 0;<br />
-	if (!(dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP))<br />
+	if (!tick_device_may_c3stop(dev))<br />
 		return 1;<br />
 	return tick_broadcast_oneshot_available();<br />
 }<br />
--- 0001/kernel/time/tick-internal.h<br />
+++ work/kernel/time/tick-internal.h	2013-06-18 15:40:10.000000000 +0900<br />
@@ -141,6 +141,17 @@ static inline int tick_device_is_functio<br />
 	return !(dev-&gt;features &amp; CLOCK_EVT_FEAT_DUMMY);<br />
 }<br />
 <br />
+/*<br />
+ * Check, if the device has C3STOP behavior and CPU Idle is enabled<br />
+ */<br />
+static inline bool tick_device_may_c3stop(struct clock_event_device *dev)<br />
+{<br />
+	/* The C3 sleep mode can only trigger when CPU Idle is enabled,<br />
+	 * so if CPU Idle is disabled then the C3STOP flag can be ignored */<br />
+	return (IS_ENABLED(CONFIG_CPU_IDLE) &amp;&amp;<br />
+		(dev-&gt;features &amp; CLOCK_EVT_FEAT_C3STOP));<br />
+}<br />
+<br />
 #endif<br />
 <br />
 extern void do_timer(unsigned long ticks);<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Magnus Damm</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727439,727439#msg-727439</guid>
            <title>[PATCH] USB: initialize or shutdown PHY when add or remove host controller (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727439,727439#msg-727439</link>
            <description><![CDATA[ Some controller need software to initialize PHY before add<br />
host controller, and shut down PHY after remove host controller.<br />
Add the generic code for these controllers so they do not need<br />
do it in its own host controller driver.<br />
<br />
Signed-off-by: Chao Xie &lt;chao.xie@marvell.com&gt;<br />
---<br />
 drivers/usb/core/hcd.c |   19 ++++++++++++++++++-<br />
 1 files changed, 18 insertions(+), 1 deletions(-)<br />
<br />
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c<br />
index d53547d..b26196b 100644<br />
--- a/drivers/usb/core/hcd.c<br />
+++ b/drivers/usb/core/hcd.c<br />
@@ -43,6 +43,7 @@<br />
 <br />
 #include &lt;linux/usb.h&gt;<br />
 #include &lt;linux/usb/hcd.h&gt;<br />
+#include &lt;linux/usb/phy.h&gt;<br />
 <br />
 #include &quot;usb.h&quot;<br />
 <br />
@@ -2531,12 +2532,22 @@ int usb_add_hcd(struct usb_hcd *hcd,<br />
 	 */<br />
 	set_bit(HCD_FLAG_RH_RUNNING, &amp;hcd-&gt;flags);<br />
 <br />
+	/* Initialize the PHY before other hardware operation. */<br />
+	if (hcd-&gt;phy) {<br />
+		retval = usb_phy_init(hcd-&gt;phy);<br />
+		if (retval) {<br />
+			dev_err(hcd-&gt;self.controller,<br />
+				&quot;can't initialize phy\n&quot;);<br />
+			goto err_hcd_driver_setup;<br />
+		}<br />
+	}<br />
+<br />
 	/* &quot;reset&quot; is misnamed; its role is now one-time init. the controller<br />
 	 * should already have been reset (and boot firmware kicked off etc).<br />
 	 */<br />
 	if (hcd-&gt;driver-&gt;reset &amp;&amp; (retval = hcd-&gt;driver-&gt;reset(hcd)) &lt; 0) {<br />
 		dev_err(hcd-&gt;self.controller, &quot;can't setup\n&quot;);<br />
-		goto err_hcd_driver_setup;<br />
+		goto err_hcd_driver_init_phy;<br />
 	}<br />
 	hcd-&gt;rh_pollable = 1;<br />
 <br />
@@ -2608,6 +2619,9 @@ err_hcd_driver_start:<br />
 	if (usb_hcd_is_primary_hcd(hcd) &amp;&amp; hcd-&gt;irq &gt; 0)<br />
 		free_irq(irqnum, hcd);<br />
 err_request_irq:<br />
+err_hcd_driver_init_phy:<br />
+	if (hcd-&gt;phy)<br />
+		usb_phy_shutdown(hcd-&gt;phy);<br />
 err_hcd_driver_setup:<br />
 err_set_rh_speed:<br />
 	usb_put_dev(hcd-&gt;self.root_hub);<br />
@@ -2674,6 +2688,9 @@ void usb_remove_hcd(struct usb_hcd *hcd)<br />
 			free_irq(hcd-&gt;irq, hcd);<br />
 	}<br />
 <br />
+	if (hcd-&gt;phy)<br />
+		usb_phy_shutdown(hcd-&gt;phy);<br />
+<br />
 	usb_put_dev(hcd-&gt;self.root_hub);<br />
 	usb_deregister_bus(&amp;hcd-&gt;self);<br />
 	hcd_buffer_destroy(hcd);<br />
-- <br />
1.7.4.1<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Chao Xie</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727434,727434#msg-727434</guid>
            <title>[patch] fbmem: return -EFAULT on copy_to_user() failure (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727434,727434#msg-727434</link>
            <description><![CDATA[ copy_to_user() returns the number of bytes remaining to be copied.<br />
put_user() returns -EFAULT on error.<br />
<br />
This function ORs a bunch of stuff together and returns jumbled non-zero<br />
values on error.  It should return -EFAULT.<br />
<br />
Signed-off-by: Dan Carpenter &lt;dan.carpenter@oracle.com&gt;<br />
<br />
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c<br />
index 098bfc6..9217be3 100644<br />
--- a/drivers/video/fbmem.c<br />
+++ b/drivers/video/fbmem.c<br />
@@ -1305,7 +1305,9 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,<br />
 	err |= copy_to_user(fix32-&gt;reserved, fix-&gt;reserved,<br />
 			    sizeof(fix-&gt;reserved));<br />
 <br />
-	return err;<br />
+	if (err)<br />
+		return -EFAULT;<br />
+	return 0;<br />
 }<br />
 <br />
 static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Dan Carpenter</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:10:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727433,727433#msg-727433</guid>
            <title>[PATCH V3 0/2] dma: mmp_pdma: Fix phy channels not protected issue (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727433,727433#msg-727433</link>
            <description><![CDATA[ From: Xiang Wang &lt;wangx@marvell.com&gt;<br />
<br />
This patch set deals with the issues that 1) phy channels are not protected<br />
in mmp_pdma. 2) dma request&lt;-&gt;channel mapping is not cleared when a phy chan<br />
is freed.<br />
<br />
Xiang Wang (2):<br />
  dma: mmp_pdma: add protect when alloc/free phy channels<br />
  dma: mmp_pdma: clear DRCMR when free a phy channel<br />
<br />
 drivers/dma/mmp_pdma.c |   48 ++++++++++++++++++++++++++++++++----------------<br />
 1 files changed, 32 insertions(+), 16 deletions(-)<br />
<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Xiang Wang</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:00:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727432,727432#msg-727432</guid>
            <title>[PATCH V3 2/2] dma: mmp_pdma: clear DRCMR when free a phy channel (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727432,727432#msg-727432</link>
            <description><![CDATA[ From: Xiang Wang &lt;wangx@marvell.com&gt;<br />
<br />
In mmp pdma, phy channels are allocated/freed dynamically.<br />
The mapping from DMA request to DMA channel number in DRCMR<br />
should be cleared when a phy channel is freed. Otherwise<br />
conflicts will happen when:<br />
1. A is using channel 2 and free it after finished, but A<br />
still maps to channel 2 in DRCMR of A.<br />
2. Now another one B gets channel 2. So B maps to channel 2<br />
too in DRCMR of B.<br />
In the datasheet, it is described that &quot;Do not map two active<br />
requests to the same channel since it produces unpredictable<br />
results&quot; and we can observe that during test.<br />
<br />
Signed-off-by: Xiang Wang &lt;wangx@marvell.com&gt;<br />
---<br />
 drivers/dma/mmp_pdma.c |    6 ++++++<br />
 1 files changed, 6 insertions(+), 0 deletions(-)<br />
<br />
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c<br />
index 226158d..2844eaf 100644<br />
--- a/drivers/dma/mmp_pdma.c<br />
+++ b/drivers/dma/mmp_pdma.c<br />
@@ -252,10 +252,16 @@ static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)<br />
 {<br />
 	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan-&gt;chan.device);<br />
 	unsigned long flags;<br />
+	u32 reg;<br />
 <br />
 	if (!pchan-&gt;phy)<br />
 		return;<br />
 <br />
+	/* clear the channel mapping in DRCMR */<br />
+	reg = pchan-&gt;phy-&gt;vchan-&gt;drcmr;<br />
+	reg = ((reg &lt; 64) ? 0x0100 : 0x1100) + ((reg &amp; 0x3f) &lt;&lt; 2);<br />
+	writel(0, pchan-&gt;phy-&gt;base + reg);<br />
+<br />
 	spin_lock_irqsave(&amp;pdev-&gt;phy_lock, flags);<br />
 	pchan-&gt;phy-&gt;vchan = NULL;<br />
 	pchan-&gt;phy = NULL;<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Xiang Wang</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:00:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727431,727431#msg-727431</guid>
            <title>[PATCH V3 1/2] dma: mmp_pdma: add protect when alloc/free phy channels (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727431,727431#msg-727431</link>
            <description><![CDATA[ From: Xiang Wang &lt;wangx@marvell.com&gt;<br />
<br />
In mmp pdma, phy channels are allocated/freed dynamically<br />
and frequently. But no proper protection is added.<br />
Conflict will happen when multi-users are requesting phy<br />
channels at the same time. Use spinlock to protect.<br />
<br />
Signed-off-by: Xiang Wang &lt;wangx@marvell.com&gt;<br />
---<br />
 drivers/dma/mmp_pdma.c |   42 ++++++++++++++++++++++++++----------------<br />
 1 files changed, 26 insertions(+), 16 deletions(-)<br />
<br />
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c<br />
index c26699f..226158d 100644<br />
--- a/drivers/dma/mmp_pdma.c<br />
+++ b/drivers/dma/mmp_pdma.c<br />
@@ -121,6 +121,7 @@ struct mmp_pdma_device {<br />
 	struct device			*dev;<br />
 	struct dma_device		device;<br />
 	struct mmp_pdma_phy		*phy;<br />
+	spinlock_t phy_lock; /* protect alloc/free phy channels */<br />
 };<br />
 <br />
 #define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)<br />
@@ -219,6 +220,7 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)<br />
 	int prio, i;<br />
 	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan-&gt;chan.device);<br />
 	struct mmp_pdma_phy *phy;<br />
+	unsigned long flags;<br />
 <br />
 	/*<br />
 	 * dma channel priorities<br />
@@ -227,6 +229,8 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)<br />
 	 * ch 8 - 11, 24 - 27  &lt;--&gt; (2)<br />
 	 * ch 12 - 15, 28 - 31  &lt;--&gt; (3)<br />
 	 */<br />
+<br />
+	spin_lock_irqsave(&amp;pdev-&gt;phy_lock, flags);<br />
 	for (prio = 0; prio &lt;= (((pdev-&gt;dma_channels - 1) &amp; 0xf) &gt;&gt; 2); prio++) {<br />
 		for (i = 0; i &lt; pdev-&gt;dma_channels; i++) {<br />
 			if (prio != ((i &amp; 0xf) &gt;&gt; 2))<br />
@@ -234,14 +238,30 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)<br />
 			phy = &amp;pdev-&gt;phy<i>;<br />
 			if (!phy-&gt;vchan) {<br />
 				phy-&gt;vchan = pchan;<br />
+				spin_unlock_irqrestore(&amp;pdev-&gt;phy_lock, flags);<br />
 				return phy;<br />
 			}<br />
 		}<br />
 	}<br />
 <br />
+	spin_unlock_irqrestore(&amp;pdev-&gt;phy_lock, flags);<br />
 	return NULL;<br />
 }<br />
 <br />
+static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)<br />
+{<br />
+	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan-&gt;chan.device);<br />
+	unsigned long flags;<br />
+<br />
+	if (!pchan-&gt;phy)<br />
+		return;<br />
+<br />
+	spin_lock_irqsave(&amp;pdev-&gt;phy_lock, flags);<br />
+	pchan-&gt;phy-&gt;vchan = NULL;<br />
+	pchan-&gt;phy = NULL;<br />
+	spin_unlock_irqrestore(&amp;pdev-&gt;phy_lock, flags);<br />
+}<br />
+<br />
 /* desc-&gt;tx_list ==&gt; pending list */<br />
 static void append_pending_queue(struct mmp_pdma_chan *chan,<br />
 					struct mmp_pdma_desc_sw *desc)<br />
@@ -277,10 +297,7 @@ static void start_pending_queue(struct mmp_pdma_chan *chan)<br />
 <br />
 	if (list_empty(&amp;chan-&gt;chain_pending)) {<br />
 		/* chance to re-fetch phy channel with higher prio */<br />
-		if (chan-&gt;phy) {<br />
-			chan-&gt;phy-&gt;vchan = NULL;<br />
-			chan-&gt;phy = NULL;<br />
-		}<br />
+		mmp_pdma_free_phy(chan);<br />
 		dev_dbg(chan-&gt;dev, &quot;no pending list\n&quot;);<br />
 		return;<br />
 	}<br />
@@ -377,10 +394,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)<br />
 		dev_err(chan-&gt;dev, &quot;unable to allocate descriptor pool\n&quot;);<br />
 		return -ENOMEM;<br />
 	}<br />
-	if (chan-&gt;phy) {<br />
-		chan-&gt;phy-&gt;vchan = NULL;<br />
-		chan-&gt;phy = NULL;<br />
-	}<br />
+	mmp_pdma_free_phy(chan);<br />
 	chan-&gt;idle = true;<br />
 	chan-&gt;dev_addr = 0;<br />
 	return 1;<br />
@@ -411,10 +425,7 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)<br />
 	chan-&gt;desc_pool = NULL;<br />
 	chan-&gt;idle = true;<br />
 	chan-&gt;dev_addr = 0;<br />
-	if (chan-&gt;phy) {<br />
-		chan-&gt;phy-&gt;vchan = NULL;<br />
-		chan-&gt;phy = NULL;<br />
-	}<br />
+	mmp_pdma_free_phy(chan);<br />
 	return;<br />
 }<br />
 <br />
@@ -581,10 +592,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,<br />
 	switch (cmd) {<br />
 	case DMA_TERMINATE_ALL:<br />
 		disable_chan(chan-&gt;phy);<br />
-		if (chan-&gt;phy) {<br />
-			chan-&gt;phy-&gt;vchan = NULL;<br />
-			chan-&gt;phy = NULL;<br />
-		}<br />
+		mmp_pdma_free_phy(chan);<br />
 		spin_lock_irqsave(&amp;chan-&gt;desc_lock, flags);<br />
 		mmp_pdma_free_desc_list(chan, &amp;chan-&gt;chain_pending);<br />
 		mmp_pdma_free_desc_list(chan, &amp;chan-&gt;chain_running);<br />
@@ -777,6 +785,8 @@ static int mmp_pdma_probe(struct platform_device *op)<br />
 		return -ENOMEM;<br />
 	pdev-&gt;dev = &amp;op-&gt;dev;<br />
 <br />
+	spin_lock_init(&amp;pdev-&gt;phy_lock);<br />
+<br />
 	iores = platform_get_resource(op, IORESOURCE_MEM, 0);<br />
 	if (!iores)<br />
 		return -EINVAL;<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a></i>]]></description>
            <dc:creator>Xiang Wang</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 09:00:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727428,727428#msg-727428</guid>
            <title>Re: + include-linux-smph-on_each_cpu-switch-back-to-a-macro.patch added to -mm tree (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727428,727428#msg-727428</link>
            <description><![CDATA[ Hi Andrew,<br />
<br />
On Mon, 17 Jun 2013 13:31:17 -0700 <a href="mailto:&#97;&#107;&#112;&#109;&#64;&#108;&#105;&#110;&#117;&#120;&#45;&#102;&#111;&#117;&#110;&#100;&#97;&#116;&#105;&#111;&#110;&#46;&#111;&#114;&#103;">&#97;&#107;&#112;&#109;&#64;&#108;&#105;&#110;&#117;&#120;&#45;&#102;&#111;&#117;&#110;&#100;&#97;&#116;&#105;&#111;&#110;&#46;&#111;&#114;&#103;</a> wrote:<br />
&gt;<br />
&gt; From: Andrew Morton &lt;akpm@linux-foundation.org&gt;<br />
&gt; Subject: include/linux/smp.h:on_each_cpu(): switch back to a macro<br />
&gt; <br />
&gt; f21afc25f9ed4 (&quot;smp.h: Use local_irq_{save,restore}() in !SMP version of<br />
&gt; on_each_cpu()&quot;) converted on_each_cpu() to a C function.  This required<br />
&gt; inclusion of irqflags.h, which broke ia64 and mn10300 (at least) due to<br />
&gt; header ordering hell.<br />
&gt; <br />
&gt; Switch on_each_cpu() back to a macro to fix this.<br />
&gt; <br />
&gt; Reported-by: Geert Uytterhoeven &lt;geert@linux-m68k.org&gt;<br />
&gt; Cc: David Daney &lt;david.daney@cavium.com&gt;<br />
&gt; Cc: Ralf Baechle &lt;ralf@linux-mips.org&gt;<br />
&gt; Cc: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;<br />
&gt; Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;<br />
&gt; ---<br />
&gt; <br />
&gt;  include/linux/smp.h |   20 ++++++++------------<br />
&gt;  1 file changed, 8 insertions(+), 12 deletions(-)<br />
&gt; <br />
&gt; diff -puN include/linux/smp.h~include-linux-smph-on_each_cpu-switch-back-to-a-macro include/linux/smp.h<br />
&gt; --- a/include/linux/smp.h~include-linux-smph-on_each_cpu-switch-back-to-a-macro<br />
&gt; +++ a/include/linux/smp.h<br />
&gt; @@ -11,7 +11,6 @@<br />
&gt;  #include &lt;linux/list.h&gt;<br />
&gt;  #include &lt;linux/cpumask.h&gt;<br />
&gt;  #include &lt;linux/init.h&gt;<br />
&gt; -#include &lt;linux/irqflags.h&gt;<br />
&gt;  <br />
&gt;  extern void cpu_idle(void);<br />
&gt;  <br />
&gt; @@ -140,17 +139,14 @@ static inline int up_smp_call_function(s<br />
&gt;  }<br />
&gt;  #define smp_call_function(func, info, wait) \<br />
&gt;  			(up_smp_call_function(func, info))<br />
&gt; -<br />
&gt; -static inline int on_each_cpu(smp_call_func_t func, void *info, int wait)<br />
&gt; -{<br />
&gt; -	unsigned long flags;<br />
&gt; -<br />
&gt; -	local_irq_save(flags);<br />
&gt; -	func(info);<br />
&gt; -	local_irq_restore(flags);<br />
&gt; -	return 0;<br />
&gt; -}<br />
&gt; -<br />
&gt; +#define on_each_cpu(func,info,wait)		\<br />
&gt; +	({					\<br />
&gt; +		unsigned long flags;		\<br />
&gt; +		local_irq_save(flags);		\<br />
&gt; +		func(info);			\<br />
&gt; +		local_irq_restore(flags);	\<br />
&gt; +		0;				\<br />
&gt; +	})<br />
&gt;  /*<br />
&gt;   * Note we still need to test the mask even for UP<br />
&gt;   * because we actually can get an empty mask from<br />
<br />
I added this to the akpm tree in linux-next today - but with<br />
s/flags/__flags/ in appropriate places.<br />
<br />
-- <br />
Cheers,<br />
Stephen Rothwell                    <a href="mailto:&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;">&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;</a>]]></description>
            <dc:creator>Stephen Rothwell</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:03 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727426,727426#msg-727426</guid>
            <title>[PATCH] gpio-langwell: remove Withney point support (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727426,727426#msg-727426</link>
            <description><![CDATA[ It seems there is no user of the wp_gpio driver in the kernel. Let's remove it.<br />
<br />
Signed-off-by: Andy Shevchenko &lt;andriy.shevchenko@linux.intel.com&gt;<br />
Acked-by: Mika Westerberg &lt;mika.westerberg@linux.intel.com&gt;<br />
---<br />
 drivers/gpio/gpio-langwell.c | 69 +-------------------------------------------<br />
 1 file changed, 1 insertion(+), 68 deletions(-)<br />
<br />
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c<br />
index 2db6ef7..bfa1af1 100644<br />
--- a/drivers/gpio/gpio-langwell.c<br />
+++ b/drivers/gpio/gpio-langwell.c<br />
@@ -20,7 +20,6 @@<br />
 /* Supports:<br />
  * Moorestown platform Langwell chip.<br />
  * Medfield platform Penwell chip.<br />
- * Whitney point.<br />
  */<br />
 <br />
 #include &lt;linux/module.h&gt;<br />
@@ -390,75 +389,9 @@ static struct pci_driver lnw_gpio_driver = {<br />
 	},<br />
 };<br />
 <br />
-<br />
-static int wp_gpio_probe(struct platform_device *pdev)<br />
-{<br />
-	struct lnw_gpio *lnw;<br />
-	struct gpio_chip *gc;<br />
-	struct resource *rc;<br />
-	int retval;<br />
-<br />
-	lnw = devm_kzalloc(&amp;pdev-&gt;dev, sizeof(struct lnw_gpio), GFP_KERNEL);<br />
-	if (!lnw) {<br />
-		dev_err(&amp;pdev-&gt;dev, &quot;can't allocate chip data\n&quot;);<br />
-		return -ENOMEM;<br />
-	}<br />
-<br />
-	rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);<br />
-	lnw-&gt;reg_base = devm_ioremap_resource(&amp;pdev-&gt;dev, rc);<br />
-	if (IS_ERR(lnw-&gt;reg_base))<br />
-		return PTR_ERR(lnw-&gt;reg_base);<br />
-<br />
-	spin_lock_init(&amp;lnw-&gt;lock);<br />
-	gc = &amp;lnw-&gt;chip;<br />
-	gc-&gt;label = dev_name(&amp;pdev-&gt;dev);<br />
-	gc-&gt;owner = THIS_MODULE;<br />
-	gc-&gt;direction_input = lnw_gpio_direction_input;<br />
-	gc-&gt;direction_output = lnw_gpio_direction_output;<br />
-	gc-&gt;get = lnw_gpio_get;<br />
-	gc-&gt;set = lnw_gpio_set;<br />
-	gc-&gt;to_irq = NULL;<br />
-	gc-&gt;base = 0;<br />
-	gc-&gt;ngpio = 64;<br />
-	gc-&gt;can_sleep = 0;<br />
-	retval = gpiochip_add(gc);<br />
-	if (retval) {<br />
-		dev_err(&amp;pdev-&gt;dev, &quot;gpiochip_add error %d\n&quot;, retval);<br />
-		return retval;<br />
-	}<br />
-	platform_set_drvdata(pdev, lnw);<br />
-	return 0;<br />
-}<br />
-<br />
-static int wp_gpio_remove(struct platform_device *pdev)<br />
-{<br />
-	struct lnw_gpio *lnw = platform_get_drvdata(pdev);<br />
-	int err;<br />
-	err = gpiochip_remove(&amp;lnw-&gt;chip);<br />
-	if (err)<br />
-		dev_err(&amp;pdev-&gt;dev, &quot;failed to remove gpio_chip.\n&quot;);<br />
-	return 0;<br />
-}<br />
-<br />
-static struct platform_driver wp_gpio_driver = {<br />
-	.probe		= wp_gpio_probe,<br />
-	.remove		= wp_gpio_remove,<br />
-	.driver		= {<br />
-		.name	= &quot;wp_gpio&quot;,<br />
-		.owner	= THIS_MODULE,<br />
-	},<br />
-};<br />
-<br />
 static int __init lnw_gpio_init(void)<br />
 {<br />
-	int ret;<br />
-	ret =  pci_register_driver(&amp;lnw_gpio_driver);<br />
-	if (ret &lt; 0)<br />
-		return ret;<br />
-	ret = platform_driver_register(&amp;wp_gpio_driver);<br />
-	if (ret &lt; 0)<br />
-		pci_unregister_driver(&amp;lnw_gpio_driver);<br />
-	return ret;<br />
+	return pci_register_driver(&amp;lnw_gpio_driver);<br />
 }<br />
 <br />
 device_initcall(lnw_gpio_init);<br />
-- <br />
1.8.3.1<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Andy Shevchenko</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727421,727421#msg-727421</guid>
            <title>[PATCH v11 0/8] ] DMA Engine support for AM33XX (2 replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727421,727421#msg-727421</link>
            <description><![CDATA[ This series is a repost of Matt Porter's EDMA patches for AM33XX EDMA support<br />
with changes for few pending review comments on v9 series.<br />
<br />
Currently this is required for AM33XX (Beaglebone or EVM) to access MMC<br />
and be able mount to rootfs and boot till command prompt over MMC.<br />
Unless there are other pending review comments, I hope this series can<br />
make it into 3.11 merge window, the dependent series has been posted at [1]<br />
and completed review.<br />
<br />
Tested EDMA on AM1808 EVM and AM33XX Beaglebone with MMC.<br />
<br />
Sekhar Nori has posted a GIT PULL [1] which has 2 patches this series depends on:<br />
[1] <a href="http://www.spinics.net/lists/arm-kernel/msg251503.html" target="_blank"  rel="nofollow">http://www.spinics.net/lists/arm-kernel/msg251503.html</a><br />
<br />
Changes since v10:<br />
	- Reworked documentation based on Arnd's feedback<br />
	- Moved EDMA bindings documentation earlier in series<br />
	- Dropped mention on am33xx on 2/8 and 3/8 in the series<br />
<br />
Changes since v9:<br />
    - Droped reserved and queue DT entries from Documentation<br />
    for now from the original patch series.<br />
    - Drop DT entries that are non-hardware-description<br />
    - Split EDMA xbar support out of original EDMA DT parsing patch<br />
    to keep it easier for review.<br />
    - Rewrite shift and offset calculation xbar event mapping.<br />
    - Setup default one-to-one mapping for queue_priority and queue_tc<br />
    mapping as discussed in.<br />
    - Split out xbar stuff to separate patch.<br />
<br />
	Reference discussion:<br />
   <a href="https://patchwork.kernel.org/patch/2226761/" target="_blank"  rel="nofollow">https://patchwork.kernel.org/patch/2226761/</a><br />
<br />
Changes since v8:<br />
	- Removed edma node interrupt-parent property, it is inherited<br />
<br />
Changes since v7:<br />
	- Dropped dmaengine compat() patch. It is upstream.<br />
	- Submitted edma_alloc_slot() error checking bug fix separately,<br />
	  now a dependency<br />
	- Fixed bisect issues due to 3/10 hunks that went into 1/10<br />
	- Fixed incorrect IS_ERRVALUE() use in 3/10<br />
<br />
Changes since v6:<br />
	- Converted edma_of_read_*() to wrappers around of_property_read_*()<br />
	- Fixed wording on the omap-spi generic DMA properties<br />
	- Added comment/check to clarify that the driver only supports<br />
	  a single EDMA instance when booting from DT<br />
<br />
Changes since v5:<br />
	- Dropped mmc portion and moved it to a separate series<br />
	- Incorporate corrected version of dma_request_slave_channel_compat()<br />
	- Fix #defines and enablement of TI_PRIV_EDMA option<br />
<br />
Changes since v4:<br />
	- Fixed debug section mismatch in private edma api [01/14]<br />
	- Respun format-patch to catch the platform_data/edma.h rename [01/14]<br />
	- Removed address/size-cells from the EDMA binding [05/14]<br />
<br />
Changes since v3:<br />
	- Rebased on 3.8-rc3<br />
	- No longer an RFC<br />
	- Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia<br />
	- Restored all the Davinci pdata to const<br />
	- Removed max_segs hack in favor of using dma_get_channel_caps()<br />
	- Fixed extra parens, __raw_* accessors and, ioremap error checks<br />
	  in xbar handling<br />
	- Removed excess license info in platform_data/edma.h<br />
	- Removed unneeded reserved channels data for AM33xx<br />
	- Removed test-specific pinmuxing from dts files<br />
	- Adjusted mmc1 node to be disabled by default in the dtsi<br />
<br />
Changes since v2:<br />
	- Rebased on 3.7-rc1<br />
	- Fixed bug in DT/pdata parsing first found by Gururaja<br />
	  that turned out to be masked by some toolchains<br />
	- Dropped unused mach-omap2/devices.c hsmmc patch<br />
	- Added AM33XX crossbar DMA event mux support<br />
	- Added am335x-evm support<br />
<br />
Changes since v1:<br />
	- Rebased on top of mainline from 12250d8<br />
	- Dropped the feature removal schedule patch<br />
	- Implemented dma_request_slave_channel_compat() and<br />
	  converted the mmc and spi drivers to use it<br />
	- Dropped unneeded #address-cells and #size-cells from<br />
	  EDMA DT support<br />
	- Moved private EDMA header to linux/platform_data/ and<br />
	  removed some unneeded definitions<br />
	- Fixed parsing of optional properties<br />
<br />
This series adds DMA Engine support for AM33xx, which uses<br />
an EDMA DMAC. The EDMA DMAC has been previously supported by only<br />
a private API implementation (much like the situation with OMAP<br />
DMA) found on the DaVinci family of SoCs.<br />
<br />
The series applies on top of 3.10-rc4.<br />
<br />
The approach taken is similar to how OMAP DMA is being converted to<br />
DMA Engine support. With the functional EDMA private API already<br />
existing in mach-davinci/dma.c, we first move that to an ARM common<br />
area so it can be shared. Adding DT and runtime PM support to the<br />
private EDMA API implementation allows it to run on AM33xx. AM33xx<br />
*only* boots using DT so the upstream generic DT DMA helpers are<br />
leveraged to register EDMA DMAC with the of_dma framework. SPI (and<br />
MMC in a separate series) are supported using the upstream<br />
dma_request_slave_channel_compat() dmaengine call that allows<br />
compatibility with !DT platforms.<br />
<br />
With this series both BeagleBone and the AM335x EVM have working<br />
SPI DMA support (and MMC support with the separate MMC series).<br />
<br />
This is tested on BeagleBone with a SPI framebuffer driver and MMC<br />
rootfs. A trivial gpio DMA event misc driver was used to test the<br />
crossbar DMA event support. It is also tested on the AM335x EVM<br />
with the onboard SPI flash and MMC rootfs. Note that MMC can only<br />
be tested with a separate MMC dmaengine/DT series applied.<br />
<br />
Regression testing was done on AM180x-EVM (which also makes use<br />
of the EDMA dmaengine driver and the EDMA private API) using SD,<br />
SPI flash, and the onboard audio supported by the ASoC Davinci<br />
driver. Regression testing was also done on a BeagleBoard xM<br />
booting from the legacy board file using MMC rootfs.<br />
<br />
<br />
Matt Porter (8):<br />
  dmaengine: edma: Add TI EDMA device tree binding<br />
  ARM: edma: Add DT and runtime PM support to the private EDMA API<br />
  ARM: edma: Add EDMA crossbar event mux support<br />
  ARM: dts: add AM33XX EDMA support<br />
  ARM: dts: add AM33XX SPI DMA support<br />
  dmaengine: edma: enable build for AM33XX<br />
  spi: omap2-mcspi: add generic DMA request support to the DT binding<br />
  spi: omap2-mcspi: convert to dma_request_slave_channel_compat()<br />
<br />
 Documentation/devicetree/bindings/dma/ti-edma.txt  |   34 +++<br />
 Documentation/devicetree/bindings/spi/omap-spi.txt |   27 ++-<br />
 arch/arm/boot/dts/am33xx.dtsi                      |   22 ++<br />
 arch/arm/common/edma.c                             |  249 +++++++++++++++++++-<br />
 arch/arm/mach-omap2/Kconfig                        |    1 +<br />
 drivers/dma/Kconfig                                |    2 +-<br />
 drivers/spi/spi-omap2-mcspi.c                      |   64 +++--<br />
 include/linux/platform_data/edma.h                 |    5 +-<br />
 8 files changed, 368 insertions(+), 36 deletions(-)<br />
 create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt<br />
<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727420,727420#msg-727420</guid>
            <title>[PATCH v11 2/8] ARM: edma: Add DT and runtime PM support to the private EDMA API (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727420,727420#msg-727420</link>
            <description><![CDATA[ From: Matt Porter &lt;mporter@ti.com&gt;<br />
<br />
Adds support for parsing the TI EDMA DT data into the required EDMA<br />
private API platform data. Enables runtime PM support to initialize<br />
the EDMA hwmod. Enables build on OMAP.<br />
<br />
Changes by Joel:<br />
* Setup default one-to-one mapping for queue_priority and queue_tc<br />
mapping as discussed in [1].<br />
* Split out xbar stuff to separate patch. [1]<br />
<br />
[1] <a href="https://patchwork.kernel.org/patch/2226761/" target="_blank"  rel="nofollow">https://patchwork.kernel.org/patch/2226761/</a><br />
<br />
Signed-off-by: Matt Porter &lt;mporter@ti.com&gt;<br />
Acked-by: Sekhar Nori &lt;nsekhar@ti.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
---<br />
 arch/arm/common/edma.c             |  190 +++++++++++++++++++++++++++++++++---<br />
 arch/arm/mach-omap2/Kconfig        |    1 +<br />
 include/linux/platform_data/edma.h |    4 +-<br />
 3 files changed, 181 insertions(+), 14 deletions(-)<br />
<br />
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c<br />
index a1db6cd..9823b79 100644<br />
--- a/arch/arm/common/edma.c<br />
+++ b/arch/arm/common/edma.c<br />
@@ -24,6 +24,13 @@<br />
 #include &lt;linux/platform_device.h&gt;<br />
 #include &lt;linux/io.h&gt;<br />
 #include &lt;linux/slab.h&gt;<br />
+#include &lt;linux/edma.h&gt;<br />
+#include &lt;linux/err.h&gt;<br />
+#include &lt;linux/of_address.h&gt;<br />
+#include &lt;linux/of_device.h&gt;<br />
+#include &lt;linux/of_dma.h&gt;<br />
+#include &lt;linux/of_irq.h&gt;<br />
+#include &lt;linux/pm_runtime.h&gt;<br />
 <br />
 #include &lt;linux/platform_data/edma.h&gt;<br />
 <br />
@@ -1369,31 +1376,173 @@ void edma_clear_event(unsigned channel)<br />
 EXPORT_SYMBOL(edma_clear_event);<br />
 <br />
 /*-----------------------------------------------------------------------*/<br />
+static int edma_of_read_u32_to_s8_array(const struct device_node *np,<br />
+					 const char *propname, s8 *out_values,<br />
+					 size_t sz)<br />
+{<br />
+	int ret;<br />
+<br />
+	ret = of_property_read_u8_array(np, propname, out_values, sz);<br />
+	if (ret)<br />
+		return ret;<br />
+<br />
+	/* Terminate it */<br />
+	*out_values++ = -1;<br />
+	*out_values++ = -1;<br />
+<br />
+	return 0;<br />
+}<br />
+<br />
+static int edma_of_read_u32_to_s16_array(const struct device_node *np,<br />
+					 const char *propname, s16 *out_values,<br />
+					 size_t sz)<br />
+{<br />
+	int ret;<br />
+<br />
+	ret = of_property_read_u16_array(np, propname, out_values, sz);<br />
+	if (ret)<br />
+		return ret;<br />
+<br />
+	/* Terminate it */<br />
+	*out_values++ = -1;<br />
+	*out_values++ = -1;<br />
+<br />
+	return 0;<br />
+}<br />
 <br />
-static int __init edma_probe(struct platform_device *pdev)<br />
+static int edma_of_parse_dt(struct device *dev,<br />
+			    struct device_node *node,<br />
+			    struct edma_soc_info *pdata)<br />
+{<br />
+	int ret = 0, i;<br />
+	u32 value;<br />
+	struct property *prop;<br />
+	size_t sz;<br />
+	struct edma_rsv_info *rsv_info;<br />
+	const s16 (*rsv_chans)[2], (*rsv_slots)[2];<br />
+	s8 (*queue_tc_map)[2], (*queue_priority_map)[2];<br />
+<br />
+	memset(pdata, 0, sizeof(struct edma_soc_info));<br />
+<br />
+	ret = of_property_read_u32(node, &quot;dma-channels&quot;, &amp;value);<br />
+	if (ret &lt; 0)<br />
+		return ret;<br />
+	pdata-&gt;n_channel = value;<br />
+<br />
+	ret = of_property_read_u32(node, &quot;ti,edma-regions&quot;, &amp;value);<br />
+	if (ret &lt; 0)<br />
+		return ret;<br />
+	pdata-&gt;n_region = value;<br />
+<br />
+	ret = of_property_read_u32(node, &quot;ti,edma-slots&quot;, &amp;value);<br />
+	if (ret &lt; 0)<br />
+		return ret;<br />
+	pdata-&gt;n_slot = value;<br />
+<br />
+	pdata-&gt;n_cc = 1;<br />
+	pdata-&gt;n_tc = 3;<br />
+<br />
+	rsv_info =<br />
+		devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL);<br />
+	if (!rsv_info)<br />
+		return -ENOMEM;<br />
+	pdata-&gt;rsv = rsv_info;<br />
+<br />
+	queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);<br />
+	if (!queue_tc_map)<br />
+		return -ENOMEM;<br />
+<br />
+	for (i = 0; i &lt; 3; i++)<br />
+		queue_tc_map<i>[0] = queue_tc_map<i>[1] = i;<br />
+	queue_tc_map<i>[0] = queue_tc_map<i>[1] = -1;<br />
+<br />
+	pdata-&gt;queue_tc_mapping = queue_tc_map;<br />
+<br />
+	queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);<br />
+	if (!queue_priority_map)<br />
+		return -ENOMEM;<br />
+<br />
+	for (i = 0; i &lt; 3; i++)<br />
+		queue_priority_map<i>[0] = queue_priority_map<i>[1] = i;<br />
+	queue_priority_map<i>[0] = queue_priority_map<i>[1] = -1;<br />
+<br />
+	pdata-&gt;queue_priority_mapping = queue_priority_map;<br />
+<br />
+	pdata-&gt;default_queue = 0;<br />
+<br />
+<br />
+	return ret;<br />
+}<br />
+<br />
+static struct of_dma_filter_info edma_filter_info = {<br />
+	.filter_fn = edma_filter_fn,<br />
+};<br />
+<br />
+static int edma_probe(struct platform_device *pdev)<br />
 {<br />
 	struct edma_soc_info	**info = pdev-&gt;dev.platform_data;<br />
-	const s8		(*queue_priority_mapping)[2];<br />
-	const s8		(*queue_tc_mapping)[2];<br />
+	struct edma_soc_info	*ninfo[EDMA_MAX_CC] = {NULL, NULL};<br />
+	struct edma_soc_info	tmpinfo;<br />
+	s8		(*queue_priority_mapping)[2];<br />
+	s8		(*queue_tc_mapping)[2];<br />
 	int			i, j, off, ln, found = 0;<br />
 	int			status = -1;<br />
 	const s16		(*rsv_chans)[2];<br />
 	const s16		(*rsv_slots)[2];<br />
 	int			irq[EDMA_MAX_CC] = {0, 0};<br />
 	int			err_irq[EDMA_MAX_CC] = {0, 0};<br />
-	struct resource		*r[EDMA_MAX_CC] = {NULL};<br />
+	struct resource		*r[EDMA_MAX_CC] = {NULL, NULL};<br />
+	struct resource		res[EDMA_MAX_CC];<br />
 	resource_size_t		len[EDMA_MAX_CC];<br />
 	char			res_name[10];<br />
 	char			irq_name[10];<br />
+	struct device_node	*node = pdev-&gt;dev.of_node;<br />
+	struct device		*dev = &amp;pdev-&gt;dev;<br />
+	int			ret;<br />
+<br />
+	if (node) {<br />
+		/* Check if this is a second instance registered */<br />
+		if (arch_num_cc) {<br />
+			dev_err(dev, &quot;only one EDMA instance is supported via DT\n&quot;);<br />
+			return -ENODEV;<br />
+		}<br />
+		info = ninfo;<br />
+		edma_of_parse_dt(dev, node, &amp;tmpinfo);<br />
+		info[0] = &amp;tmpinfo;<br />
+<br />
+		dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);<br />
+		of_dma_controller_register(dev-&gt;of_node,<br />
+					   of_dma_simple_xlate,<br />
+					   &amp;edma_filter_info);<br />
+	}<br />
 <br />
 	if (!info)<br />
 		return -ENODEV;<br />
 <br />
+	pm_runtime_enable(dev);<br />
+	ret = pm_runtime_get_sync(dev);<br />
+	if (ret &lt; 0) {<br />
+		dev_err(dev, &quot;pm_runtime_get_sync() failed\n&quot;);<br />
+		return ret;<br />
+	}<br />
+<br />
 	for (j = 0; j &lt; EDMA_MAX_CC; j++) {<br />
-		sprintf(res_name, &quot;edma_cc%d&quot;, j);<br />
-		r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,<br />
+		if (!info[j]) {<br />
+			if (!found)<br />
+				return -ENODEV;<br />
+			break;<br />
+		}<br />
+		if (node) {<br />
+			ret = of_address_to_resource(node, j, &amp;res[j]);<br />
+			if (!ret)<br />
+				r[j] = &amp;res[j];<br />
+		} else {<br />
+			sprintf(res_name, &quot;edma_cc%d&quot;, j);<br />
+			r[j] = platform_get_resource_byname(pdev,<br />
+						IORESOURCE_MEM,<br />
 						res_name);<br />
-		if (!r[j] || !info[j]) {<br />
+		}<br />
+		if (!r[j]) {<br />
 			if (found)<br />
 				break;<br />
 			else<br />
@@ -1468,8 +1617,13 @@ static int __init edma_probe(struct platform_device *pdev)<br />
 			}<br />
 		}<br />
 <br />
-		sprintf(irq_name, &quot;edma%d&quot;, j);<br />
-		irq[j] = platform_get_irq_byname(pdev, irq_name);<br />
+<br />
+		if (node)<br />
+			irq[j] = irq_of_parse_and_map(node, 0);<br />
+		else {<br />
+			sprintf(irq_name, &quot;edma%d&quot;, j);<br />
+			irq[j] = platform_get_irq_byname(pdev, irq_name);<br />
+		}<br />
 		edma_cc[j]-&gt;irq_res_start = irq[j];<br />
 		status = request_irq(irq[j], dma_irq_handler, 0, &quot;edma&quot;,<br />
 					&amp;pdev-&gt;dev);<br />
@@ -1479,8 +1633,12 @@ static int __init edma_probe(struct platform_device *pdev)<br />
 			goto fail;<br />
 		}<br />
 <br />
-		sprintf(irq_name, &quot;edma%d_err&quot;, j);<br />
-		err_irq[j] = platform_get_irq_byname(pdev, irq_name);<br />
+		if (node)<br />
+			err_irq[j] = irq_of_parse_and_map(node, 2);<br />
+		else {<br />
+			sprintf(irq_name, &quot;edma%d_err&quot;, j);<br />
+			err_irq[j] = platform_get_irq_byname(pdev, irq_name);<br />
+		}<br />
 		edma_cc[j]-&gt;irq_res_end = err_irq[j];<br />
 		status = request_irq(err_irq[j], dma_ccerr_handler, 0,<br />
 					&quot;edma_error&quot;, &amp;pdev-&gt;dev);<br />
@@ -1541,9 +1699,17 @@ fail1:<br />
 	return status;<br />
 }<br />
 <br />
+static const struct of_device_id edma_of_ids[] = {<br />
+	{ .compatible = &quot;ti,edma3&quot;, },<br />
+	{}<br />
+};<br />
 <br />
 static struct platform_driver edma_driver = {<br />
-	.driver.name	= &quot;edma&quot;,<br />
+	.driver = {<br />
+		.name	= &quot;edma&quot;,<br />
+		.of_match_table = edma_of_ids,<br />
+	},<br />
+	.probe = edma_probe,<br />
 };<br />
 <br />
 static int __init edma_init(void)<br />
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig<br />
index f49cd51..f91b07f 100644<br />
--- a/arch/arm/mach-omap2/Kconfig<br />
+++ b/arch/arm/mach-omap2/Kconfig<br />
@@ -17,6 +17,7 @@ config ARCH_OMAP2PLUS<br />
 	select PROC_DEVICETREE if PROC_FS<br />
 	select SOC_BUS<br />
 	select SPARSE_IRQ<br />
+	select TI_PRIV_EDMA<br />
 	select USE_OF<br />
 	help<br />
 	  Systems based on OMAP2, OMAP3, OMAP4 or OMAP5<br />
diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h<br />
index 2344ea2..317f2be 100644<br />
--- a/include/linux/platform_data/edma.h<br />
+++ b/include/linux/platform_data/edma.h<br />
@@ -175,8 +175,8 @@ struct edma_soc_info {<br />
 	/* Resource reservation for other cores */<br />
 	struct edma_rsv_info	*rsv;<br />
 <br />
-	const s8	(*queue_tc_mapping)[2];<br />
-	const s8	(*queue_priority_mapping)[2];<br />
+	s8	(*queue_tc_mapping)[2];<br />
+	s8	(*queue_priority_mapping)[2];<br />
 };<br />
 <br />
 #endif<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a></i></i></i></i></i></i></i></i>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727419,727419#msg-727419</guid>
            <title>[PATCH v11 5/8] ARM: dts: add AM33XX SPI DMA support (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727419,727419#msg-727419</link>
            <description><![CDATA[ From: Matt Porter &lt;mporter@ti.com&gt;<br />
<br />
Adds DMA resources to the AM33XX SPI nodes.<br />
<br />
Signed-off-by: Matt Porter &lt;mporter@ti.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
---<br />
 arch/arm/boot/dts/am33xx.dtsi |   10 ++++++++++<br />
 1 file changed, 10 insertions(+)<br />
<br />
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi<br />
index 3d59bb3..fb17103 100644<br />
--- a/arch/arm/boot/dts/am33xx.dtsi<br />
+++ b/arch/arm/boot/dts/am33xx.dtsi<br />
@@ -361,6 +361,11 @@<br />
 			interrupts = &lt;65&gt;;<br />
 			ti,spi-num-cs = &lt;2&gt;;<br />
 			ti,hwmods = &quot;spi0&quot;;<br />
+			dmas = &lt;&amp;edma 16<br />
+				&amp;edma 17<br />
+				&amp;edma 18<br />
+				&amp;edma 19&gt;;<br />
+			dma-names = &quot;tx0&quot;, &quot;rx0&quot;, &quot;tx1&quot;, &quot;rx1&quot;;<br />
 			status = &quot;disabled&quot;;<br />
 		};<br />
 <br />
@@ -372,6 +377,11 @@<br />
 			interrupts = &lt;125&gt;;<br />
 			ti,spi-num-cs = &lt;2&gt;;<br />
 			ti,hwmods = &quot;spi1&quot;;<br />
+			dmas = &lt;&amp;edma 42<br />
+				&amp;edma 43<br />
+				&amp;edma 44<br />
+				&amp;edma 45&gt;;<br />
+			dma-names = &quot;tx0&quot;, &quot;rx0&quot;, &quot;tx1&quot;, &quot;rx1&quot;;<br />
 			status = &quot;disabled&quot;;<br />
 		};<br />
 <br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727418,727418#msg-727418</guid>
            <title>[PATCH v11 4/8] ARM: dts: add AM33XX EDMA support (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727418,727418#msg-727418</link>
            <description><![CDATA[ From: Matt Porter &lt;mdp@ti.com&gt;<br />
<br />
Adds AM33XX EDMA support to the am33xx.dtsi as documented in<br />
Documentation/devicetree/bindings/dma/ti-edma.txt<br />
<br />
Joel: Drop DT entries that are non-hardware-description for now as discussed in [1]<br />
<br />
[1] <a href="https://patchwork.kernel.org/patch/2226761/" target="_blank"  rel="nofollow">https://patchwork.kernel.org/patch/2226761/</a><br />
<br />
Signed-off-by: Matt Porter &lt;mporter@ti.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
---<br />
 arch/arm/boot/dts/am33xx.dtsi |   12 ++++++++++++<br />
 1 file changed, 12 insertions(+)<br />
<br />
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi<br />
index d9cad72..3d59bb3 100644<br />
--- a/arch/arm/boot/dts/am33xx.dtsi<br />
+++ b/arch/arm/boot/dts/am33xx.dtsi<br />
@@ -89,6 +89,18 @@<br />
 			reg = &lt;0x48200000 0x1000&gt;;<br />
 		};<br />
 <br />
+		edma: edma@49000000 {<br />
+			compatible = &quot;ti,edma3&quot;;<br />
+			ti,hwmods = &quot;tpcc&quot;, &quot;tptc0&quot;, &quot;tptc1&quot;, &quot;tptc2&quot;;<br />
+			reg =	&lt;0x49000000 0x10000&gt;,<br />
+				&lt;0x44e10f90 0x10&gt;;<br />
+			interrupts = &lt;12 13 14&gt;;<br />
+			#dma-cells = &lt;1&gt;;<br />
+			dma-channels = &lt;64&gt;;<br />
+			ti,edma-regions = &lt;4&gt;;<br />
+			ti,edma-slots = &lt;256&gt;;<br />
+		};<br />
+<br />
 		gpio0: gpio@44e07000 {<br />
 			compatible = &quot;ti,omap4-gpio&quot;;<br />
 			ti,hwmods = &quot;gpio1&quot;;<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727417,727417#msg-727417</guid>
            <title>[PATCH v11 7/8] spi: omap2-mcspi: add generic DMA request support to the DT binding (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727417,727417#msg-727417</link>
            <description><![CDATA[ From: Matt Porter &lt;mporter@ti.com&gt;<br />
<br />
The binding definition is based on the generic DMA request binding<br />
<br />
Signed-off-by: Matt Porter &lt;mporter@ti.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
---<br />
 Documentation/devicetree/bindings/spi/omap-spi.txt |   27 +++++++++++++++++++-<br />
 1 file changed, 26 insertions(+), 1 deletion(-)<br />
<br />
diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt<br />
index 938809c..4c85c4c 100644<br />
--- a/Documentation/devicetree/bindings/spi/omap-spi.txt<br />
+++ b/Documentation/devicetree/bindings/spi/omap-spi.txt<br />
@@ -10,7 +10,18 @@ Required properties:<br />
 			  input. The default is D0 as input and<br />
 			  D1 as output.<br />
 <br />
-Example:<br />
+Optional properties:<br />
+- dmas: List of DMA specifiers with the controller specific format<br />
+	as described in the generic DMA client binding. A tx and rx<br />
+	specifier is required for each chip select.<br />
+- dma-names: List of DMA request names. These strings correspond<br />
+	1:1 with the DMA specifiers listed in dmas. The string naming<br />
+	is to be &quot;rxN&quot; and &quot;txN&quot; for RX and TX requests,<br />
+	respectively, where N equals the chip select number.<br />
+<br />
+Examples:<br />
+<br />
+[hwmod populated DMA resources]<br />
 <br />
 mcspi1: mcspi@1 {<br />
     #address-cells = &lt;1&gt;;<br />
@@ -20,3 +31,17 @@ mcspi1: mcspi@1 {<br />
     ti,spi-num-cs = &lt;4&gt;;<br />
 };<br />
 <br />
+[generic DMA request binding]<br />
+<br />
+mcspi1: mcspi@1 {<br />
+    #address-cells = &lt;1&gt;;<br />
+    #size-cells = &lt;0&gt;;<br />
+    compatible = &quot;ti,omap4-mcspi&quot;;<br />
+    ti,hwmods = &quot;mcspi1&quot;;<br />
+    ti,spi-num-cs = &lt;2&gt;;<br />
+    dmas = &lt;&amp;edma 42<br />
+	    &amp;edma 43<br />
+	    &amp;edma 44<br />
+	    &amp;edma 45&gt;;<br />
+    dma-names = &quot;tx0&quot;, &quot;rx0&quot;, &quot;tx1&quot;, &quot;rx1&quot;;<br />
+};<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727416,727416#msg-727416</guid>
            <title>[PATCH v11 3/8] ARM: edma: Add EDMA crossbar event mux support (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727416,727416#msg-727416</link>
            <description><![CDATA[ From: Matt Porter &lt;mporter@ti.com&gt;<br />
<br />
Changes by Joel:<br />
* Split EDMA xbar support out of original EDMA DT parsing patch<br />
to keep it easier for review.<br />
* Rewrite shift and offset calculation.<br />
<br />
Suggested-by: Sekhar Nori &lt;nsekhar@ti.com&gt;<br />
Suggested by: Andy Shevchenko &lt;andy.shevchenko@gmail.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
<br />
Reference:<br />
[1] <a href="https://patchwork.kernel.org/patch/2226991/" target="_blank"  rel="nofollow">https://patchwork.kernel.org/patch/2226991/</a><br />
---<br />
 arch/arm/common/edma.c             |   59 ++++++++++++++++++++++++++++++++++++<br />
 include/linux/platform_data/edma.h |    1 +<br />
 2 files changed, 60 insertions(+)<br />
<br />
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c<br />
index 9823b79..1c2fb15 100644<br />
--- a/arch/arm/common/edma.c<br />
+++ b/arch/arm/common/edma.c<br />
@@ -1410,6 +1410,52 @@ static int edma_of_read_u32_to_s16_array(const struct device_node *np,<br />
 	return 0;<br />
 }<br />
 <br />
+static int edma_xbar_event_map(struct device *dev,<br />
+			       struct device_node *node,<br />
+			       struct edma_soc_info *pdata, int len)<br />
+{<br />
+	int ret = 0;<br />
+	int i;<br />
+	struct resource res;<br />
+	void *xbar;<br />
+	const s16 (*xbar_chans)[2];<br />
+	u32 shift, offset, mux;<br />
+<br />
+	xbar_chans = devm_kzalloc(dev,<br />
+				  len/sizeof(s16) + 2*sizeof(s16),<br />
+				  GFP_KERNEL);<br />
+	if (!xbar_chans)<br />
+		return -ENOMEM;<br />
+<br />
+	ret = of_address_to_resource(node, 1, &amp;res);<br />
+	if (ret)<br />
+		return -EIO;<br />
+<br />
+	xbar = devm_ioremap(dev, res.start, resource_size(&amp;res));<br />
+	if (!xbar)<br />
+		return -ENOMEM;<br />
+<br />
+	ret = edma_of_read_u32_to_s16_array(node,<br />
+					    &quot;ti,edma-xbar-event-map&quot;,<br />
+					    (s16 *)xbar_chans,<br />
+					    len/sizeof(u32));<br />
+	if (ret)<br />
+		return -EIO;<br />
+<br />
+	for (i = 0; xbar_chans<i>[0] != -1; i++) {<br />
+		shift = (xbar_chans<i>[1] &amp; 0x03) &lt;&lt; 3;<br />
+		offset = xbar_chans<i>[1] &amp; 0xfffffffc;<br />
+		mux = readl((void *)((u32)xbar + offset));<br />
+		mux &amp;= ~(0xff &lt;&lt; shift);<br />
+		mux |= xbar_chans<i>[0] &lt;&lt; shift;<br />
+		writel(mux, (void *)((u32)xbar + offset));<br />
+	}<br />
+<br />
+	pdata-&gt;xbar_chans = xbar_chans;<br />
+<br />
+	return 0;<br />
+}<br />
+<br />
 static int edma_of_parse_dt(struct device *dev,<br />
 			    struct device_node *node,<br />
 			    struct edma_soc_info *pdata)<br />
@@ -1470,6 +1516,9 @@ static int edma_of_parse_dt(struct device *dev,<br />
 <br />
 	pdata-&gt;default_queue = 0;<br />
 <br />
+	prop = of_find_property(node, &quot;ti,edma-xbar-event-map&quot;, &amp;sz);<br />
+	if (prop)<br />
+		ret = edma_xbar_event_map(dev, node, pdata, sz);<br />
 <br />
 	return ret;<br />
 }<br />
@@ -1489,6 +1538,7 @@ static int edma_probe(struct platform_device *pdev)<br />
 	int			status = -1;<br />
 	const s16		(*rsv_chans)[2];<br />
 	const s16		(*rsv_slots)[2];<br />
+	const s16		(*xbar_chans)[2];<br />
 	int			irq[EDMA_MAX_CC] = {0, 0};<br />
 	int			err_irq[EDMA_MAX_CC] = {0, 0};<br />
 	struct resource		*r[EDMA_MAX_CC] = {NULL, NULL};<br />
@@ -1617,6 +1667,15 @@ static int edma_probe(struct platform_device *pdev)<br />
 			}<br />
 		}<br />
 <br />
+		/* Clear the xbar mapped channels in unused list */<br />
+		xbar_chans = info[j]-&gt;xbar_chans;<br />
+		if (xbar_chans) {<br />
+			for (i = 0; xbar_chans<i>[1] != -1; i++) {<br />
+				off = xbar_chans<i>[1];<br />
+				clear_bits(off, 1,<br />
+					edma_cc[j]-&gt;edma_unused);<br />
+			}<br />
+		}<br />
 <br />
 		if (node)<br />
 			irq[j] = irq_of_parse_and_map(node, 0);<br />
diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h<br />
index 317f2be..57300fd 100644<br />
--- a/include/linux/platform_data/edma.h<br />
+++ b/include/linux/platform_data/edma.h<br />
@@ -177,6 +177,7 @@ struct edma_soc_info {<br />
 <br />
 	s8	(*queue_tc_mapping)[2];<br />
 	s8	(*queue_priority_mapping)[2];<br />
+	const s16	(*xbar_chans)[2];<br />
 };<br />
 <br />
 #endif<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a></i></i></i></i></i></i>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727415,727415#msg-727415</guid>
            <title>[PATCH v11 8/8] spi: omap2-mcspi: convert to dma_request_slave_channel_compat() (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727415,727415#msg-727415</link>
            <description><![CDATA[ From: Matt Porter &lt;mporter@ti.com&gt;<br />
<br />
Convert dmaengine channel requests to use<br />
dma_request_slave_channel_compat(). This supports the DT case of<br />
platforms requiring channel selection from either the OMAP DMA or<br />
the EDMA engine. AM33xx only boots from DT and is the only user<br />
implementing EDMA so in the !DT case we can default to the OMAP DMA<br />
filter.<br />
<br />
Signed-off-by: Matt Porter &lt;mporter@ti.com&gt;<br />
Acked-by: Mark Brown &lt;broonie@opensource.wolfsonmicro.com&gt;<br />
Signed-off-by: Joel A Fernandes &lt;joelagnel@ti.com&gt;<br />
---<br />
 drivers/spi/spi-omap2-mcspi.c |   64 ++++++++++++++++++++++++++++-------------<br />
 1 file changed, 44 insertions(+), 20 deletions(-)<br />
<br />
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c<br />
index 86d2158..ca4ab78 100644<br />
--- a/drivers/spi/spi-omap2-mcspi.c<br />
+++ b/drivers/spi/spi-omap2-mcspi.c<br />
@@ -102,6 +102,9 @@ struct omap2_mcspi_dma {<br />
 <br />
 	struct completion dma_tx_completion;<br />
 	struct completion dma_rx_completion;<br />
+<br />
+	char dma_rx_ch_name[14];<br />
+	char dma_tx_ch_name[14];<br />
 };<br />
 <br />
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and<br />
@@ -830,12 +833,20 @@ static int omap2_mcspi_request_dma(struct spi_device *spi)<br />
 	dma_cap_zero(mask);<br />
 	dma_cap_set(DMA_SLAVE, mask);<br />
 	sig = mcspi_dma-&gt;dma_rx_sync_dev;<br />
-	mcspi_dma-&gt;dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &amp;sig);<br />
+<br />
+	mcspi_dma-&gt;dma_rx =<br />
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,<br />
+						 &amp;sig, &amp;master-&gt;dev,<br />
+						 mcspi_dma-&gt;dma_rx_ch_name);<br />
 	if (!mcspi_dma-&gt;dma_rx)<br />
 		goto no_dma;<br />
 <br />
 	sig = mcspi_dma-&gt;dma_tx_sync_dev;<br />
-	mcspi_dma-&gt;dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &amp;sig);<br />
+	mcspi_dma-&gt;dma_tx =<br />
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,<br />
+						 &amp;sig, &amp;master-&gt;dev,<br />
+						 mcspi_dma-&gt;dma_tx_ch_name);<br />
+<br />
 	if (!mcspi_dma-&gt;dma_tx) {<br />
 		dma_release_channel(mcspi_dma-&gt;dma_rx);<br />
 		mcspi_dma-&gt;dma_rx = NULL;<br />
@@ -1256,29 +1267,42 @@ static int omap2_mcspi_probe(struct platform_device *pdev)<br />
 		goto free_master;<br />
 <br />
 	for (i = 0; i &lt; master-&gt;num_chipselect; i++) {<br />
-		char dma_ch_name[14];<br />
+		char *dma_rx_ch_name = mcspi-&gt;dma_channels<i>.dma_rx_ch_name;<br />
+		char *dma_tx_ch_name = mcspi-&gt;dma_channels<i>.dma_tx_ch_name;<br />
 		struct resource *dma_res;<br />
 <br />
-		sprintf(dma_ch_name, &quot;rx%d&quot;, i);<br />
-		dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,<br />
-				dma_ch_name);<br />
-		if (!dma_res) {<br />
-			dev_dbg(&amp;pdev-&gt;dev, &quot;cannot get DMA RX channel\n&quot;);<br />
-			status = -ENODEV;<br />
-			break;<br />
-		}<br />
+		sprintf(dma_rx_ch_name, &quot;rx%d&quot;, i);<br />
+		if (!pdev-&gt;dev.of_node) {<br />
+			dma_res =<br />
+				platform_get_resource_byname(pdev,<br />
+							     IORESOURCE_DMA,<br />
+							     dma_rx_ch_name);<br />
+			if (!dma_res) {<br />
+				dev_dbg(&amp;pdev-&gt;dev,<br />
+					&quot;cannot get DMA RX channel\n&quot;);<br />
+				status = -ENODEV;<br />
+				break;<br />
+			}<br />
 <br />
-		mcspi-&gt;dma_channels<i>.dma_rx_sync_dev = dma_res-&gt;start;<br />
-		sprintf(dma_ch_name, &quot;tx%d&quot;, i);<br />
-		dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,<br />
-				dma_ch_name);<br />
-		if (!dma_res) {<br />
-			dev_dbg(&amp;pdev-&gt;dev, &quot;cannot get DMA TX channel\n&quot;);<br />
-			status = -ENODEV;<br />
-			break;<br />
+			mcspi-&gt;dma_channels<i>.dma_rx_sync_dev =<br />
+				dma_res-&gt;start;<br />
 		}<br />
+		sprintf(dma_tx_ch_name, &quot;tx%d&quot;, i);<br />
+		if (!pdev-&gt;dev.of_node) {<br />
+			dma_res =<br />
+				platform_get_resource_byname(pdev,<br />
+							     IORESOURCE_DMA,<br />
+							     dma_tx_ch_name);<br />
+			if (!dma_res) {<br />
+				dev_dbg(&amp;pdev-&gt;dev,<br />
+					&quot;cannot get DMA TX channel\n&quot;);<br />
+				status = -ENODEV;<br />
+				break;<br />
+			}<br />
 <br />
-		mcspi-&gt;dma_channels<i>.dma_tx_sync_dev = dma_res-&gt;start;<br />
+			mcspi-&gt;dma_channels<i>.dma_tx_sync_dev =<br />
+				dma_res-&gt;start;<br />
+		}<br />
 	}<br />
 <br />
 	if (status &lt; 0)<br />
-- <br />
1.7.9.5<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a></i></i></i></i></i></i>]]></description>
            <dc:creator>Joel A Fernandes</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:40:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727413,727413#msg-727413</guid>
            <title>[PATCH] sched: fix load_above_capacity underflow (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727413,727413#msg-727413</link>
            <description><![CDATA[ Apparently we don't want to see sds-&gt;busiest_nr_running is small than<br />
sds-&gt;busiest_group_capacity, while our load_above_capacity is<br />
an &quot;unsigned long&quot; type.<br />
<br />
Signed-off-by: Lei Wen &lt;leiwen@marvell.com&gt;<br />
---<br />
 kernel/sched/fair.c |   13 +++++++++----<br />
 1 file changed, 9 insertions(+), 4 deletions(-)<br />
<br />
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c<br />
index c61a614..fd90b17 100644<br />
--- a/kernel/sched/fair.c<br />
+++ b/kernel/sched/fair.c<br />
@@ -4780,12 +4780,17 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s<br />
 		/*<br />
 		 * Don't want to pull so many tasks that a group would go idle.<br />
 		 */<br />
-		load_above_capacity = (sds-&gt;busiest_nr_running -<br />
-						sds-&gt;busiest_group_capacity);<br />
+		if (sds-&gt;busiest_has_capacity)<br />
+			load_above_capacity = 0;<br />
+		else {<br />
+			load_above_capacity = (sds-&gt;busiest_nr_running -<br />
+					sds-&gt;busiest_group_capacity);<br />
 <br />
-		load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE);<br />
+			load_above_capacity *=<br />
+				(SCHED_LOAD_SCALE * SCHED_POWER_SCALE);<br />
 <br />
-		load_above_capacity /= sds-&gt;busiest-&gt;sgp-&gt;power;<br />
+			load_above_capacity /= sds-&gt;busiest-&gt;sgp-&gt;power;<br />
+		}<br />
 	}<br />
 <br />
 	/*<br />
-- <br />
1.7.10.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Lei Wen</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727411,727411#msg-727411</guid>
            <title>[PATCH v2] dma: mmp_pdma: fix a memory alloc error (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727411,727411#msg-727411</link>
            <description><![CDATA[ From: Xiang Wang &lt;wangx@marvell.com&gt;<br />
<br />
pdev-&gt;phy is of type &quot;struct mmp_pdma_phy *&quot;. But when<br />
allocating memory for it, &quot;struct mmp_pdma_chan&quot; is used<br />
by mistake.<br />
<br />
Signed-off-by: Xiang Wang &lt;wangx@marvell.com&gt;<br />
---<br />
 drivers/dma/mmp_pdma.c |    2 +-<br />
 1 files changed, 1 insertions(+), 1 deletions(-)<br />
<br />
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c<br />
index c26699f..18ac57f 100644<br />
--- a/drivers/dma/mmp_pdma.c<br />
+++ b/drivers/dma/mmp_pdma.c<br />
@@ -801,7 +801,7 @@ static int mmp_pdma_probe(struct platform_device *op)<br />
 	}<br />
 <br />
 	pdev-&gt;phy = devm_kzalloc(pdev-&gt;dev,<br />
-		dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);<br />
+		dma_channels * sizeof(*pdev-&gt;phy), GFP_KERNEL);<br />
 	if (pdev-&gt;phy == NULL)<br />
 		return -ENOMEM;<br />
 <br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Xiang Wang</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727409,727409#msg-727409</guid>
            <title>linux-next: manual merge of the arm-soc tree with the usb tree (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727409,727409#msg-727409</link>
            <description><![CDATA[ Hi all,<br />
<br />
Today's linux-next merge of the arm-soc tree got a conflict in<br />
drivers/usb/phy/phy-rcar-usb.c between commit 56a9a6de2a87 (&quot;usb: phy:<br />
rcar-usb: Fix comment w.r.t. devm_ioremap_resource&quot;) from the usb tree<br />
and commit 725bf9dcafe1 (&quot;phy-rcar-usb: correct base address&quot;) from the<br />
arm-soc tree.<br />
<br />
I fixed it up (The latter removed the comment corrected by the former)<br />
and can carry the fix as necessary (no action is required).<br />
<br />
-- <br />
Cheers,<br />
Stephen Rothwell                    <a href="mailto:&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;">&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;</a>]]></description>
            <dc:creator>Stephen Rothwell</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 08:20:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727401,727401#msg-727401</guid>
            <title>linux-next: manual merge of the irqdomain tree with the  tree (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727401,727401#msg-727401</link>
            <description><![CDATA[ Hi Grant,<br />
<br />
Today's linux-next merge of the irqdomain tree got a conflict in<br />
kernel/irq/irqdomain.c between commit c5cdc67a58a2 (&quot;irqdomain: Remove<br />
temporary MIPS workaround code&quot;) from the mips tree and commit<br />
bd4641e31e90 (&quot;irq: fix checkpatch error&quot;) from the irqdomain tree.<br />
<br />
I fixed it up (see below) and can carry the fix as necessary (no action<br />
is required).<br />
<br />
-- <br />
Cheers,<br />
Stephen Rothwell                    <a href="mailto:&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;">&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;</a><br />
<br />
diff --cc kernel/irq/irqdomain.c<br />
index a341b3d,13f2654..0000000<br />
--- a/kernel/irq/irqdomain.c<br />
+++ b/kernel/irq/irqdomain.c<br />
@@@ -665,8 -475,20 +475,8 @@@ unsigned int irq_create_of_mapping(stru<br />
  <br />
  	domain = controller ? irq_find_host(controller) : irq_default_domain;<br />
  	if (!domain) {<br />
- 		pr_warning(&quot;no irq domain found for %s !\n&quot;,<br />
- 			   of_node_full_name(controller));<br />
 -#ifdef CONFIG_MIPS<br />
 -		/*<br />
 -		 * Workaround to avoid breaking interrupt controller drivers<br />
 -		 * that don't yet register an irq_domain.  This is temporary<br />
 -		 * code. ~~~gcl, Feb 24, 2012<br />
 -		 *<br />
 -		 * Scheduled for removal in Linux v3.6.  That should be enough<br />
 -		 * time.<br />
 -		 */<br />
 -		if (intsize &gt; 0)<br />
 -			return intspec[0];<br />
 -#endif<br />
+ 		pr_warn(&quot;no irq domain found for %s !\n&quot;,<br />
+ 			of_node_full_name(controller));<br />
  		return 0;<br />
  	}]]></description>
            <dc:creator>Stephen Rothwell</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:50:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727395,727395#msg-727395</guid>
            <title>[PATCH 4/4] idr: Percpu ida (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727395,727395#msg-727395</link>
            <description><![CDATA[ Percpu frontend for allocating ids. With percpu allocation (that works),<br />
it's impossible to guarantee it will always be possible to allocate all<br />
nr_tags - typically, some will be stuck on a remote percpu freelist<br />
where the current job can't get to them.<br />
<br />
We do guarantee that it will always be possible to allocate at least<br />
(nr_tags / 2) tags - this is done by keeping track of which and how many<br />
cpus have tags on their percpu freelists. On allocation failure if<br />
enough cpus have tags that there could potentially be (nr_tags / 2) tags<br />
stuck on remote percpu freelists, we then pick a remote cpu at random to<br />
steal from.<br />
<br />
Note that the synchronization is _definitely_ tricky - we're using<br />
xchg()/cmpxchg() on the percpu lists, to synchronize between<br />
steal_tags().<br />
<br />
The alternative would've been adding a spinlock to protect the percpu<br />
freelists, but that would've required some different tricky code to<br />
avoid deadlock because of the lock ordering.<br />
<br />
Note that there's no cpu hotplug notifier - we don't care, because<br />
steal_tags() will eventually get the down cpu's tags. We _could_ satisfy<br />
more allocations if we had a notifier - but we'll still meet our<br />
guarantees and it's absolutely not a correctness issue, so I don't think<br />
it's worth the extra code.<br />
<br />
Signed-off-by: Kent Overstreet &lt;koverstreet@google.com&gt;<br />
Cc: Tejun Heo &lt;tj@kernel.org&gt;<br />
Cc: Oleg Nesterov &lt;oleg@redhat.com&gt;<br />
Cc: Christoph Lameter &lt;cl@linux-foundation.org&gt;<br />
Cc: Ingo Molnar &lt;mingo@redhat.com&gt;<br />
Cc: Andi Kleen &lt;andi@firstfloor.org&gt;<br />
Cc: Jens Axboe &lt;axboe@kernel.dk&gt;<br />
Cc: &quot;Nicholas A. Bellinger&quot; &lt;nab@linux-iscsi.org&gt;<br />
---<br />
 include/linux/idr.h |  48 ++++++++<br />
 lib/idr.c           | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++--<br />
 2 files changed, 352 insertions(+), 8 deletions(-)<br />
<br />
diff --git a/include/linux/idr.h b/include/linux/idr.h<br />
index 9169e18..afaa071 100644<br />
--- a/include/linux/idr.h<br />
+++ b/include/linux/idr.h<br />
@@ -16,6 +16,8 @@<br />
 #include &lt;linux/bitops.h&gt;<br />
 #include &lt;linux/init.h&gt;<br />
 #include &lt;linux/rcupdate.h&gt;<br />
+#include &lt;linux/spinlock_types.h&gt;<br />
+#include &lt;linux/wait.h&gt;<br />
 <br />
 /* IDA */<br />
 <br />
@@ -97,6 +99,52 @@ static inline void ida_init(struct ida *ida)<br />
 	ida_init_prealloc(ida, 0);<br />
 }<br />
 <br />
+/* Percpu IDA/tag allocator */<br />
+<br />
+struct percpu_ida_cpu;<br />
+<br />
+struct percpu_ida {<br />
+	/*<br />
+	 * number of tags available to be allocated, as passed to<br />
+	 * percpu_ida_init()<br />
+	 */<br />
+	unsigned			nr_tags;<br />
+<br />
+	struct percpu_ida_cpu __percpu	*tag_cpu;<br />
+<br />
+	/*<br />
+	 * Bitmap of cpus that (may) have tags on their percpu freelists:<br />
+	 * steal_tags() uses this to decide when to steal tags, and which cpus<br />
+	 * to try stealing from.<br />
+	 *<br />
+	 * It's ok for a freelist to be empty when its bit is set - steal_tags()<br />
+	 * will just keep looking - but the bitmap _must_ be set whenever a<br />
+	 * percpu freelist does have tags.<br />
+	 */<br />
+	unsigned long			*cpus_have_tags;<br />
+<br />
+	struct {<br />
+		/*<br />
+		 * When we go to steal tags from another cpu (see steal_tags()),<br />
+		 * we want to pick a cpu at random. Cycling through them every<br />
+		 * time we steal is a bit easier and more or less equivalent:<br />
+		 */<br />
+		unsigned		cpu_last_stolen;<br />
+<br />
+		/* For sleeping on allocation failure */<br />
+		wait_queue_head_t	wait;<br />
+<br />
+		/* Global freelist */<br />
+		struct ida		ida;<br />
+	} ____cacheline_aligned_in_smp;<br />
+};<br />
+<br />
+int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp);<br />
+void percpu_ida_free(struct percpu_ida *pool, unsigned tag);<br />
+<br />
+void percpu_ida_destroy(struct percpu_ida *pool);<br />
+int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags);<br />
+<br />
 /* IDR */<br />
 <br />
 /*<br />
diff --git a/lib/idr.c b/lib/idr.c<br />
index 7d89587..401933f 100644<br />
--- a/lib/idr.c<br />
+++ b/lib/idr.c<br />
@@ -28,17 +28,20 @@<br />
  * with the slab allocator.<br />
  */<br />
 <br />
-#ifndef TEST                        // to test in user space...<br />
-#include &lt;linux/slab.h&gt;<br />
-#include &lt;linux/init.h&gt;<br />
-#include &lt;linux/export.h&gt;<br />
-#endif<br />
+#include &lt;linux/bitmap.h&gt;<br />
+#include &lt;linux/bitops.h&gt;<br />
+#include &lt;linux/bug.h&gt;<br />
 #include &lt;linux/err.h&gt;<br />
-#include &lt;linux/string.h&gt;<br />
+#include &lt;linux/export.h&gt;<br />
+#include &lt;linux/hardirq.h&gt;<br />
 #include &lt;linux/idr.h&gt;<br />
-#include &lt;linux/spinlock.h&gt;<br />
+#include &lt;linux/init.h&gt;<br />
+#include &lt;linux/kernel.h&gt;<br />
 #include &lt;linux/percpu.h&gt;<br />
-#include &lt;linux/hardirq.h&gt;<br />
+#include &lt;linux/sched.h&gt;<br />
+#include &lt;linux/slab.h&gt;<br />
+#include &lt;linux/string.h&gt;<br />
+#include &lt;linux/spinlock.h&gt;<br />
 <br />
 #define IDA_TREE_ARY		BITS_PER_LONG<br />
 <br />
@@ -527,6 +530,299 @@ int ida_init_prealloc(struct ida *ida, unsigned prealloc)<br />
 }<br />
 EXPORT_SYMBOL(ida_init_prealloc);<br />
 <br />
+/* Percpu IDA */<br />
+<br />
+/*<br />
+ * Number of tags we move between the percpu freelist and the global freelist at<br />
+ * a time<br />
+ */<br />
+#define TAG_CPU_BATCH_MOVE	32U<br />
+<br />
+/* Max size of percpu freelist, */<br />
+#define TAG_CPU_SIZE		(TAG_CPU_BATCH_MOVE + TAG_CPU_BATCH_MOVE / 2)<br />
+<br />
+struct percpu_ida_cpu {<br />
+	spinlock_t			lock;<br />
+	unsigned			nr_free;<br />
+	unsigned			freelist[];<br />
+};<br />
+<br />
+/*<br />
+ * Try to steal tags from a remote cpu's percpu freelist.<br />
+ *<br />
+ * We first check how many percpu freelists have tags - we don't steal tags<br />
+ * unless enough percpu freelists have tags on them that it's possible more than<br />
+ * half the total tags could be stuck on remote percpu freelists.<br />
+ *<br />
+ * Then we iterate through the cpus until we find some tags - we don't attempt<br />
+ * to find the &quot;best&quot; cpu to steal from, to keep cacheline bouncing to a<br />
+ * minimum.<br />
+ *<br />
+ * Returns true on success (our percpu freelist is no longer empty), false on<br />
+ * failure.<br />
+ */<br />
+static inline bool steal_tags(struct percpu_ida *pool,<br />
+			      struct percpu_ida_cpu *tags)<br />
+{<br />
+	unsigned cpus_have_tags, cpu = pool-&gt;cpu_last_stolen;<br />
+	struct percpu_ida_cpu *remote;<br />
+<br />
+	for (cpus_have_tags = bitmap_weight(pool-&gt;cpus_have_tags, nr_cpu_ids);<br />
+	     cpus_have_tags * TAG_CPU_SIZE &gt; pool-&gt;nr_tags / 2;<br />
+	     cpus_have_tags--) {<br />
+		cpu = find_next_bit(pool-&gt;cpus_have_tags, nr_cpu_ids, cpu);<br />
+<br />
+		if (cpu == nr_cpu_ids)<br />
+			cpu = find_first_bit(pool-&gt;cpus_have_tags, nr_cpu_ids);<br />
+<br />
+		if (cpu == nr_cpu_ids)<br />
+			BUG();<br />
+<br />
+		pool-&gt;cpu_last_stolen = cpu;<br />
+		remote = per_cpu_ptr(pool-&gt;tag_cpu, cpu);<br />
+<br />
+		clear_bit(cpu, pool-&gt;cpus_have_tags);<br />
+<br />
+		if (remote == tags)<br />
+			continue;<br />
+<br />
+		spin_lock(&amp;remote-&gt;lock);<br />
+<br />
+		if (remote-&gt;nr_free) {<br />
+			memcpy(tags-&gt;freelist,<br />
+			       remote-&gt;freelist,<br />
+			       sizeof(unsigned) * remote-&gt;nr_free);<br />
+<br />
+			tags-&gt;nr_free = remote-&gt;nr_free;<br />
+			remote-&gt;nr_free = 0;<br />
+		}<br />
+<br />
+		spin_unlock(&amp;remote-&gt;lock);<br />
+<br />
+		if (tags-&gt;nr_free)<br />
+			return true;<br />
+	}<br />
+<br />
+	return false;<br />
+}<br />
+<br />
+static inline bool alloc_global_tags(struct percpu_ida *pool,<br />
+				     struct percpu_ida_cpu *tags)<br />
+{<br />
+	int nr_free = __ida_alloc_range_multiple(&amp;pool-&gt;ida, tags-&gt;freelist,<br />
+						 TAG_CPU_BATCH_MOVE, 0,<br />
+						 pool-&gt;nr_tags, GFP_NOWAIT,<br />
+						 NULL);<br />
+<br />
+	if (nr_free &lt;= 0)<br />
+		return false;<br />
+<br />
+	tags-&gt;nr_free = nr_free;<br />
+	return true;<br />
+}<br />
+<br />
+static inline unsigned alloc_local_tag(struct percpu_ida *pool,<br />
+				       struct percpu_ida_cpu *tags)<br />
+{<br />
+	int tag = -ENOSPC;<br />
+<br />
+	spin_lock(&amp;tags-&gt;lock);<br />
+	if (tags-&gt;nr_free)<br />
+			tag = tags-&gt;freelist[--tags-&gt;nr_free];<br />
+	spin_unlock(&amp;tags-&gt;lock);<br />
+<br />
+	return tag;<br />
+}<br />
+<br />
+/**<br />
+ * percpu_ida_alloc - allocate a tag<br />
+ * @pool: pool to allocate from<br />
+ * @gfp: gfp flags<br />
+ *<br />
+ * Returns a tag - an integer in the range [0..nr_tags) (passed to<br />
+ * tag_pool_init()), or otherwise -ENOSPC on allocation failure.<br />
+ *<br />
+ * Safe to be called from interrupt context (assuming it isn't passed<br />
+ * __GFP_WAIT, of course).<br />
+ *<br />
+ * Will not fail if passed __GFP_WAIT.<br />
+ */<br />
+int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp)<br />
+{<br />
+	DEFINE_WAIT(wait);<br />
+	struct percpu_ida_cpu *tags;<br />
+	unsigned long flags;<br />
+	unsigned this_cpu;<br />
+	int tag;<br />
+<br />
+	local_irq_save(flags);<br />
+	this_cpu = smp_processor_id();<br />
+	tags = per_cpu_ptr(pool-&gt;tag_cpu, this_cpu);<br />
+<br />
+	/* Fastpath */<br />
+	tag = alloc_local_tag(pool, tags);<br />
+	if (likely(tag &gt;= 0)) {<br />
+		local_irq_restore(flags);<br />
+		return tag;<br />
+	}<br />
+<br />
+	while (1) {<br />
+		spin_lock(&amp;pool-&gt;ida.lock);<br />
+<br />
+		/*<br />
+		 * prepare_to_wait() must come before steal_tags(), in case<br />
+		 * percpu_ida_free() on another cpu flips a bit in<br />
+		 * cpus_have_tags<br />
+		 */<br />
+		prepare_to_wait(&amp;pool-&gt;wait, &amp;wait, TASK_UNINTERRUPTIBLE);<br />
+<br />
+		/*<br />
+		 * alloc_global_tags(), steal_tags() return true iff we now have<br />
+		 * tags on our percpu freelist<br />
+		 */<br />
+		if (tags-&gt;nr_free ||<br />
+		    alloc_global_tags(pool, tags) ||<br />
+		    steal_tags(pool, tags)) {<br />
+			/*<br />
+			 * Global lock held and irqs disabled, don't need percpu<br />
+			 * lock<br />
+			 */<br />
+			tag = tags-&gt;freelist[--tags-&gt;nr_free];<br />
+			if (tags-&gt;nr_free)<br />
+				set_bit(this_cpu, pool-&gt;cpus_have_tags);<br />
+		}<br />
+<br />
+		spin_unlock(&amp;pool-&gt;ida.lock);<br />
+		local_irq_restore(flags);<br />
+<br />
+		if (tag &gt;= 0 || !(gfp &amp; __GFP_WAIT))<br />
+			break;<br />
+<br />
+		schedule();<br />
+<br />
+		local_irq_save(flags);<br />
+		this_cpu = smp_processor_id();<br />
+		tags = per_cpu_ptr(pool-&gt;tag_cpu, this_cpu);<br />
+	}<br />
+<br />
+	finish_wait(&amp;pool-&gt;wait, &amp;wait);<br />
+	return tag;<br />
+}<br />
+EXPORT_SYMBOL_GPL(percpu_ida_alloc);<br />
+<br />
+/**<br />
+ * percpu_ida_free - free a tag<br />
+ * @pool: pool @tag was allocated from<br />
+ * @tag: a tag previously allocated with percpu_ida_alloc()<br />
+ *<br />
+ * Safe to be called from interrupt context.<br />
+ */<br />
+void percpu_ida_free(struct percpu_ida *pool, unsigned tag)<br />
+{<br />
+	struct percpu_ida_cpu *tags;<br />
+	unsigned long flags;<br />
+	unsigned nr_free, this_cpu;<br />
+<br />
+	BUG_ON(tag &gt;= pool-&gt;nr_tags);<br />
+<br />
+	local_irq_save(flags);<br />
+	this_cpu = smp_processor_id();<br />
+	tags = per_cpu_ptr(pool-&gt;tag_cpu, this_cpu);<br />
+<br />
+	spin_lock(&amp;tags-&gt;lock);<br />
+	nr_free = tags-&gt;nr_free;<br />
+	tags-&gt;freelist[tags-&gt;nr_free++] = tag;<br />
+	spin_unlock(&amp;tags-&gt;lock);<br />
+<br />
+	if (!nr_free) {<br />
+		set_bit(this_cpu, pool-&gt;cpus_have_tags);<br />
+		wake_up(&amp;pool-&gt;wait);<br />
+	}<br />
+<br />
+	if (nr_free + 1 == TAG_CPU_SIZE) {<br />
+		spin_lock(&amp;pool-&gt;ida.lock);<br />
+<br />
+		/*<br />
+		 * Global lock held and irqs disabled, don't need percpu<br />
+		 * lock<br />
+		 */<br />
+		while (tags-&gt;nr_free &gt; TAG_CPU_SIZE - TAG_CPU_BATCH_MOVE)<br />
+			__ida_remove(&amp;pool-&gt;ida,<br />
+				     tags-&gt;freelist[--tags-&gt;nr_free]);<br />
+<br />
+		wake_up(&amp;pool-&gt;wait);<br />
+		spin_unlock(&amp;pool-&gt;ida.lock);<br />
+	}<br />
+<br />
+	local_irq_restore(flags);<br />
+}<br />
+EXPORT_SYMBOL_GPL(percpu_ida_free);<br />
+<br />
+/**<br />
+ * percpu_ida_destroy - release a tag pool's resources<br />
+ * @pool: pool to free<br />
+ *<br />
+ * Frees the resources allocated by percpu_ida_init().<br />
+ */<br />
+void percpu_ida_destroy(struct percpu_ida *pool)<br />
+{<br />
+	free_percpu(pool-&gt;tag_cpu);<br />
+	kfree(pool-&gt;cpus_have_tags);<br />
+	ida_destroy(&amp;pool-&gt;ida);<br />
+}<br />
+EXPORT_SYMBOL_GPL(percpu_ida_destroy);<br />
+<br />
+/**<br />
+ * percpu_ida_init - initialize a percpu tag pool<br />
+ * @pool: pool to initialize<br />
+ * @nr_tags: number of tags that will be available for allocation<br />
+ *<br />
+ * Initializes @pool so that it can be used to allocate tags - integers in the<br />
+ * range [0, nr_tags). Typically, they'll be used by driver code to refer to a<br />
+ * preallocated array of tag structures.<br />
+ *<br />
+ * Allocation is percpu, but sharding is limited by nr_tags - for best<br />
+ * performance, the workload should not span more cpus than nr_tags / 128.<br />
+ */<br />
+int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags)<br />
+{<br />
+	unsigned cpu;<br />
+<br />
+	memset(pool, 0, sizeof(*pool));<br />
+<br />
+	init_waitqueue_head(&amp;pool-&gt;wait);<br />
+	pool-&gt;nr_tags = nr_tags;<br />
+<br />
+	/* Guard against overflow */<br />
+	if (nr_tags &gt; (unsigned) INT_MAX + 1) {<br />
+		pr_err(&quot;tags.c: nr_tags too large\n&quot;);<br />
+		return -EINVAL;<br />
+	}<br />
+<br />
+	if (ida_init_prealloc(&amp;pool-&gt;ida, nr_tags))<br />
+		return -ENOMEM;<br />
+<br />
+	pool-&gt;cpus_have_tags = kzalloc(BITS_TO_LONGS(nr_cpu_ids) *<br />
+				       sizeof(unsigned long), GFP_KERNEL);<br />
+	if (!pool-&gt;cpus_have_tags)<br />
+		goto err;<br />
+<br />
+	pool-&gt;tag_cpu = __alloc_percpu(sizeof(struct percpu_ida_cpu) +<br />
+				       TAG_CPU_SIZE * sizeof(unsigned),<br />
+				       sizeof(unsigned));<br />
+	if (!pool-&gt;tag_cpu)<br />
+		goto err;<br />
+<br />
+	for_each_possible_cpu(cpu)<br />
+		spin_lock_init(&amp;per_cpu_ptr(pool-&gt;tag_cpu, cpu)-&gt;lock);<br />
+<br />
+	return 0;<br />
+err:<br />
+	percpu_ida_destroy(pool);<br />
+	return -ENOMEM;<br />
+}<br />
+EXPORT_SYMBOL_GPL(percpu_ida_init);<br />
+<br />
 /* IDR */<br />
 <br />
 #define MAX_IDR_SHIFT		(sizeof(int) * 8 - 1)<br />
-- <br />
1.8.3.1<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Kent Overstreet</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727394,727394#msg-727394</guid>
            <title>[PATCH 3/4] idr: Rewrite ida (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727394,727394#msg-727394</link>
            <description><![CDATA[ This is a new, from scratch implementation of ida that should be<br />
simpler, faster and more space efficient.<br />
<br />
Two primary reasons for the rewrite:<br />
 * A future patch will reimplement idr on top of this ida implementation +<br />
   radix trees. Once that's done, the end result will be ~1k fewer lines<br />
   of code, much simpler and easier to understand and it should be quite<br />
   a bit faster.<br />
<br />
 * The performance improvements and addition of ganged allocation should<br />
   make ida more suitable for use by a percpu id/tag allocator, which<br />
   would then act as a frontend to this allocator.<br />
<br />
The old ida implementation was done with the idr data structures - this<br />
was IMO backwards. I'll soon be reimplementing idr on top of this new<br />
ida implementation and radix trees - using a separate dedicated data<br />
structure for the free ID bitmap should actually make idr faster, and<br />
the end result is _significantly_ less code.<br />
<br />
This implementation conceptually isn't that different from the old one -<br />
it's a tree of bitmaps, where one bit in a given node indicates whether<br />
or not there are free bits in a child node.<br />
<br />
The main difference (and advantage) over the old version is that the<br />
tree isn't implemented with pointers - it's implemented in an array,<br />
like how heaps are implemented, which both better space efficiency and<br />
it'll be faster since there's no pointer chasing.<br />
<br />
This does mean that the entire bitmap is stored in one contiguous memory<br />
allocation - and as currently implemented we won't be able to allocate<br />
_quite_ as many ids as with the previous implementation.<br />
<br />
I don't expect this to be an issue in practice since anywhere this is<br />
used, an id corresponds to a struct allocation somewher else - we can't<br />
allocate an unbounded number of ids, we'll run out of memory somewhere<br />
else eventually, and I expect that to be the limiting factor in<br />
practice.<br />
<br />
If a user/use case does come up where this matters I can add some<br />
sharding (or perhaps add a separate big_ida implementation) - but the<br />
extra complexity would adversely affect performance for the users that<br />
don't need &gt; millions of ids, so I intend to leave the implementation as<br />
is until if and when this becomes an issue.<br />
<br />
Signed-off-by: Kent Overstreet &lt;koverstreet@google.com&gt;<br />
Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;<br />
Cc: Tejun Heo &lt;tj@kernel.org&gt;<br />
Cc: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;<br />
Cc: Fengguang Wu &lt;fengguang.wu@intel.com&gt;<br />
---<br />
 include/linux/idr.h | 118 +++++---<br />
 lib/idr.c           | 776 +++++++++++++++++++++++++++++++++-------------------<br />
 2 files changed, 573 insertions(+), 321 deletions(-)<br />
<br />
diff --git a/include/linux/idr.h b/include/linux/idr.h<br />
index c0e0c54..9169e18 100644<br />
--- a/include/linux/idr.h<br />
+++ b/include/linux/idr.h<br />
@@ -17,6 +17,88 @@<br />
 #include &lt;linux/init.h&gt;<br />
 #include &lt;linux/rcupdate.h&gt;<br />
 <br />
+/* IDA */<br />
+<br />
+#define IDA_INLINE_NODES	4<br />
+<br />
+struct ida {<br />
+	spinlock_t		lock;<br />
+<br />
+	/*<br />
+	 * cur_id and allocated_ids are for ida_alloc_cyclic. For cyclic<br />
+	 * allocations we search for new ids to allocate starting from the last<br />
+	 * id allocated - cur_id is the next id to try allocating.<br />
+	 *<br />
+	 * But we also don't want the allocated ids to be arbitrarily sparse -<br />
+	 * the memory usage for the bitmap could be arbitrarily bad, and if<br />
+	 * they're used as keys in a radix tree the memory overhead of the radix<br />
+	 * tree could be quite bad as well. So we use allocated_ids to decide<br />
+	 * when to restart cur_id from 0, and bound how sparse the bitmap can<br />
+	 * be.<br />
+	 */<br />
+	unsigned		cur_id;<br />
+	unsigned		allocated_ids;<br />
+<br />
+	/* size of ida-&gt;tree */<br />
+	unsigned		nodes;<br />
+<br />
+	/*<br />
+	 * Index of first leaf node in ida-&gt;tree; equal to the number of non<br />
+	 * leaf nodes, ida-&gt;nodes - ida-&gt;first_leaf == number of leaf nodes<br />
+	 */<br />
+	unsigned		first_leaf;<br />
+<br />
+	unsigned long		*tree;<br />
+	unsigned long		inline_nodes[IDA_INLINE_NODES];<br />
+};<br />
+<br />
+#define IDA_INIT(name)						\<br />
+{								\<br />
+	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),	\<br />
+	.nodes		= IDA_INLINE_NODES,			\<br />
+	.first_leaf	= 1,					\<br />
+	.tree		= name.inline_nodes,			\<br />
+}<br />
+#define DEFINE_IDA(name)	struct ida name = IDA_INIT(name)<br />
+<br />
+void ida_remove(struct ida *ida, unsigned id);<br />
+int ida_alloc_range(struct ida *ida, unsigned int start,<br />
+		  unsigned int end, gfp_t gfp);<br />
+int ida_alloc_cyclic(struct ida *ida, unsigned start, unsigned end, gfp_t gfp);<br />
+void ida_destroy(struct ida *ida);<br />
+int ida_init_prealloc(struct ida *ida, unsigned prealloc);<br />
+<br />
+/**<br />
+ * ida_alloc_range - allocate a new id.<br />
+ * @ida: the (initialized) ida.<br />
+ * @gfp_mask: memory allocation flags<br />
+ *<br />
+ * Allocates an id in the range [0, INT_MAX]. Returns -ENOSPC if no ids are<br />
+ * available, or -ENOMEM on memory allocation failure.<br />
+ *<br />
+ * Returns the smallest available id<br />
+ *<br />
+ * Use ida_remove() to get rid of an id.<br />
+ */<br />
+static inline int ida_alloc(struct ida *ida, gfp_t gfp_mask)<br />
+{<br />
+	return ida_alloc_range(ida, 0, 0, gfp_mask);<br />
+}<br />
+<br />
+/**<br />
+ * ida_init - initialize ida handle<br />
+ * @ida:	ida handle<br />
+ *<br />
+ * This function is use to set up the handle (@ida) that you will pass<br />
+ * to the rest of the functions.<br />
+ */<br />
+static inline void ida_init(struct ida *ida)<br />
+{<br />
+	ida_init_prealloc(ida, 0);<br />
+}<br />
+<br />
+/* IDR */<br />
+<br />
 /*<br />
  * We want shallower trees and thus more bits covered at each layer.  8<br />
  * bits gives us large enough first layer for most use cases and maximum<br />
@@ -195,42 +277,6 @@ static inline void __deprecated idr_remove_all(struct idr *idp)<br />
 	__idr_remove_all(idp);<br />
 }<br />
 <br />
-/*<br />
- * IDA - IDR based id allocator, use when translation from id to<br />
- * pointer isn't necessary.<br />
- *<br />
- * IDA_BITMAP_LONGS is calculated to be one less to accommodate<br />
- * ida_bitmap-&gt;nr_busy so that the whole struct fits in 128 bytes.<br />
- */<br />
-#define IDA_CHUNK_SIZE		128	/* 128 bytes per chunk */<br />
-#define IDA_BITMAP_LONGS	(IDA_CHUNK_SIZE / sizeof(long) - 1)<br />
-#define IDA_BITMAP_BITS 	(IDA_BITMAP_LONGS * sizeof(long) * 8)<br />
-<br />
-struct ida_bitmap {<br />
-	long			nr_busy;<br />
-	unsigned long		bitmap[IDA_BITMAP_LONGS];<br />
-};<br />
-<br />
-struct ida {<br />
-	struct idr		idr;<br />
-	struct ida_bitmap	*free_bitmap;<br />
-};<br />
-<br />
-#define IDA_INIT(name)		{ .idr = IDR_INIT((name).idr), .free_bitmap = NULL, }<br />
-#define DEFINE_IDA(name)	struct ida name = IDA_INIT(name)<br />
-<br />
-void ida_destroy(struct ida *ida);<br />
-void ida_init(struct ida *ida);<br />
-<br />
-int ida_alloc_range(struct ida *ida, unsigned int start, unsigned int end,<br />
-		   gfp_t gfp_mask);<br />
-void ida_remove(struct ida *ida, unsigned int id);<br />
-<br />
-static inline int ida_alloc(struct ida *ida, gfp_t gfp_mask)<br />
-{<br />
-	return ida_alloc_range(ida, 0, 0, gfp_mask);<br />
-}<br />
-<br />
 void __init idr_init_cache(void);<br />
 <br />
 #endif /* __IDR_H__ */<br />
diff --git a/lib/idr.c b/lib/idr.c<br />
index df2d32e..7d89587 100644<br />
--- a/lib/idr.c<br />
+++ b/lib/idr.c<br />
@@ -8,6 +8,8 @@<br />
  *<br />
  * Modified by Nadia Derbey to make it RCU safe.<br />
  *<br />
+ * IDA completely rewritten by Kent Overstreet &lt;koverstreet@google.com&gt;<br />
+ *<br />
  * Small id to pointer translation service.<br />
  *<br />
  * It uses a radix tree like structure as a sparse array indexed<br />
@@ -38,6 +40,495 @@<br />
 #include &lt;linux/percpu.h&gt;<br />
 #include &lt;linux/hardirq.h&gt;<br />
 <br />
+#define IDA_TREE_ARY		BITS_PER_LONG<br />
+<br />
+/**<br />
+ * DOC: IDA description<br />
+ * IDA - ID (small integer) allocator<br />
+ *<br />
+ * This works much like using a simple bitmap to allocate indices - ida_alloc()<br />
+ * is equivalent to find_first_zero_bit() then __set_bit(), and ida_remove() is<br />
+ * equivalent to __clear_bit(). But it's much more efficient than a large<br />
+ * bitmap, and resizes itself as needed.<br />
+ *<br />
+ * It's implemented as a tree of bitmaps: a node in the tree is a single<br />
+ * unsigned long. The leaf nodes of the tree are segments of the entire bitmap -<br />
+ * a cleared bit indicates a free id, and a set bit indicates an allocated one.<br />
+ * Bits in the parent nodes indicate whether or not there are free bits in the<br />
+ * corresponding child node - when all the bits in a parent node are set, none<br />
+ * of its children have bits free.<br />
+ *<br />
+ * The splay factor of the tree (IDA_TREE_ARY) == BITS_PER_LONG - parent nodes<br />
+ * have 32 or 64 children.<br />
+ *<br />
+ * The tree itself is implemented with an array instead of pointers - exactly<br />
+ * like the textbook implementation of D-ary heaps. The root of the bitmap tree<br />
+ * is at ida-&gt;tree[0]. The children of node i are at i * IDA_TREE_ARY + 1 + j,<br />
+ * where j is in the range [0, 63], and the parent of node i is at (i - 1) /<br />
+ * IDA_TREE_ARY.<br />
+ *<br />
+ * This conveniently means that our leaf nodes are all contiguous in memory -<br />
+ * the bit for id i is bit id % BITS_PER_LONG in ida-&gt;tree[ida-&gt;first_leaf + i /<br />
+ * BITS_PER_LONG].<br />
+ *<br />
+ * Note that the number of ids we can allocate is limited by the amount of<br />
+ * memory we can contiguously allocate. The amount of memory used for the bitmap<br />
+ * tree is only slightly more than a flat bitmap would use - about 1 / TREE_ARY<br />
+ * * (sizeof flat bitmap).<br />
+ *<br />
+ * So for 1 mb of memory (and allocating more than that should be fine with<br />
+ * CONFIG_COMPACTION) you get slightly under 8 million IDs.<br />
+ */<br />
+<br />
+/*<br />
+ * For a given number of nodes, calculate how many are going to be parent nodes<br />
+ * (equal to ida-&gt;first_leaf) and by extension how my will be leaves.<br />
+ */<br />
+static unsigned first_leaf_from_nodes(unsigned nodes)<br />
+{<br />
+	unsigned ret = 0;<br />
+<br />
+	while (ret * IDA_TREE_ARY + 1 &lt; nodes)<br />
+		ret = ret * IDA_TREE_ARY + 1;<br />
+<br />
+	return ret;<br />
+}<br />
+<br />
+/*<br />
+ * Given some number of leaf nodes, calculate the number of parent nodes the<br />
+ * bitmap tree will require - i.e. the new ida-&gt;first_leaf<br />
+ */<br />
+static unsigned first_leaf_from_leaves(unsigned leaves)<br />
+{<br />
+	unsigned ret = 0;<br />
+<br />
+	while (ret * IDA_TREE_ARY + 1 &lt; ret + leaves)<br />
+		ret = ret * IDA_TREE_ARY + 1;<br />
+<br />
+	return ret;<br />
+}<br />
+<br />
+static void __ida_remove(struct ida *ida, unsigned int id)<br />
+{<br />
+	unsigned i = ida-&gt;first_leaf + id / BITS_PER_LONG;<br />
+	unsigned bit = id % BITS_PER_LONG;<br />
+<br />
+	BUG_ON(i &gt;= ida-&gt;nodes);<br />
+<br />
+	--ida-&gt;allocated_ids;<br />
+<br />
+	while (1) {<br />
+		unsigned long *node = ida-&gt;tree + i, old = *node;<br />
+<br />
+		WARN_ON(!test_bit(bit, node));<br />
+		__clear_bit(bit, node);<br />
+<br />
+		if (~old || !i)<br />
+			break;<br />
+<br />
+		/*<br />
+		 * If this node's bits were all 1s before we cleared this bit,<br />
+		 * we need to clear this node's bit in the parent node - and so<br />
+		 * on up to the root.<br />
+		 */<br />
+<br />
+		bit = (i - 1) % IDA_TREE_ARY;<br />
+		i = (i - 1) / IDA_TREE_ARY;<br />
+	}<br />
+}<br />
+<br />
+/**<br />
+ * ida_remove - remove an allocated id.<br />
+ * @ida: the (initialized) ida.<br />
+ * @id: the id returned by ida_alloc_range.<br />
+ */<br />
+void ida_remove(struct ida *ida, unsigned int id)<br />
+{<br />
+	unsigned long flags;<br />
+	spin_lock_irqsave(&amp;ida-&gt;lock, flags);<br />
+	__ida_remove(ida, id);<br />
+	spin_unlock_irqrestore(&amp;ida-&gt;lock, flags);<br />
+}<br />
+EXPORT_SYMBOL(ida_remove);<br />
+<br />
+static void ida_free_tree(unsigned long *tree, unsigned nodes)<br />
+{<br />
+	size_t bytes = nodes * sizeof(unsigned long);<br />
+<br />
+	if (bytes &lt; PAGE_SIZE)<br />
+		kfree(tree);<br />
+	else<br />
+		free_pages((unsigned long) tree,<br />
+			   get_order(bytes));<br />
+<br />
+}<br />
+<br />
+/*<br />
+ * Attempt to double the size of the tree. We have to drop ida-&gt;lock to allocate<br />
+ * memory, so we might race with another allocation that also tries to resize.<br />
+ * So if the tree's not the size it originally was when we retake ida-&gt;lock,<br />
+ * just return 0 - but the caller needs to recheck for the tree being full in<br />
+ * case we _really_ raced badly.<br />
+ */<br />
+static inline int __ida_resize(struct ida *ida, unsigned max_id,<br />
+			       gfp_t gfp, unsigned long *flags)<br />
+	__releases(&amp;ida-&gt;lock)<br />
+	__acquires(&amp;ida-&gt;lock)<br />
+{<br />
+	unsigned long *tree;<br />
+	unsigned old_nodes = ida-&gt;nodes;<br />
+	unsigned cur_leaves = ida-&gt;nodes - ida-&gt;first_leaf;<br />
+	unsigned new_nodes = roundup_pow_of_two(ida-&gt;nodes + 1);<br />
+	unsigned first_leaf = first_leaf_from_nodes(new_nodes);<br />
+	size_t bytes;<br />
+<br />
+	if (cur_leaves &gt;= BITS_TO_LONGS(max_id))<br />
+		return -ENOSPC;<br />
+<br />
+	spin_unlock_irqrestore(&amp;ida-&gt;lock, *flags);<br />
+<br />
+	bytes = new_nodes * sizeof(unsigned long);<br />
+<br />
+	tree = bytes &lt; PAGE_SIZE<br />
+		? kmalloc(bytes, gfp)<br />
+		: (void *) __get_free_pages(gfp, get_order(bytes));<br />
+<br />
+	spin_lock_irqsave(&amp;ida-&gt;lock, *flags);<br />
+<br />
+	if (!tree)<br />
+		return -ENOMEM;<br />
+<br />
+	if (old_nodes != ida-&gt;nodes) {<br />
+		ida_free_tree(tree, new_nodes);<br />
+		return 0;<br />
+	}<br />
+<br />
+	if (first_leaf == ida-&gt;first_leaf) {<br />
+		/* Depth doesn't change, just appending leaf nodes */<br />
+		memcpy(tree, ida-&gt;tree, ida-&gt;nodes * sizeof(unsigned long));<br />
+	} else {<br />
+		unsigned i, j, bit;<br />
+<br />
+		/* Zero out new parent nodes, reconstructing them below */<br />
+		memset(tree, 0, first_leaf * sizeof(unsigned long));<br />
+<br />
+		memcpy(tree + first_leaf,<br />
+		       ida-&gt;tree + ida-&gt;first_leaf,<br />
+		       cur_leaves * sizeof(unsigned long));<br />
+<br />
+		for (i = first_leaf; i &lt; first_leaf + cur_leaves; i++) {<br />
+			j = i;<br />
+<br />
+			while (!~tree[j] &amp;&amp; j) {<br />
+				bit = (j - 1) % IDA_TREE_ARY;<br />
+				j = (j - 1) / IDA_TREE_ARY;<br />
+<br />
+				__set_bit(bit, tree + j);<br />
+			}<br />
+		}<br />
+	}<br />
+<br />
+	/* Zero out new leaf nodes */<br />
+	memset(tree + first_leaf + cur_leaves, 0,<br />
+	       (new_nodes - first_leaf - cur_leaves) * sizeof(unsigned long));<br />
+<br />
+	if (ida-&gt;tree != ida-&gt;inline_nodes)<br />
+		ida_free_tree(ida-&gt;tree, ida-&gt;nodes);<br />
+<br />
+	ida-&gt;nodes	= new_nodes;<br />
+	ida-&gt;first_leaf = first_leaf;<br />
+	ida-&gt;tree	= tree;<br />
+<br />
+	return 0;<br />
+}<br />
+<br />
+/*<br />
+ * Ganged allocation - amortize locking and tree traversal for when we've got<br />
+ * another allocator (i.e. a percpu version) acting as a frontend to this code<br />
+ */<br />
+static int __ida_alloc_range_multiple(struct ida *ida, unsigned *ids,<br />
+				      unsigned nr_ids, unsigned min_id,<br />
+				      unsigned max_id, gfp_t gfp,<br />
+				      unsigned long *flags)<br />
+	__releases(&amp;ida-&gt;lock)<br />
+	__acquires(&amp;ida-&gt;lock)<br />
+{<br />
+	unsigned i = 0, bit, bit_offset, id, ids_found = 0;<br />
+	unsigned long *node = ida-&gt;tree;<br />
+	int err = 0;<br />
+<br />
+	if (!max_id)<br />
+		max_id = (unsigned) INT_MAX + 1;<br />
+<br />
+	if (min_id &gt;= max_id)<br />
+		return -ENOSPC;<br />
+<br />
+	while (ids_found &lt; nr_ids) {<br />
+		/*<br />
+		 * If all bits are set in the root, no bits free and we need to<br />
+		 * resize.<br />
+		 */<br />
+		while (!~*node) {<br />
+resize:<br />
+			err = __ida_resize(ida, max_id, gfp, flags);<br />
+			if (err)<br />
+				break;<br />
+<br />
+			i = 0;<br />
+			node = ida-&gt;tree;<br />
+		}<br />
+<br />
+		if (min_id) {<br />
+			/*<br />
+			 * If we're starting from a specific index, skip to that<br />
+			 * leaf node and start looking there:<br />
+			 */<br />
+			bit_offset = min_id % BITS_PER_LONG;<br />
+			i = ida-&gt;first_leaf + min_id / BITS_PER_LONG;<br />
+<br />
+			if (i &gt;= ida-&gt;nodes)<br />
+				goto resize;<br />
+<br />
+			while (1) {<br />
+				node = ida-&gt;tree + i;<br />
+				bit = ffz(*node &gt;&gt; bit_offset) + bit_offset;<br />
+<br />
+				/*<br />
+				 * We might have had to go back up the tree<br />
+				 * before we found a free bit - so skip down to<br />
+				 * where we recurse down the tree.<br />
+				 */<br />
+				if (~*node &amp;&amp; bit &lt; BITS_PER_LONG)<br />
+					goto found;<br />
+<br />
+				if (!i)<br />
+					goto resize;<br />
+<br />
+				/*<br />
+				 * Ok, no bits available in this node - go up a<br />
+				 * level. But we have to update bit_offset so we<br />
+				 * start searching in the parent _after_ the<br />
+				 * node we're currently at<br />
+				 */<br />
+				bit_offset = (i - 1) % IDA_TREE_ARY + 1;<br />
+				i = (i - 1) / IDA_TREE_ARY;<br />
+			}<br />
+		}<br />
+<br />
+		/*<br />
+		 * Recurse down the tree looking for a free bit. We already<br />
+		 * checked to make sure there _were_ free bits, but we might end<br />
+		 * up at a leaf node we haven't allocated yet.<br />
+		 */<br />
+		while (1) {<br />
+			bit = ffz(*node);<br />
+found:<br />
+			/*<br />
+			 * Found a bit - if we're at a leaf node, great! We're<br />
+			 * done:<br />
+			 */<br />
+			if (i &gt;= ida-&gt;first_leaf)<br />
+				break;<br />
+<br />
+			i = i * IDA_TREE_ARY + 1 + bit;<br />
+			node = ida-&gt;tree + i;<br />
+<br />
+			/*<br />
+			 * Recurse. But if we'd recurse to a node that hasn't<br />
+			 * been allocated yet, resize:<br />
+			 */<br />
+<br />
+			if (i &gt;= ida-&gt;nodes)<br />
+				goto resize;<br />
+<br />
+			BUG_ON(!~*node);<br />
+		}<br />
+<br />
+		/*<br />
+		 * Our leaves are contiguous, so we can calculate the id we<br />
+		 * allocated from the node we're at and the bit we found within<br />
+		 * that node:<br />
+		 */<br />
+		id = (i - ida-&gt;first_leaf) * BITS_PER_LONG + bit;<br />
+		BUG_ON(id &lt; min_id);<br />
+<br />
+		if (id &gt;= max_id) {<br />
+			err = -ENOSPC;<br />
+			break;<br />
+		}<br />
+<br />
+		ids[ids_found++] = id;<br />
+		ida-&gt;allocated_ids++;<br />
+<br />
+		/*<br />
+		 * Mark the id as allocated. If all the bits are now set in this<br />
+		 * node, set this node's bit in the parent node - and so on up<br />
+		 * to the root:<br />
+		 */<br />
+		while (1) {<br />
+			__set_bit(bit, node);<br />
+<br />
+			if (~*node || !i)<br />
+				break;<br />
+<br />
+			bit = (i - 1) % IDA_TREE_ARY;<br />
+			i = (i - 1) / IDA_TREE_ARY;<br />
+<br />
+			node = ida-&gt;tree + i;<br />
+		}<br />
+	}<br />
+<br />
+	return ids_found ? ids_found : err;<br />
+}<br />
+<br />
+/**<br />
+ * ida_alloc_range - allocate a new id.<br />
+ * @ida: the (initialized) ida.<br />
+ * @start: the minimum id (inclusive, &lt;= INT_MAX)<br />
+ * @end: the maximum id (exclusive, &lt;= INT_MAX + 1 or 0 for unlimited)<br />
+ * @gfp_mask: memory allocation flags<br />
+ *<br />
+ * Allocates an id in the range [start, end). Returns -ENOSPC if no ids are<br />
+ * available, or -ENOMEM on memory allocation failure.<br />
+ *<br />
+ * Returns the smallest free id &gt;= start.<br />
+ *<br />
+ * Use ida_remove() to get rid of an id.<br />
+ */<br />
+int ida_alloc_range(struct ida *ida, unsigned int start,<br />
+		    unsigned int end, gfp_t gfp)<br />
+{<br />
+	int ret;<br />
+	unsigned id;<br />
+	unsigned long flags;<br />
+<br />
+	spin_lock_irqsave(&amp;ida-&gt;lock, flags);<br />
+	ret = __ida_alloc_range_multiple(ida, &amp;id, 1, start, end, gfp, &amp;flags);<br />
+	spin_unlock_irqrestore(&amp;ida-&gt;lock, flags);<br />
+<br />
+	return ret == 1 ? id : ret;<br />
+}<br />
+EXPORT_SYMBOL(ida_alloc_range);<br />
+<br />
+static int __ida_alloc_cyclic(struct ida *ida, unsigned start, unsigned end,<br />
+			      gfp_t gfp, unsigned long *flags)<br />
+	__releases(&amp;ida-&gt;lock)<br />
+	__acquires(&amp;ida-&gt;lock)<br />
+{<br />
+	int ret;<br />
+	unsigned id;<br />
+<br />
+	ret = __ida_alloc_range_multiple(ida, &amp;id, 1,<br />
+					 max(start, ida-&gt;cur_id),<br />
+					 end, gfp, flags);<br />
+<br />
+	if (ret == -ENOSPC)<br />
+		ret = __ida_alloc_range_multiple(ida, &amp;id, 1, start,<br />
+						 end, gfp, flags);<br />
+	if (ret == 1) {<br />
+		ida-&gt;cur_id = id + 1;<br />
+		if ((ida-&gt;cur_id - start) / 2 &gt; max(1024U, ida-&gt;allocated_ids))<br />
+			ida-&gt;cur_id = 0;<br />
+<br />
+		return id;<br />
+	}<br />
+<br />
+	return ret;<br />
+}<br />
+<br />
+/**<br />
+ * ida_alloc_cyclic - allocate new ids cyclically<br />
+ * @ida: the (initialized) ida.<br />
+ * @start: the minimum id (inclusive, &lt;= INT_MAX)<br />
+ * @end: the maximum id (exclusive, &lt;= INT_MAX + 1 or 0 for unlimited)<br />
+ * @gfp_mask: memory allocation flags<br />
+ *<br />
+ * Allocates an id in the range start &lt;= id &lt; end, or returns -ENOSPC.<br />
+ * On memory allocation failure, returns -ENOMEM.<br />
+ *<br />
+ * Instead of returning the smallest free id, start searching from the position<br />
+ * where the last id was allocated - i.e. it won't reuse freed ids right away.<br />
+ *<br />
+ * To avoid the allocated id space (and internal bitmap) becoming arbitrarily<br />
+ * sparse, it can wrap before reaching the maximum id - if less than half of our<br />
+ * current id space is allocated, it resets cur_id to 0<br />
+ *<br />
+ * But we don't want to wrap when the id space is small, so we use the maximum<br />
+ * of (1024, allocated_ids) - see __ida_alloc_cyclic().<br />
+ *<br />
+ * Use ida_remove() to get rid of an id.<br />
+ */<br />
+int ida_alloc_cyclic(struct ida *ida, unsigned start, unsigned end, gfp_t gfp)<br />
+{<br />
+	int ret;<br />
+	unsigned long flags;<br />
+<br />
+	spin_lock_irqsave(&amp;ida-&gt;lock, flags);<br />
+	ret = __ida_alloc_cyclic(ida, start, end, gfp, &amp;flags);<br />
+	spin_unlock_irqrestore(&amp;ida-&gt;lock, flags);<br />
+<br />
+	return ret;<br />
+}<br />
+EXPORT_SYMBOL(ida_alloc_cyclic);<br />
+<br />
+/**<br />
+ * ida_destroy - release all cached layers within an ida tree<br />
+ * @ida:		ida handle<br />
+ */<br />
+void ida_destroy(struct ida *ida)<br />
+{<br />
+	if (ida-&gt;tree != ida-&gt;inline_nodes)<br />
+		ida_free_tree(ida-&gt;tree, ida-&gt;nodes);<br />
+}<br />
+EXPORT_SYMBOL(ida_destroy);<br />
+<br />
+/**<br />
+ * ida_init_prealloc - initialize ida handle<br />
+ * @ida:	ida handle<br />
+ * @prealloc:	number of ids to preallocate memory for<br />
+ *<br />
+ * Initialize an ida, and preallocate enough memory that ida_alloc() will never<br />
+ * return -ENOMEM if passed max_id &lt;= prealloc.<br />
+ */<br />
+int ida_init_prealloc(struct ida *ida, unsigned prealloc)<br />
+{<br />
+	memset(ida, 0, sizeof(*ida));<br />
+<br />
+	spin_lock_init(&amp;ida-&gt;lock);<br />
+<br />
+	ida-&gt;nodes	= IDA_INLINE_NODES;<br />
+	ida-&gt;first_leaf = 0;<br />
+	ida-&gt;tree	= ida-&gt;inline_nodes;<br />
+<br />
+	if (prealloc) {<br />
+		unsigned leaves = BITS_TO_LONGS(prealloc);<br />
+		unsigned first_leaf = first_leaf_from_leaves(leaves);<br />
+		unsigned nodes = first_leaf + leaves;<br />
+		size_t bytes;<br />
+<br />
+		if (nodes &gt; ida-&gt;nodes) {<br />
+			nodes = roundup_pow_of_two(nodes);<br />
+			bytes = nodes * sizeof(unsigned long);<br />
+<br />
+			ida-&gt;tree = bytes &lt; PAGE_SIZE<br />
+				? kzalloc(bytes, GFP_KERNEL)<br />
+				: (void *) __get_free_pages(GFP_KERNEL|__GFP_ZERO,<br />
+							    get_order(bytes));<br />
+			if (!ida-&gt;tree)<br />
+				return -ENOMEM;<br />
+<br />
+			ida-&gt;nodes = nodes;<br />
+			ida-&gt;first_leaf = first_leaf;<br />
+		}<br />
+	}<br />
+<br />
+	return 0;<br />
+<br />
+}<br />
+EXPORT_SYMBOL(ida_init_prealloc);<br />
+<br />
+/* IDR */<br />
+<br />
 #define MAX_IDR_SHIFT		(sizeof(int) * 8 - 1)<br />
 #define MAX_IDR_BIT		(1U &lt;&lt; MAX_IDR_SHIFT)<br />
 <br />
@@ -50,7 +541,6 @@<br />
 static struct kmem_cache *idr_layer_cache;<br />
 static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head);<br />
 static DEFINE_PER_CPU(int, idr_preload_cnt);<br />
-static DEFINE_SPINLOCK(simple_ida_lock);<br />
 <br />
 /* the maximum ID which can be allocated given idr-&gt;layers */<br />
 static int idr_max(int layers)<br />
@@ -870,287 +1360,3 @@ void idr_init(struct idr *idp)<br />
 	spin_lock_init(&amp;idp-&gt;lock);<br />
 }<br />
 EXPORT_SYMBOL(idr_init);<br />
-<br />
-<br />
-/**<br />
- * DOC: IDA description<br />
- * IDA - IDR based ID allocator<br />
- *<br />
- * This is id allocator without id -&gt; pointer translation.  Memory<br />
- * usage is much lower than full blown idr because each id only<br />
- * occupies a bit.  ida uses a custom leaf node which contains<br />
- * IDA_BITMAP_BITS slots.<br />
- *<br />
- * 2007-04-25  written by Tejun Heo &lt;htejun@gmail.com&gt;<br />
- */<br />
-<br />
-static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)<br />
-{<br />
-	unsigned long flags;<br />
-<br />
-	if (!ida-&gt;free_bitmap) {<br />
-		spin_lock_irqsave(&amp;ida-&gt;idr.lock, flags);<br />
-		if (!ida-&gt;free_bitmap) {<br />
-			ida-&gt;free_bitmap = bitmap;<br />
-			bitmap = NULL;<br />
-		}<br />
-		spin_unlock_irqrestore(&amp;ida-&gt;idr.lock, flags);<br />
-	}<br />
-<br />
-	kfree(bitmap);<br />
-}<br />
-<br />
-/**<br />
- * ida_pre_get - reserve resources for ida allocation<br />
- * @ida:	ida handle<br />
- * @gfp_mask:	memory allocation flag<br />
- *<br />
- * This function should be called prior to locking and calling the<br />
- * following function.  It preallocates enough memory to satisfy the<br />
- * worst possible allocation.<br />
- *<br />
- * If the system is REALLY out of memory this function returns %0,<br />
- * otherwise %1.<br />
- */<br />
-static int ida_pre_get(struct ida *ida, gfp_t gfp_mask)<br />
-{<br />
-	/* allocate idr_layers */<br />
-	if (!__idr_pre_get(&amp;ida-&gt;idr, gfp_mask))<br />
-		return 0;<br />
-<br />
-	/* allocate free_bitmap */<br />
-	if (!ida-&gt;free_bitmap) {<br />
-		struct ida_bitmap *bitmap;<br />
-<br />
-		bitmap = kmalloc(sizeof(struct ida_bitmap), gfp_mask);<br />
-		if (!bitmap)<br />
-			return 0;<br />
-<br />
-		free_bitmap(ida, bitmap);<br />
-	}<br />
-<br />
-	return 1;<br />
-}<br />
-<br />
-/**<br />
- * ida_get_new_above - allocate new ID above or equal to a start id<br />
- * @ida:	ida handle<br />
- * @starting_id: id to start search at<br />
- * @p_id:	pointer to the allocated handle<br />
- *<br />
- * Allocate new ID above or equal to @starting_id.  It should be called<br />
- * with any required locks.<br />
- *<br />
- * If memory is required, it will return %-EAGAIN, you should unlock<br />
- * and go back to the ida_pre_get() call.  If the ida is full, it will<br />
- * return %-ENOSPC.<br />
- *<br />
- * @p_id returns a value in the range @starting_id ... %0x7fffffff.<br />
- */<br />
-static int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)<br />
-{<br />
-	struct idr_layer *pa[MAX_IDR_LEVEL + 1];<br />
-	struct ida_bitmap *bitmap;<br />
-	unsigned long flags;<br />
-	int idr_id = starting_id / IDA_BITMAP_BITS;<br />
-	int offset = starting_id % IDA_BITMAP_BITS;<br />
-	int t, id;<br />
-<br />
- restart:<br />
-	/* get vacant slot */<br />
-	t = idr_get_empty_slot(&amp;ida-&gt;idr, idr_id, pa, 0, &amp;ida-&gt;idr);<br />
-	if (t &lt; 0)<br />
-		return t == -ENOMEM ? -EAGAIN : t;<br />
-<br />
-	if (t * IDA_BITMAP_BITS &gt;= MAX_IDR_BIT)<br />
-		return -ENOSPC;<br />
-<br />
-	if (t != idr_id)<br />
-		offset = 0;<br />
-	idr_id = t;<br />
-<br />
-	/* if bitmap isn't there, create a new one */<br />
-	bitmap = (void *)pa[0]-&gt;ary[idr_id &amp; IDR_MASK];<br />
-	if (!bitmap) {<br />
-		spin_lock_irqsave(&amp;ida-&gt;idr.lock, flags);<br />
-		bitmap = ida-&gt;free_bitmap;<br />
-		ida-&gt;free_bitmap = NULL;<br />
-		spin_unlock_irqrestore(&amp;ida-&gt;idr.lock, flags);<br />
-<br />
-		if (!bitmap)<br />
-			return -EAGAIN;<br />
-<br />
-		memset(bitmap, 0, sizeof(struct ida_bitmap));<br />
-		rcu_assign_pointer(pa[0]-&gt;ary[idr_id &amp; IDR_MASK],<br />
-				(void *)bitmap);<br />
-		pa[0]-&gt;count++;<br />
-	}<br />
-<br />
-	/* lookup for empty slot */<br />
-	t = find_next_zero_bit(bitmap-&gt;bitmap, IDA_BITMAP_BITS, offset);<br />
-	if (t == IDA_BITMAP_BITS) {<br />
-		/* no empty slot after offset, continue to the next chunk */<br />
-		idr_id++;<br />
-		offset = 0;<br />
-		goto restart;<br />
-	}<br />
-<br />
-	id = idr_id * IDA_BITMAP_BITS + t;<br />
-	if (id &gt;= MAX_IDR_BIT)<br />
-		return -ENOSPC;<br />
-<br />
-	__set_bit(t, bitmap-&gt;bitmap);<br />
-	if (++bitmap-&gt;nr_busy == IDA_BITMAP_BITS)<br />
-		idr_mark_full(pa, idr_id);<br />
-<br />
-	*p_id = id;<br />
-<br />
-	/* Each leaf node can handle nearly a thousand slots and the<br />
-	 * whole idea of ida is to have small memory foot print.<br />
-	 * Throw away extra resources one by one after each successful<br />
-	 * allocation.<br />
-	 */<br />
-	if (ida-&gt;idr.id_free_cnt || ida-&gt;free_bitmap) {<br />
-		struct idr_layer *p = get_from_free_list(&amp;ida-&gt;idr);<br />
-		if (p)<br />
-			kmem_cache_free(idr_layer_cache, p);<br />
-	}<br />
-<br />
-	return 0;<br />
-}<br />
-<br />
-static void __ida_remove(struct ida *ida, int id)<br />
-{<br />
-	struct idr_layer *p = ida-&gt;idr.top;<br />
-	int shift = (ida-&gt;idr.layers - 1) * IDR_BITS;<br />
-	int idr_id = id / IDA_BITMAP_BITS;<br />
-	int offset = id % IDA_BITMAP_BITS;<br />
-	int n;<br />
-	struct ida_bitmap *bitmap;<br />
-<br />
-	/* clear full bits while looking up the leaf idr_layer */<br />
-	while ((shift &gt; 0) &amp;&amp; p) {<br />
-		n = (idr_id &gt;&gt; shift) &amp; IDR_MASK;<br />
-		__clear_bit(n, p-&gt;bitmap);<br />
-		p = p-&gt;ary[n];<br />
-		shift -= IDR_BITS;<br />
-	}<br />
-<br />
-	if (p == NULL)<br />
-		goto err;<br />
-<br />
-	n = idr_id &amp; IDR_MASK;<br />
-	__clear_bit(n, p-&gt;bitmap);<br />
-<br />
-	bitmap = (void *)p-&gt;ary[n];<br />
-	if (!test_bit(offset, bitmap-&gt;bitmap))<br />
-		goto err;<br />
-<br />
-	/* update bitmap and remove it if empty */<br />
-	__clear_bit(offset, bitmap-&gt;bitmap);<br />
-	if (--bitmap-&gt;nr_busy == 0) {<br />
-		__set_bit(n, p-&gt;bitmap);	/* to please idr_remove() */<br />
-		idr_remove(&amp;ida-&gt;idr, idr_id);<br />
-		free_bitmap(ida, bitmap);<br />
-	}<br />
-<br />
-	return;<br />
-<br />
- err:<br />
-	printk(KERN_WARNING<br />
-	       &quot;ida_remove called for id=%d which is not allocated.\n&quot;, id);<br />
-}<br />
-<br />
-/**<br />
- * ida_destroy - release all cached layers within an ida tree<br />
- * @ida:		ida handle<br />
- */<br />
-void ida_destroy(struct ida *ida)<br />
-{<br />
-	idr_destroy(&amp;ida-&gt;idr);<br />
-	kfree(ida-&gt;free_bitmap);<br />
-}<br />
-EXPORT_SYMBOL(ida_destroy);<br />
-<br />
-/**<br />
- * ida_alloc_range - get a new id.<br />
- * @ida: the (initialized) ida.<br />
- * @start: the minimum id (inclusive, &lt; 0x8000000)<br />
- * @end: the maximum id (exclusive, &lt; 0x8000000 or 0)<br />
- * @gfp_mask: memory allocation flags<br />
- *<br />
- * Allocates an id in the range start &lt;= id &lt; end, or returns -ENOSPC.<br />
- * On memory allocation failure, returns -ENOMEM.<br />
- *<br />
- * Use ida_remove() to get rid of an id.<br />
- */<br />
-int ida_alloc_range(struct ida *ida, unsigned int start, unsigned int end,<br />
-		   gfp_t gfp_mask)<br />
-{<br />
-	int ret, id;<br />
-	unsigned int max;<br />
-	unsigned long flags;<br />
-<br />
-	BUG_ON((int)start &lt; 0);<br />
-	BUG_ON((int)end &lt; 0);<br />
-<br />
-	if (end == 0)<br />
-		max = 0x80000000;<br />
-	else {<br />
-		BUG_ON(end &lt; start);<br />
-		max = end - 1;<br />
-	}<br />
-<br />
-again:<br />
-	if (!ida_pre_get(ida, gfp_mask))<br />
-		return -ENOMEM;<br />
-<br />
-	spin_lock_irqsave(&amp;simple_ida_lock, flags);<br />
-	ret = ida_get_new_above(ida, start, &amp;id);<br />
-	if (!ret) {<br />
-		if (id &gt; max) {<br />
-			__ida_remove(ida, id);<br />
-			ret = -ENOSPC;<br />
-		} else {<br />
-			ret = id;<br />
-		}<br />
-	}<br />
-	spin_unlock_irqrestore(&amp;simple_ida_lock, flags);<br />
-<br />
-	if (unlikely(ret == -EAGAIN))<br />
-		goto again;<br />
-<br />
-	return ret;<br />
-}<br />
-EXPORT_SYMBOL(ida_alloc_range);<br />
-<br />
-/**<br />
- * ida_remove - remove an allocated id.<br />
- * @ida: the (initialized) ida.<br />
- * @id: the id returned by ida_alloc_range.<br />
- */<br />
-void ida_remove(struct ida *ida, unsigned int id)<br />
-{<br />
-	unsigned long flags;<br />
-<br />
-	BUG_ON((int)id &lt; 0);<br />
-	spin_lock_irqsave(&amp;simple_ida_lock, flags);<br />
-	__ida_remove(ida, id);<br />
-	spin_unlock_irqrestore(&amp;simple_ida_lock, flags);<br />
-}<br />
-EXPORT_SYMBOL(ida_remove);<br />
-<br />
-/**<br />
- * ida_init - initialize ida handle<br />
- * @ida:	ida handle<br />
- *<br />
- * This function is use to set up the handle (@ida) that you will pass<br />
- * to the rest of the functions.<br />
- */<br />
-void ida_init(struct ida *ida)<br />
-{<br />
-	memset(ida, 0, sizeof(struct ida));<br />
-	idr_init(&amp;ida-&gt;idr);<br />
-<br />
-}<br />
-EXPORT_SYMBOL(ida_init);<br />
-- <br />
1.8.3.1<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Kent Overstreet</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:20:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727392,727392#msg-727392</guid>
            <title>[PATCH] drivers: hv: switch to use mb() instead of smp_mb() (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727392,727392#msg-727392</link>
            <description><![CDATA[ Even if guest were compiled without SMP support, it could not assume that host<br />
wasn't. So switch to use mb() instead of smp_mb() to force memory barriers for<br />
UP guest.<br />
<br />
Cc: K. Y. Srinivasan &lt;kys@microsoft.com&gt;<br />
Cc: Haiyang Zhang &lt;haiyangz@microsoft.com&gt;<br />
Cc: <a href="mailto:&#115;&#116;&#97;&#98;&#108;&#101;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#115;&#116;&#97;&#98;&#108;&#101;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
Signed-off-by: Jason Wang &lt;jasowang@redhat.com&gt;<br />
---<br />
 drivers/hv/ring_buffer.c |   10 +++++-----<br />
 drivers/hv/vmbus_drv.c   |    2 +-<br />
 2 files changed, 6 insertions(+), 6 deletions(-)<br />
<br />
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c<br />
index d6fbb57..791f45d 100644<br />
--- a/drivers/hv/ring_buffer.c<br />
+++ b/drivers/hv/ring_buffer.c<br />
@@ -32,7 +32,7 @@<br />
 void hv_begin_read(struct hv_ring_buffer_info *rbi)<br />
 {<br />
 	rbi-&gt;ring_buffer-&gt;interrupt_mask = 1;<br />
-	smp_mb();<br />
+	mb();<br />
 }<br />
 <br />
 u32 hv_end_read(struct hv_ring_buffer_info *rbi)<br />
@@ -41,7 +41,7 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)<br />
 	u32 write;<br />
 <br />
 	rbi-&gt;ring_buffer-&gt;interrupt_mask = 0;<br />
-	smp_mb();<br />
+	mb();<br />
 <br />
 	/*<br />
 	 * Now check to see if the ring buffer is still empty.<br />
@@ -71,7 +71,7 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi)<br />
 <br />
 static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)<br />
 {<br />
-	smp_mb();<br />
+	mb();<br />
 	if (rbi-&gt;ring_buffer-&gt;interrupt_mask)<br />
 		return false;<br />
 <br />
@@ -442,7 +442,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,<br />
 					     sizeof(u64));<br />
 <br />
 	/* Issue a full memory barrier before updating the write index */<br />
-	smp_mb();<br />
+	mb();<br />
 <br />
 	/* Now, update the write location */<br />
 	hv_set_next_write_location(outring_info, next_write_location);<br />
@@ -549,7 +549,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,<br />
 	/* Make sure all reads are done before we update the read index since */<br />
 	/* the writer may start writing to the read area once the read index */<br />
 	/*is updated */<br />
-	smp_mb();<br />
+	mb();<br />
 <br />
 	/* Update the read index */<br />
 	hv_set_next_read_location(inring_info, next_read_location);<br />
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c<br />
index bf421e0..4004e54 100644<br />
--- a/drivers/hv/vmbus_drv.c<br />
+++ b/drivers/hv/vmbus_drv.c<br />
@@ -434,7 +434,7 @@ static void vmbus_on_msg_dpc(unsigned long data)<br />
 		 * will not deliver any more messages since there is<br />
 		 * no empty slot<br />
 		 */<br />
-		smp_mb();<br />
+		mb();<br />
 <br />
 		if (msg-&gt;header.message_flags.msg_pending) {<br />
 			/*<br />
-- <br />
1.7.1<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Jason Wang</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:20:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727390,727390#msg-727390</guid>
            <title>[RESEND PATCH v1 3/3] spi: s3c64xx: Added support for exynos5440 spi (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727390,727390#msg-727390</link>
            <description><![CDATA[ From: Girish K S &lt;girishks2000@gmail.com&gt;<br />
<br />
This patch adds support for the exynos5440 spi controller.<br />
The integration of the spi IP in exynos5440 is different from<br />
other SoC's. The I/O pins are no more configured via gpio, they<br />
have dedicated pins.<br />
<br />
Signed-off-by: Girish K S &lt;ks.giri@samsung.com&gt;<br />
---<br />
 drivers/spi/spi-s3c64xx.c |   12 ++++++++++++<br />
 1 files changed, 12 insertions(+), 0 deletions(-)<br />
<br />
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c<br />
index eaf9e1c..bd43888 100644<br />
--- a/drivers/spi/spi-s3c64xx.c<br />
+++ b/drivers/spi/spi-s3c64xx.c<br />
@@ -1608,6 +1608,15 @@ static struct s3c64xx_spi_port_config exynos4_spi_port_config = {<br />
 	.clk_from_cmu	= true,<br />
 };<br />
 <br />
+static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {<br />
+	.fifo_lvl_mask	= { 0x1ff },<br />
+	.rx_lvl_offset	= 15,<br />
+	.tx_st_done	= 25,<br />
+	.high_speed	= true,<br />
+	.clk_from_cmu	= true,<br />
+	.quirks		= S3C64XX_SPI_QUIRK_POLL,<br />
+};<br />
+<br />
 static struct platform_device_id s3c64xx_spi_driver_ids[] = {<br />
 	{<br />
 		.name		= &quot;s3c2443-spi&quot;,<br />
@@ -1636,6 +1645,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {<br />
 	{ .compatible = &quot;samsung,exynos4210-spi&quot;,<br />
 			.data = (void *)&amp;exynos4_spi_port_config,<br />
 	},<br />
+	{ .compatible = &quot;samsung,exynos5440-spi&quot;,<br />
+			.data = (void *)&amp;exynos5440_spi_port_config,<br />
+	},<br />
 	{ },<br />
 };<br />
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Anonymous User</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727389,727389#msg-727389</guid>
            <title>[RESEND PATCH v1 2/3] spi: s3c64xx: Added provision for dedicated cs pin (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727389,727389#msg-727389</link>
            <description><![CDATA[ From: Girish K S &lt;girishks2000@gmail.com&gt;<br />
<br />
The existing driver supports gpio based /cs signal.<br />
For controller's that have one device per controller,<br />
the slave device's /cs signal might be internally controlled<br />
by the chip select bit of slave select register. They are not<br />
externally asserted/deasserted using gpio pin.<br />
<br />
This patch adds support for controllers with dedicated /cs pin.<br />
if &quot;cs-gpio&quot; property doesnt exist in a spi dts node, the controller<br />
would treat the /cs pin as dedicated.<br />
<br />
Signed-off-by: Girish K S &lt;ks.giri@samsung.com&gt;<br />
---<br />
changes in v1:<br />
		Added the missing data structure that caused the<br />
compilation error<br />
<br />
 drivers/spi/spi-s3c64xx.c |   34 ++++++++++++++++++++++++++--------<br />
 1 files changed, 26 insertions(+), 8 deletions(-)<br />
<br />
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c<br />
index 0a80692..eaf9e1c 100644<br />
--- a/drivers/spi/spi-s3c64xx.c<br />
+++ b/drivers/spi/spi-s3c64xx.c<br />
@@ -208,6 +208,7 @@ struct s3c64xx_spi_driver_data {<br />
 	struct s3c64xx_spi_port_config	*port_conf;<br />
 	unsigned int			port_id;<br />
 	unsigned long			gpios[4];<br />
+	bool				cs_gpio;<br />
 };<br />
 <br />
 static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)<br />
@@ -570,14 +571,16 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,<br />
 		if (sdd-&gt;tgl_spi != spi) { /* if last mssg on diff device */<br />
 			/* Deselect the last toggled device */<br />
 			cs = sdd-&gt;tgl_spi-&gt;controller_data;<br />
-			gpio_set_value(cs-&gt;line,<br />
-				spi-&gt;mode &amp; SPI_CS_HIGH ? 0 : 1);<br />
+			if (sdd-&gt;cs_gpio)<br />
+				gpio_set_value(cs-&gt;line,<br />
+					spi-&gt;mode &amp; SPI_CS_HIGH ? 0 : 1);<br />
 		}<br />
 		sdd-&gt;tgl_spi = NULL;<br />
 	}<br />
 <br />
 	cs = spi-&gt;controller_data;<br />
-	gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 1 : 0);<br />
+	if (sdd-&gt;cs_gpio)<br />
+		gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 1 : 0);<br />
 <br />
 	/* Start the signals */<br />
 	writel(0, sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
@@ -709,7 +712,8 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,<br />
 	if (sdd-&gt;tgl_spi == spi)<br />
 		sdd-&gt;tgl_spi = NULL;<br />
 <br />
-	gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 0 : 1);<br />
+	if (sdd-&gt;cs_gpio)<br />
+		gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 0 : 1);<br />
 <br />
 	/* Quiese the signals */<br />
 	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
@@ -997,8 +1001,10 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(<br />
 {<br />
 	struct s3c64xx_spi_csinfo *cs;<br />
 	struct device_node *slave_np, *data_np = NULL;<br />
+	struct s3c64xx_spi_driver_data *sdd;<br />
 	u32 fb_delay = 0;<br />
 <br />
+	sdd = spi_master_get_devdata(spi-&gt;master);<br />
 	slave_np = spi-&gt;dev.of_node;<br />
 	if (!slave_np) {<br />
 		dev_err(&amp;spi-&gt;dev, &quot;device node not found\n&quot;);<br />
@@ -1018,7 +1024,10 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(<br />
 		return ERR_PTR(-ENOMEM);<br />
 	}<br />
 <br />
-	cs-&gt;line = of_get_named_gpio(data_np, &quot;cs-gpio&quot;, 0);<br />
+	/* The CS line is asserted/deasserted by the gpio pin */<br />
+	if (sdd-&gt;cs_gpio)<br />
+		cs-&gt;line = of_get_named_gpio(data_np, &quot;cs-gpio&quot;, 0);<br />
+<br />
 	if (!gpio_is_valid(cs-&gt;line)) {<br />
 		dev_err(&amp;spi-&gt;dev, &quot;chip select gpio is not specified or invalid\n&quot;);<br />
 		kfree(cs);<br />
@@ -1058,7 +1067,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)<br />
 		return -ENODEV;<br />
 	}<br />
 <br />
-	if (!spi_get_ctldata(spi)) {<br />
+	/* Request gpio only if cs line is asserted by gpio pins */<br />
+	if (sdd-&gt;cs_gpio) {<br />
 		err = gpio_request_one(cs-&gt;line, GPIOF_OUT_INIT_HIGH,<br />
 				       dev_name(&amp;spi-&gt;dev));<br />
 		if (err) {<br />
@@ -1067,9 +1077,11 @@ static int s3c64xx_spi_setup(struct spi_device *spi)<br />
 				cs-&gt;line, err);<br />
 			goto err_gpio_req;<br />
 		}<br />
-		spi_set_ctldata(spi, cs);<br />
 	}<br />
 <br />
+	if (!spi_get_ctldata(spi))<br />
+		spi_set_ctldata(spi, cs);<br />
+<br />
 	sci = sdd-&gt;cntrlr_info;<br />
 <br />
 	spin_lock_irqsave(&amp;sdd-&gt;lock, flags);<br />
@@ -1147,8 +1159,10 @@ err_gpio_req:<br />
 static void s3c64xx_spi_cleanup(struct spi_device *spi)<br />
 {<br />
 	struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);<br />
+	struct s3c64xx_spi_driver_data *sdd;<br />
 <br />
-	if (cs) {<br />
+	sdd = spi_master_get_devdata(spi-&gt;master);<br />
+	if (cs &amp;&amp; sdd-&gt;cs_gpio) {<br />
 		gpio_free(cs-&gt;line);<br />
 		if (spi-&gt;dev.of_node)<br />
 			kfree(cs);<br />
@@ -1325,7 +1339,11 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)<br />
 	sdd-&gt;cntrlr_info = sci;<br />
 	sdd-&gt;pdev = pdev;<br />
 	sdd-&gt;sfr_start = mem_res-&gt;start;<br />
+	sdd-&gt;cs_gpio = false;<br />
 	if (pdev-&gt;dev.of_node) {<br />
+		if (of_find_property(pdev-&gt;dev.of_node, &quot;cs-gpio&quot;, NULL))<br />
+			sdd-&gt;cs_gpio = true;<br />
+<br />
 		ret = of_alias_get_id(pdev-&gt;dev.of_node, &quot;spi&quot;);<br />
 		if (ret &lt; 0) {<br />
 			dev_err(&amp;pdev-&gt;dev, &quot;failed to get alias id, errno %d\n&quot;,<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Anonymous User</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727388,727388#msg-727388</guid>
            <title>[RESEND PATCH v1 0/3] Polling support for s3c64xx spi controller (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727388,727388#msg-727388</link>
            <description><![CDATA[ From: Girish K S &lt;ks.giri@samsung.com&gt;<br />
<br />
This patch series adds support for the polling mode only. Also 2nd patch<br />
in the series adds support for dedicated cs pin. After Thomas's patch for<br />
using default gpio is merged(commit id: 00ab539), one of the patch in this<br />
series is dropped and new series is generated.<br />
<br />
Girish K S (3):<br />
  spi: s3c64xx: added support for polling mode<br />
  spi: s3c64xx: Added provision for dedicated cs pin<br />
  spi: s3c64xx: Added support for exynos5440 spi<br />
<br />
 drivers/spi/spi-s3c64xx.c |  197 ++++++++++++++++++++++++++++++++-------------<br />
 1 files changed, 140 insertions(+), 57 deletions(-)<br />
<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Anonymous User</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727387,727387#msg-727387</guid>
            <title>[RESEND PATCH v1 1/3] spi: s3c64xx: added support for polling mode (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727387,727387#msg-727387</link>
            <description><![CDATA[ From: Girish K S &lt;girishks2000@gmail.com&gt;<br />
<br />
The 64xx spi driver supports partial polling mode.<br />
Only the last chunk of the transfer length is transferred<br />
or recieved in polling mode.<br />
<br />
Some SoC's that adopt this controller might not have have dma<br />
interface. This patch adds support for complete polling mode<br />
and gives flexibity for the user to select poll/dma mode.<br />
<br />
Signed-off-by: Girish K S &lt;ks.giri@samsung.com&gt;<br />
---<br />
changes in v1:<br />
		Addressed the performance issue reported by Mark Brown<br />
caused due to this patch. The wait_for_timeout function is modified to<br />
address this issue in dma mode.<br />
<br />
 drivers/spi/spi-s3c64xx.c |  153 ++++++++++++++++++++++++++++++--------------<br />
 1 files changed, 104 insertions(+), 49 deletions(-)<br />
<br />
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c<br />
index 5000586..0a80692 100644<br />
--- a/drivers/spi/spi-s3c64xx.c<br />
+++ b/drivers/spi/spi-s3c64xx.c<br />
@@ -39,6 +39,7 @@<br />
 #endif<br />
 <br />
 #define MAX_SPI_PORTS		3<br />
+#define S3C64XX_SPI_QUIRK_POLL		(1 &lt;&lt; 0)<br />
 <br />
 /* Registers and bit-fields */<br />
 <br />
@@ -130,6 +131,7 @@<br />
 #define S3C64XX_SPI_TRAILCNT		S3C64XX_SPI_MAX_TRAILCNT<br />
 <br />
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)<br />
+#define is_polling(x)	(x-&gt;port_conf-&gt;quirks &amp; S3C64XX_SPI_QUIRK_POLL)<br />
 <br />
 #define RXBUSY    (1&lt;&lt;2)<br />
 #define TXBUSY    (1&lt;&lt;3)<br />
@@ -158,6 +160,7 @@ struct s3c64xx_spi_port_config {<br />
 	int	fifo_lvl_mask[MAX_SPI_PORTS];<br />
 	int	rx_lvl_offset;<br />
 	int	tx_st_done;<br />
+	int	quirks;<br />
 	bool	high_speed;<br />
 	bool	clk_from_cmu;<br />
 };<br />
@@ -344,8 +347,12 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)<br />
 {<br />
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);<br />
 <br />
-	/* Acquire DMA channels */<br />
-	while (!acquire_dma(sdd))<br />
+	/*<br />
+	 * If DMA resource was not available during<br />
+	 * probe, no need to continue with dma requests<br />
+	 * else Acquire DMA channels<br />
+	 */<br />
+	while (!is_polling(sdd) &amp;&amp; !acquire_dma(sdd))<br />
 		usleep_range(10000, 11000);<br />
 <br />
 	pm_runtime_get_sync(&amp;sdd-&gt;pdev-&gt;dev);<br />
@@ -358,9 +365,12 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)<br />
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);<br />
 <br />
 	/* Free DMA channels */<br />
-	sdd-&gt;ops-&gt;release((enum dma_ch)sdd-&gt;rx_dma.ch, &amp;s3c64xx_spi_dma_client);<br />
-	sdd-&gt;ops-&gt;release((enum dma_ch)sdd-&gt;tx_dma.ch, &amp;s3c64xx_spi_dma_client);<br />
-<br />
+	if (!is_polling(sdd)) {<br />
+		sdd-&gt;ops-&gt;release((enum dma_ch)sdd-&gt;rx_dma.ch,<br />
+					&amp;s3c64xx_spi_dma_client);<br />
+		sdd-&gt;ops-&gt;release((enum dma_ch)sdd-&gt;tx_dma.ch,<br />
+					&amp;s3c64xx_spi_dma_client);<br />
+	}<br />
 	pm_runtime_put(&amp;sdd-&gt;pdev-&gt;dev);<br />
 <br />
 	return 0;<br />
@@ -464,8 +474,10 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)<br />
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);<br />
 <br />
 	/* Free DMA channels */<br />
-	dma_release_channel(sdd-&gt;rx_dma.ch);<br />
-	dma_release_channel(sdd-&gt;tx_dma.ch);<br />
+	if (!is_polling(sdd)) {<br />
+		dma_release_channel(sdd-&gt;rx_dma.ch);<br />
+		dma_release_channel(sdd-&gt;tx_dma.ch);<br />
+	}<br />
 <br />
 	pm_runtime_put(&amp;sdd-&gt;pdev-&gt;dev);<br />
 	return 0;<br />
@@ -566,6 +578,30 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,<br />
 <br />
 	cs = spi-&gt;controller_data;<br />
 	gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 1 : 0);<br />
+<br />
+	/* Start the signals */<br />
+	writel(0, sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
+}<br />
+<br />
+static u32 wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,<br />
+					int timeout_ms)<br />
+{<br />
+	void __iomem *regs = sdd-&gt;regs;<br />
+	unsigned long val = 1;<br />
+	u32 status;<br />
+<br />
+	/* max fifo depth available */<br />
+	u32 max_fifo = (FIFO_LVL_MASK(sdd) &gt;&gt; 1) + 1;<br />
+<br />
+	if (timeout_ms)<br />
+		val = msecs_to_loops(timeout_ms);<br />
+<br />
+	do {<br />
+		status = readl(regs + S3C64XX_SPI_STATUS);<br />
+	} while (RX_FIFO_LVL(status, sdd) &lt; max_fifo &amp;&amp; --val);<br />
+<br />
+	/* return the actual received data length */<br />
+	return RX_FIFO_LVL(status, sdd);<br />
 }<br />
 <br />
 static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,<br />
@@ -590,20 +626,19 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,<br />
 		} while (RX_FIFO_LVL(status, sdd) &lt; xfer-&gt;len &amp;&amp; --val);<br />
 	}<br />
 <br />
-	if (!val)<br />
-		return -EIO;<br />
-<br />
 	if (dma_mode) {<br />
 		u32 status;<br />
 <br />
 		/*<br />
+		 * If the previous xfer was completed within timeout, then<br />
+		 * proceed further else return -EIO.<br />
 		 * DmaTx returns after simply writing data in the FIFO,<br />
 		 * w/o waiting for real transmission on the bus to finish.<br />
 		 * DmaRx returns only after Dma read data from FIFO which<br />
 		 * needs bus transmission to finish, so we don't worry if<br />
 		 * Xfer involved Rx(with or without Tx).<br />
 		 */<br />
-		if (xfer-&gt;rx_buf == NULL) {<br />
+		if (val &amp;&amp; !xfer-&gt;rx_buf) {<br />
 			val = msecs_to_loops(10);<br />
 			status = readl(regs + S3C64XX_SPI_STATUS);<br />
 			while ((TX_FIFO_LVL(status, sdd)<br />
@@ -613,30 +648,53 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,<br />
 				status = readl(regs + S3C64XX_SPI_STATUS);<br />
 			}<br />
 <br />
-			if (!val)<br />
-				return -EIO;<br />
 		}<br />
+<br />
+		/* If timed out while checking rx/tx status return error */<br />
+		if (!val)<br />
+			return -EIO;<br />
 	} else {<br />
+		int loops;<br />
+		u32 cpy_len;<br />
+		u8 *buf;<br />
+<br />
 		/* If it was only Tx */<br />
-		if (xfer-&gt;rx_buf == NULL) {<br />
+		if (!xfer-&gt;rx_buf) {<br />
 			sdd-&gt;state &amp;= ~TXBUSY;<br />
 			return 0;<br />
 		}<br />
 <br />
-		switch (sdd-&gt;cur_bpw) {<br />
-		case 32:<br />
-			ioread32_rep(regs + S3C64XX_SPI_RX_DATA,<br />
-				xfer-&gt;rx_buf, xfer-&gt;len / 4);<br />
-			break;<br />
-		case 16:<br />
-			ioread16_rep(regs + S3C64XX_SPI_RX_DATA,<br />
-				xfer-&gt;rx_buf, xfer-&gt;len / 2);<br />
-			break;<br />
-		default:<br />
-			ioread8_rep(regs + S3C64XX_SPI_RX_DATA,<br />
-				xfer-&gt;rx_buf, xfer-&gt;len);<br />
-			break;<br />
-		}<br />
+		/*<br />
+		 * If the receive length is bigger than the controller fifo<br />
+		 * size, calculate the loops and read the fifo as many times.<br />
+		 * loops = length / max fifo size (calculated by using the<br />
+		 * fifo mask).<br />
+		 * For any size less than the fifo size the below code is<br />
+		 * executed atleast once.<br />
+		 */<br />
+		loops = xfer-&gt;len / ((FIFO_LVL_MASK(sdd) &gt;&gt; 1) + 1);<br />
+		buf = xfer-&gt;rx_buf;<br />
+		do {<br />
+			/* wait for data to be received in the fifo */<br />
+			cpy_len = wait_for_timeout(sdd, (loops ? ms : 0));<br />
+<br />
+			switch (sdd-&gt;cur_bpw) {<br />
+			case 32:<br />
+				ioread32_rep(regs + S3C64XX_SPI_RX_DATA,<br />
+					buf, cpy_len / 4);<br />
+				break;<br />
+			case 16:<br />
+				ioread16_rep(regs + S3C64XX_SPI_RX_DATA,<br />
+					buf, cpy_len / 2);<br />
+				break;<br />
+			default:<br />
+				ioread8_rep(regs + S3C64XX_SPI_RX_DATA,<br />
+					buf, cpy_len);<br />
+				break;<br />
+			}<br />
+<br />
+			buf = buf + cpy_len;<br />
+		} while (loops--);<br />
 		sdd-&gt;state &amp;= ~RXBUSY;<br />
 	}<br />
 <br />
@@ -652,6 +710,9 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,<br />
 		sdd-&gt;tgl_spi = NULL;<br />
 <br />
 	gpio_set_value(cs-&gt;line, spi-&gt;mode &amp; SPI_CS_HIGH ? 0 : 1);<br />
+<br />
+	/* Quiese the signals */<br />
+	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
 }<br />
 <br />
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)<br />
@@ -733,7 +794,7 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,<br />
 	struct device *dev = &amp;sdd-&gt;pdev-&gt;dev;<br />
 	struct spi_transfer *xfer;<br />
 <br />
-	if (msg-&gt;is_dma_mapped)<br />
+	if (is_polling(sdd) || msg-&gt;is_dma_mapped)<br />
 		return 0;<br />
 <br />
 	/* First mark all xfer unmapped */<br />
@@ -782,7 +843,7 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,<br />
 	struct device *dev = &amp;sdd-&gt;pdev-&gt;dev;<br />
 	struct spi_transfer *xfer;<br />
 <br />
-	if (msg-&gt;is_dma_mapped)<br />
+	if (is_polling(sdd) || msg-&gt;is_dma_mapped)<br />
 		return;<br />
 <br />
 	list_for_each_entry(xfer, &amp;msg-&gt;transfers, transfer_list) {<br />
@@ -861,8 +922,9 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,<br />
 <br />
 		/* Polling method for xfers not bigger than FIFO capacity */<br />
 		use_dma = 0;<br />
-		if (sdd-&gt;rx_dma.ch &amp;&amp; sdd-&gt;tx_dma.ch &amp;&amp;<br />
-		    (xfer-&gt;len &gt; ((FIFO_LVL_MASK(sdd) &gt;&gt; 1) + 1)))<br />
+		if (!is_polling(sdd) &amp;&amp;<br />
+			(sdd-&gt;rx_dma.ch &amp;&amp; sdd-&gt;tx_dma.ch &amp;&amp;<br />
+			(xfer-&gt;len &gt; ((FIFO_LVL_MASK(sdd) &gt;&gt; 1) + 1))))<br />
 			use_dma = 1;<br />
 <br />
 		spin_lock_irqsave(&amp;sdd-&gt;lock, flags);<br />
@@ -876,17 +938,10 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,<br />
 		/* Slave Select */<br />
 		enable_cs(sdd, spi);<br />
 <br />
-		/* Start the signals */<br />
-		writel(0, sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
-<br />
 		spin_unlock_irqrestore(&amp;sdd-&gt;lock, flags);<br />
 <br />
 		status = wait_for_xfer(sdd, xfer, use_dma);<br />
 <br />
-		/* Quiese the signals */<br />
-		writel(S3C64XX_SPI_SLAVE_SIG_INACT,<br />
-		       sdd-&gt;regs + S3C64XX_SPI_SLAVE_SEL);<br />
-<br />
 		if (status) {<br />
 			dev_err(&amp;spi-&gt;dev, &quot;I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n&quot;,<br />
 				xfer-&gt;rx_buf ? 1 : 0, xfer-&gt;tx_buf ? 1 : 0,<br />
@@ -1287,19 +1342,19 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)<br />
 	if (!sdd-&gt;pdev-&gt;dev.of_node) {<br />
 		res = platform_get_resource(pdev, IORESOURCE_DMA,  0);<br />
 		if (!res) {<br />
-			dev_err(&amp;pdev-&gt;dev, &quot;Unable to get SPI tx dma &quot;<br />
-					&quot;resource\n&quot;);<br />
-			return -ENXIO;<br />
-		}<br />
-		sdd-&gt;tx_dma.dmach = res-&gt;start;<br />
+			dev_warn(&amp;pdev-&gt;dev, &quot;Unable to get SPI tx dma &quot;<br />
+					&quot;resource. Switching to poll mode\n&quot;);<br />
+			sdd-&gt;port_conf-&gt;quirks = S3C64XX_SPI_QUIRK_POLL;<br />
+		} else<br />
+			sdd-&gt;tx_dma.dmach = res-&gt;start;<br />
 <br />
 		res = platform_get_resource(pdev, IORESOURCE_DMA,  1);<br />
 		if (!res) {<br />
-			dev_err(&amp;pdev-&gt;dev, &quot;Unable to get SPI rx dma &quot;<br />
-					&quot;resource\n&quot;);<br />
-			return -ENXIO;<br />
-		}<br />
-		sdd-&gt;rx_dma.dmach = res-&gt;start;<br />
+			dev_warn(&amp;pdev-&gt;dev, &quot;Unable to get SPI rx dma &quot;<br />
+					&quot;resource. Switching to poll mode\n&quot;);<br />
+			sdd-&gt;port_conf-&gt;quirks = S3C64XX_SPI_QUIRK_POLL;<br />
+		} else<br />
+			sdd-&gt;rx_dma.dmach = res-&gt;start;<br />
 	}<br />
 <br />
 	sdd-&gt;tx_dma.direction = DMA_MEM_TO_DEV;<br />
-- <br />
1.7.5.4<br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Anonymous User</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:10:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727385,727385#msg-727385</guid>
            <title>linux-next: manual merge of the staging tree with the usb tree (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727385,727385#msg-727385</link>
            <description><![CDATA[ Hi Greg,<br />
<br />
Today's linux-next merge of the staging tree got a conflict in<br />
drivers/staging/serqt_usb2/serqt_usb2.c between commit 1143832eca8f<br />
(&quot;USB: serial: ports: add minor and port number&quot;) from the usb tree and<br />
commit d68edc2881b1 (&quot;staging: serqt_usb2: Fixed coding style<br />
CamelCases&quot;) from the staging tree.<br />
<br />
I fixed it up (see below) and can carry the fix as necessary (no action<br />
is required).<br />
<br />
-- <br />
Cheers,<br />
Stephen Rothwell                    <a href="mailto:&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;">&#115;&#102;&#114;&#64;&#99;&#97;&#110;&#98;&#46;&#97;&#117;&#117;&#103;&#46;&#111;&#114;&#103;&#46;&#97;&#117;</a><br />
<br />
diff --cc drivers/staging/serqt_usb2/serqt_usb2.c<br />
index 880f5c0,39de5e0..0000000<br />
--- a/drivers/staging/serqt_usb2/serqt_usb2.c<br />
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c<br />
@@@ -870,10 -870,10 +870,10 @@@ static int qt_open(struct tty_struct *t<br />
  	usb_clear_halt(serial-&gt;dev, port-&gt;read_urb-&gt;pipe);<br />
  	port0-&gt;open_ports++;<br />
  <br />
- 	result = qt_get_device(serial, &amp;port0-&gt;DeviceData);<br />
+ 	result = qt_get_device(serial, &amp;port0-&gt;device_data);<br />
  <br />
  	/* Port specific setups */<br />
- 	result = qt_open_channel(serial, port-&gt;port_number, &amp;ChannelData);<br />
 -	result = qt_open_channel(serial, port-&gt;number, &amp;channel_data);<br />
++	result = qt_open_channel(serial, port-&gt;port_number, &amp;channel_data);<br />
  	if (result &lt; 0) {<br />
  		dev_dbg(&amp;port-&gt;dev, &quot;qt_open_channel failed\n&quot;);<br />
  		return result;<br />
@@@ -1239,23 -1245,25 +1239,23 @@@ static void qt_set_termios(struct tty_s<br />
  <br />
  	/* Now determine flow control */<br />
  	if (cflag &amp; CRTSCTS) {<br />
 -		dev_dbg(&amp;port-&gt;dev, &quot;%s - Enabling HW flow control port %d\n&quot;,<br />
 -			__func__, port-&gt;number);<br />
 +		dev_dbg(&amp;port-&gt;dev, &quot;%s - Enabling HW flow control\n&quot;, __func__);<br />
  <br />
  		/* Enable RTS/CTS flow control */<br />
- 		status = BoxSetHW_FlowCtrl(port-&gt;serial, index, 1);<br />
+ 		status = box_set_hw_flow_ctrl(port-&gt;serial, index, 1);<br />
  <br />
  		if (status &lt; 0) {<br />
- 			dev_dbg(&amp;port-&gt;dev, &quot;BoxSetHW_FlowCtrl failed\n&quot;);<br />
+ 			dev_dbg(&amp;port-&gt;dev, &quot;box_set_hw_flow_ctrl failed\n&quot;);<br />
  			return;<br />
  		}<br />
  	} else {<br />
  		/* Disable RTS/CTS flow control */<br />
  		dev_dbg(&amp;port-&gt;dev,<br />
 -			&quot;%s - disabling HW flow control port %d\n&quot;,<br />
 -			__func__, port-&gt;number);<br />
 +			&quot;%s - disabling HW flow control\n&quot;, __func__);<br />
  <br />
- 		status = BoxSetHW_FlowCtrl(port-&gt;serial, index, 0);<br />
+ 		status = box_set_hw_flow_ctrl(port-&gt;serial, index, 0);<br />
  		if (status &lt; 0) {<br />
- 			dev_dbg(&amp;port-&gt;dev, &quot;BoxSetHW_FlowCtrl failed\n&quot;);<br />
+ 			dev_dbg(&amp;port-&gt;dev, &quot;box_set_hw_flow_ctrl failed\n&quot;);<br />
  			return;<br />
  		}<br />
  <br />
@@@ -1324,12 -1332,12 +1324,12 @@@ static inline int qt_real_tiocmget(stru<br />
  	int status;<br />
  	unsigned int index;<br />
  <br />
 -	index = tty-&gt;index - serial-&gt;minor;<br />
 +	index = port-&gt;port_number;<br />
  	status =<br />
- 	    BoxGetRegister(port-&gt;serial, index, MODEM_CONTROL_REGISTER, &amp;mcr);<br />
+ 	    box_get_register(port-&gt;serial, index, MODEM_CONTROL_REGISTER, &amp;mcr);<br />
  	if (status &gt;= 0) {<br />
  		status =<br />
- 		    BoxGetRegister(port-&gt;serial, index,<br />
+ 		    box_get_register(port-&gt;serial, index,<br />
  				   MODEM_STATUS_REGISTER, &amp;msr);<br />
  <br />
  	}<br />
@@@ -1363,9 -1371,9 +1363,9 @@@ static inline int qt_real_tiocmset(stru<br />
  	int status;<br />
  	unsigned int index;<br />
  <br />
 -	index = tty-&gt;index - serial-&gt;minor;<br />
 +	index = port-&gt;port_number;<br />
  	status =<br />
- 	    BoxGetRegister(port-&gt;serial, index, MODEM_CONTROL_REGISTER, &amp;mcr);<br />
+ 	    box_get_register(port-&gt;serial, index, MODEM_CONTROL_REGISTER, &amp;mcr);<br />
  	if (status &lt; 0)<br />
  		return -ESPIPE;]]></description>
            <dc:creator>Stephen Rothwell</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 07:00:03 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727377,727377#msg-727377</guid>
            <title>[PATCH] input/joystick: Fix for xpad driver support of &quot;Mad Catz Street Fighter IV FightPad&quot; controllers (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727377,727377#msg-727377</link>
            <description><![CDATA[ From: shawn joseph &lt;jms.576@gmail.com&gt;<br />
<br />
Added MAP_TRIGGERS_TO_BUTTONS for Mad Catz Street Fighter IV FightPad<br />
device. This controller model was already supported by the xpad<br />
driver, but none of the buttons work correctly without this change.<br />
Tested on kernel version 3.9.5.<br />
Signed-off-by: shawn joseph &lt;jms.576@gmail.com&gt;<br />
---<br />
--- linux-3.9.5/drivers/input/<br />
joystick/xpad.c.orig      2013-06-16 15:09:47.974170141 -0400<br />
+++ linux-3.9.5/drivers/input/joystick/xpad.c   2013-06-16<br />
15:10:24.070611282 -0400<br />
@@ -137,7 +137,7 @@ static const struct xpad_device {<br />
        { 0x0738, 0x4540, &quot;Mad Catz Beat Pad&quot;, MAP_DPAD_TO_BUTTONS,<br />
XTYPE_XBOX },<br />
        { 0x0738, 0x4556, &quot;Mad Catz Lynx Wireless Controller&quot;, 0, XTYPE_XBOX },<br />
        { 0x0738, 0x4716, &quot;Mad Catz Wired Xbox 360 Controller&quot;, 0,<br />
XTYPE_XBOX360 },<br />
-       { 0x0738, 0x4728, &quot;Mad Catz Street Fighter IV FightPad&quot;,<br />
XTYPE_XBOX360 },<br />
+       { 0x0738, 0x4728, &quot;Mad Catz Street Fighter IV FightPad&quot;,<br />
MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },<br />
        { 0x0738, 0x4738, &quot;Mad Catz Wired Xbox 360 Controller (SFIV)&quot;,<br />
MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },<br />
        { 0x0738, 0x6040, &quot;Mad Catz Beat Pad Pro&quot;,<br />
MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },<br />
        { 0x0738, 0xbeef, &quot;Mad Catz JOYTECH NEO SE Advanced GamePad&quot;,<br />
XTYPE_XBOX360 },<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Shawn</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 06:40:01 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727374,727374#msg-727374</guid>
            <title>[PATCH -next] pinctrl: core: fix missing unlock on error in pinctrl_find_gpio_range_from_pin() (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727374,727374#msg-727374</link>
            <description><![CDATA[ From: Wei Yongjun &lt;yongjun_wei@trendmicro.com.cn&gt;<br />
<br />
Add the missing unlock before return from function pinctrl_find_gpio_range_from_pin()<br />
in the error handling case.<br />
<br />
Introduced by commit 2ff3477efd7086544b9e298fc63afab0645921b4.<br />
(pinctrl: add pin list based GPIO ranges)<br />
<br />
Signed-off-by: Wei Yongjun &lt;yongjun_wei@trendmicro.com.cn&gt;<br />
---<br />
 drivers/pinctrl/core.c | 15 +++++++--------<br />
 1 file changed, 7 insertions(+), 8 deletions(-)<br />
<br />
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c<br />
index 33710b5..28a3f7b 100644<br />
--- a/drivers/pinctrl/core.c<br />
+++ b/drivers/pinctrl/core.c<br />
@@ -465,7 +465,7 @@ struct pinctrl_gpio_range *<br />
 pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,<br />
 				 unsigned int pin)<br />
 {<br />
-	struct pinctrl_gpio_range *range = NULL;<br />
+	struct pinctrl_gpio_range *range;<br />
 <br />
 	mutex_lock(&amp;pctldev-&gt;mutex);<br />
 	/* Loop over the ranges */<br />
@@ -475,17 +475,16 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,<br />
 			int a;<br />
 			for (a = 0; a &lt; range-&gt;npins; a++) {<br />
 				if (range-&gt;pins[a] == pin)<br />
-					return range;<br />
+					goto out;<br />
 			}<br />
 		} else if (pin &gt;= range-&gt;pin_base &amp;&amp;<br />
-			   pin &lt; range-&gt;pin_base + range-&gt;npins) {<br />
-			mutex_unlock(&amp;pctldev-&gt;mutex);<br />
-			return range;<br />
-		}<br />
+			   pin &lt; range-&gt;pin_base + range-&gt;npins)<br />
+			goto out;<br />
 	}<br />
+	range = NULL;<br />
+out:<br />
 	mutex_unlock(&amp;pctldev-&gt;mutex);<br />
-<br />
-	return NULL;<br />
+	return range;<br />
 }<br />
 EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);<br />
 <br />
<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Wei Yongjun</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 06:30:02 +0200</pubDate>
        </item>
        <item>
            <guid>http://www.serverphorums.com/read.php?12,727371,727371#msg-727371</guid>
            <title>[x86] only print out DR registers if they are not power-on defaults. (no replies)</title>
            <link>http://www.serverphorums.com/read.php?12,727371,727371#msg-727371</link>
            <description><![CDATA[ The DR registers are rarely useful when decoding oopses.<br />
With screen real estate during oopses at a premium, we can save two lines<br />
by only printing out these registers when they are set to something other<br />
than they power-on state.<br />
<br />
Signed-off-by: Dave Jones &lt;davej@redhat.com&gt;<br />
<br />
diff -durpN '--exclude-from=/home/davej/.exclude' /home/davej/src/kernel/git-trees/linux/arch/x86/kernel/process_64.c linux-dj/arch/x86/kernel/process_64.c<br />
--- /home/davej/src/kernel/git-trees/linux/arch/x86/kernel/process_64.c	2013-05-01 10:02:52.064151923 -0400<br />
+++ linux-dj/arch/x86/kernel/process_64.c	2013-05-06 20:35:09.219868881 -0400<br />
@@ -105,11 +105,18 @@ void __show_regs(struct pt_regs *regs, i<br />
 	get_debugreg(d0, 0);<br />
 	get_debugreg(d1, 1);<br />
 	get_debugreg(d2, 2);<br />
-	printk(KERN_DEFAULT &quot;DR0: %016lx DR1: %016lx DR2: %016lx\n&quot;, d0, d1, d2);<br />
 	get_debugreg(d3, 3);<br />
 	get_debugreg(d6, 6);<br />
 	get_debugreg(d7, 7);<br />
+<br />
+	/* Only print out debug registers if they are in their non-default state. */<br />
+	if ((d0 == 0) &amp;&amp; (d1 == 0) &amp;&amp; (d2 == 0) &amp;&amp; (d3 == 0) &amp;&amp;<br />
+	    (d6 &amp; ~DR6_RESERVED) &amp;&amp; (d7 == 0x400))<br />
+		return;<br />
+<br />
+	printk(KERN_DEFAULT &quot;DR0: %016lx DR1: %016lx DR2: %016lx\n&quot;, d0, d1, d2);<br />
 	printk(KERN_DEFAULT &quot;DR3: %016lx DR6: %016lx DR7: %016lx\n&quot;, d3, d6, d7);<br />
+<br />
 }<br />
 <br />
 void release_thread(struct task_struct *dead_task)<br />
<br />
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c<br />
index 7305f7d..5905dc5 100644<br />
--- a/arch/x86/kernel/process_32.c<br />
+++ b/arch/x86/kernel/process_32.c<br />
@@ -110,11 +110,16 @@ void __show_regs(struct pt_regs *regs, int all)<br />
 	get_debugreg(d1, 1);<br />
 	get_debugreg(d2, 2);<br />
 	get_debugreg(d3, 3);<br />
-	printk(KERN_DEFAULT &quot;DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n&quot;,<br />
-			d0, d1, d2, d3);<br />
-<br />
 	get_debugreg(d6, 6);<br />
 	get_debugreg(d7, 7);<br />
+<br />
+	/* Only print out debug registers if they are in their non-default state. */<br />
+	if ((d0 == 0) &amp;&amp; (d1 == 0) &amp;&amp; (d2 == 0) &amp;&amp; (d3 == 0) &amp;&amp;<br />
+	    (d6 &amp; ~DR6_RESERVED) &amp;&amp; (d7 == 0x400))<br />
+		return;<br />
+<br />
+	printk(KERN_DEFAULT &quot;DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n&quot;,<br />
+			d0, d1, d2, d3);<br />
 	printk(KERN_DEFAULT &quot;DR6: %08lx DR7: %08lx\n&quot;,<br />
 			d6, d7);<br />
 }<br />
--<br />
To unsubscribe from this list: send the line &quot;unsubscribe linux-kernel&quot; in<br />
the body of a message to <a href="mailto:&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;">&#109;&#97;&#106;&#111;&#114;&#100;&#111;&#109;&#111;&#64;&#118;&#103;&#101;&#114;&#46;&#107;&#101;&#114;&#110;&#101;&#108;&#46;&#111;&#114;&#103;</a><br />
More majordomo info at  <a href="http://vger.kernel.org/majordomo-info.html" target="_blank"  rel="nofollow">http://vger.kernel.org/majordomo-info.html</a><br />
Please read the FAQ at  <a href="http://www.tux.org/lkml/" target="_blank"  rel="nofollow">http://www.tux.org/lkml/</a>]]></description>
            <dc:creator>Dave Jones</dc:creator>
            <category>Linux Kernel</category>
            <pubDate>Tue, 18 Jun 2013 06:20:02 +0200</pubDate>
        </item>
    </channel>
</rss>
