Netdev List
 help / color / mirror / Atom feed
* [net-next 13/14] i40e: Change MSIX to MSI-X
From: Aaron Brown @ 2014-02-14 22:58 UTC (permalink / raw)
  To: davem
  Cc: Catherine Sullivan, netdev, gospo, sassmann, Jesse Brandeburg,
	Aaron Brown
In-Reply-To: <1392418688-23895-1-git-send-email-aaron.f.brown@intel.com>

From: Catherine Sullivan <catherine.sullivan@intel.com>

Fix inconsistent use of MSIX and MSI-X in messages.

Change-ID: Iae9ffb42819677c34544719044ed77632e06147d
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c     | 9 +++++----
 drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 ++-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 4a19073..7562af7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -5946,7 +5946,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
 
 	} else if (vec == I40E_MIN_MSIX) {
 		/* Adjust for minimal MSIX use */
-		dev_info(&pf->pdev->dev, "Features disabled, not enough MSIX vectors\n");
+		dev_info(&pf->pdev->dev, "Features disabled, not enough MSI-X vectors\n");
 		pf->flags &= ~I40E_FLAG_VMDQ_ENABLED;
 		pf->num_vmdq_vsis = 0;
 		pf->num_vmdq_qps = 0;
@@ -6075,7 +6075,7 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
 
 	if (!(pf->flags & I40E_FLAG_MSIX_ENABLED) &&
 	    (pf->flags & I40E_FLAG_MSI_ENABLED)) {
-		dev_info(&pf->pdev->dev, "MSIX not available, trying MSI\n");
+		dev_info(&pf->pdev->dev, "MSI-X not available, trying MSI\n");
 		err = pci_enable_msi(pf->pdev);
 		if (err) {
 			dev_info(&pf->pdev->dev, "MSI init failed - %d\n", err);
@@ -6084,7 +6084,7 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
 	}
 
 	if (!(pf->flags & (I40E_FLAG_MSIX_ENABLED | I40E_FLAG_MSI_ENABLED)))
-		dev_info(&pf->pdev->dev, "MSIX and MSI not available, falling back to Legacy IRQ\n");
+		dev_info(&pf->pdev->dev, "MSI-X and MSI not available, falling back to Legacy IRQ\n");
 
 	/* track first vector for misc interrupts */
 	err = i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT-1);
@@ -6111,7 +6111,8 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
 				  i40e_intr, 0, pf->misc_int_name, pf);
 		if (err) {
 			dev_info(&pf->pdev->dev,
-				 "request_irq for msix_misc failed: %d\n", err);
+				 "request_irq for %s failed: %d\n",
+				 pf->misc_int_name, err);
 			return -EFAULT;
 		}
 	}
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 5bcbdcc..e0d2799 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -524,7 +524,8 @@ static int i40evf_request_misc_irq(struct i40evf_adapter *adapter)
 			  adapter->misc_vector_name, netdev);
 	if (err) {
 		dev_err(&adapter->pdev->dev,
-			"request_irq for msix_aq failed: %d\n", err);
+			"request_irq for %s failed: %d\n",
+			adapter->misc_vector_name, err);
 		free_irq(adapter->msix_entries[0].vector, netdev);
 	}
 	return err;
-- 
1.8.5.GIT

^ permalink raw reply related

* [net-next 12/14] i40e: tighten up ring enable/disable flow
From: Aaron Brown @ 2014-02-14 22:58 UTC (permalink / raw)
  To: davem
  Cc: Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg,
	Aaron Brown
In-Reply-To: <1392418688-23895-1-git-send-email-aaron.f.brown@intel.com>

From: Mitch Williams <mitch.a.williams@intel.com>

Change the do/while to a for loop, so we don't hit the delay each
time, even when the register is ready for action.
Don't bother to set or clear the QENA_STAT bit as it is
read-only.

Change-ID: Ie464718804dd79f6d726f291caa9b0c872b49978
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 32 ++++++++++++++---------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 628e917..4a19073 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -3108,13 +3108,13 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
 
 	pf_q = vsi->base_queue;
 	for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
-		j = 1000;
-		do {
-			usleep_range(1000, 2000);
+		for (j = 0; j < 50; j++) {
 			tx_reg = rd32(hw, I40E_QTX_ENA(pf_q));
-		} while (j-- && ((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT)
-			       ^ (tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT)) & 1);
-
+			if (((tx_reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 1) ==
+			    ((tx_reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) & 1))
+				break;
+			usleep_range(1000, 2000);
+		}
 		/* Skip if the queue is already in the requested state */
 		if (enable && (tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
 			continue;
@@ -3124,8 +3124,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
 		/* turn on/off the queue */
 		if (enable) {
 			wr32(hw, I40E_QTX_HEAD(pf_q), 0);
-			tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK |
-				  I40E_QTX_ENA_QENA_STAT_MASK;
+			tx_reg |= I40E_QTX_ENA_QENA_REQ_MASK;
 		} else {
 			tx_reg &= ~I40E_QTX_ENA_QENA_REQ_MASK;
 		}
@@ -3172,12 +3171,13 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
 
 	pf_q = vsi->base_queue;
 	for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
-		j = 1000;
-		do {
-			usleep_range(1000, 2000);
+		for (j = 0; j < 50; j++) {
 			rx_reg = rd32(hw, I40E_QRX_ENA(pf_q));
-		} while (j-- && ((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT)
-			       ^ (rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT)) & 1);
+			if (((rx_reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 1) ==
+			    ((rx_reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 1))
+				break;
+			usleep_range(1000, 2000);
+		}
 
 		if (enable) {
 			/* is STAT set ? */
@@ -3191,11 +3191,9 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
 
 		/* turn on/off the queue */
 		if (enable)
-			rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK |
-				  I40E_QRX_ENA_QENA_STAT_MASK;
+			rx_reg |= I40E_QRX_ENA_QENA_REQ_MASK;
 		else
-			rx_reg &= ~(I40E_QRX_ENA_QENA_REQ_MASK |
-				  I40E_QRX_ENA_QENA_STAT_MASK);
+			rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK;
 		wr32(hw, I40E_QRX_ENA(pf_q), rx_reg);
 
 		/* wait for the change to finish */
-- 
1.8.5.GIT

^ permalink raw reply related

* [net-next 07/14] i40evf: don't guess device name
From: Aaron Brown @ 2014-02-14 22:58 UTC (permalink / raw)
  To: davem
  Cc: Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg,
	Aaron Brown
In-Reply-To: <1392418688-23895-1-git-send-email-aaron.f.brown@intel.com>

From: Mitch Williams <mitch.a.williams@intel.com>

We don't need to set an interface name here; the net core will do
that, and then it will get renamed by udev anyway.

Change-ID: I839a17837d19bedd1f490bff32ac5b85b4bfd97f
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
 drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index a64570e..4a75e84 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -2086,8 +2086,6 @@ static void i40evf_init_task(struct work_struct *work)
 
 	netif_carrier_off(netdev);
 
-	strcpy(netdev->name, "eth%d");
-
 	adapter->vsi.id = adapter->vsi_res->vsi_id;
 	adapter->vsi.seid = adapter->vsi_res->vsi_id; /* dummy */
 	adapter->vsi.back = adapter;
-- 
1.8.5.GIT

^ permalink raw reply related

* [net-next 11/14] i40e: remove unnecessary delay
From: Aaron Brown @ 2014-02-14 22:58 UTC (permalink / raw)
  To: davem
  Cc: Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg,
	Aaron Brown
In-Reply-To: <1392418688-23895-1-git-send-email-aaron.f.brown@intel.com>

From: Mitch Williams <mitch.a.williams@intel.com>

Ain't nothing gonna break my stride, nobody's gonna slow me down,
oh no. I got to keep on moving.

This was originally put in for debugging just-in-case purposes
and never removed.

Change-ID: Ic12c2e179c3923f54e6ba0a9e4ab05d25c3bab29
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 7d133fa..189e250 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -671,7 +671,6 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
 complete_reset:
 	/* reallocate vf resources to reset the VSI state */
 	i40e_free_vf_res(vf);
-	mdelay(10);
 	i40e_alloc_vf_res(vf);
 	i40e_enable_vf_mappings(vf);
 	set_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
-- 
1.8.5.GIT

^ permalink raw reply related

* [net-next 14/14] i40e and i40evf: Bump driver versions
From: Aaron Brown @ 2014-02-14 22:58 UTC (permalink / raw)
  To: davem
  Cc: Catherine Sullivan, netdev, gospo, sassmann, Jesse Brandeburg,
	Aaron Brown
In-Reply-To: <1392418688-23895-1-git-send-email-aaron.f.brown@intel.com>

From: Catherine Sullivan <catherine.sullivan@intel.com>

Update the driver versions.

Change-ID: I3fe23024d17da0e614ce126edb365bb2c428d482
Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c     | 2 +-
 drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 7562af7..2d9168e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -38,7 +38,7 @@ static const char i40e_driver_string[] =
 
 #define DRV_VERSION_MAJOR 0
 #define DRV_VERSION_MINOR 3
-#define DRV_VERSION_BUILD 31
+#define DRV_VERSION_BUILD 32
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
 	     __stringify(DRV_VERSION_MINOR) "." \
 	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index e0d2799..a1bfff9 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -31,7 +31,7 @@ char i40evf_driver_name[] = "i40evf";
 static const char i40evf_driver_string[] =
 	"Intel(R) XL710 X710 Virtual Function Network Driver";
 
-#define DRV_VERSION "0.9.12"
+#define DRV_VERSION "0.9.13"
 const char i40evf_driver_version[] = DRV_VERSION;
 static const char i40evf_copyright[] =
 	"Copyright (c) 2013 - 2014 Intel Corporation.";
-- 
1.8.5.GIT

^ permalink raw reply related

* Re: [PATCH] DT: net: document Ethernet bindings in one place
From: Sergei Shtylyov @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Grant Likely, Florian Fainelli, Rob Herring, David Miller
  Cc: netdev, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Rob Landley, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20140210220541.C7A56C408F7-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>

Hello.

On 02/11/2014 01:05 AM, Grant Likely wrote:

>>>>>>>>>>>>>         I'm afraid that's too late, it has spread very far, so that
>>>>>>>>>>>>> of_get_phy_mode() handles that property, not "phy-connection-type".

>>>>>>>>>>>> Uggg, I guess this is a case of a defacto standard then if the kernel
>>>>>>>>>>>> doesn't even support it.

>>>>>>>>>>> Maybe I forgot to CC you on patch sent to Grant only, I sent a patch a
>>>>>>>>>>> while ago for of_get_phy_mode() to look for both "phy-mode" and
>>>>>>>>>>> "phy-connection-type" since the former has been a Linux invention, but
>>>>>>>>>>> the latter is ePAPR specified.

>>>>>>>>>> Here is a link to the actual patch in question, not sure which tree
>>>>>>>>>> Grant applied it to though:

>>>>>>>>>> http://lkml.indiana.edu/hypermail/linux/kernel/1311.2/00048.html

>>>>>>>>>         It's not the patch mail, it's Grant's "applied" reply, patch is mangled in
>>>>>>>>> this reply, and I couldn't follow the thread. Here's the actual patch mail:

>>>>>>>>> http://marc.info/?l=devicetree&m=138449662807254

>>>>>>>>         Florian, I didn't find this patch in Grant's official tree, so maybe you
>>>>>>>> should ask him where is the patch already?

>>>>>>> Sorry, I accidentally dropped it. It will be in the next merge window.

>>>>>>        Already saw it, thanks. Would that it was in 3.14 instead of course, so
>>>>>> that I could use "phy-connection-type" in my binding...

>>>>> Is 3.14 broken because of missing the patch? If so I'll get it merged as
>>>>> a bug fix.

>>>>       No, it's not. I could have used "phy-connection-type" in my binding
>>>> destined for 3.15 and document it as a preferred property as well.

>>> You still can. We just need to make sure that your patch is applied on

>>      Patches.

>>> top of the phy-connection-type patch.

>>      I'm not sure this trick is possible if the patches are merged via the
>> different trees...

> There are two ways to do it. A) by having a common merge commit
> containing that patch and merged into both branches, or B) just merging
> the patch in the same tree.

> Normally I'd suggest B), but I've already picked up the patch and I try
> very hard not to rebase my commit tree. However, since the branch is
> stable, you can ask for my branch to be merged into the net branch
> before applying the dependant patches. The relevant commit id is
> cf4c9eb5a4, and it is in my devicetree/next branch on
> git://git.secretlab.ca/git/linux

    David, would it be possible for you to merge this into net-next?

> g.

WBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCHv2 1/5] wl1251: split wl251 platform data to a separate structure
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Luciano Coelho
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>

From: Luciano Coelho <coelho@ti.com>

Move the wl1251 part of the wl12xx platform data structure into a new
structure specifically for wl1251.  Change the platform data built-in
block and board files accordingly.

Signed-off-by: Luciano Coelho <coelho@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
Reviewed-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
---
 arch/arm/mach-omap2/board-omap3pandora.c       |  4 +--
 arch/arm/mach-omap2/board-rx51-peripherals.c   |  2 +-
 drivers/net/wireless/ti/wilink_platform_data.c | 37 +++++++++++++++++++++-----
 drivers/net/wireless/ti/wl1251/sdio.c          | 12 ++++-----
 drivers/net/wireless/ti/wl1251/spi.c           |  2 +-
 include/linux/wl12xx.h                         | 22 ++++++++++++++-
 6 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index de1bc6b..24f3c1b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -536,7 +536,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
 
 static void __init pandora_wl1251_init(void)
 {
-	struct wl12xx_platform_data pandora_wl1251_pdata;
+	struct wl1251_platform_data pandora_wl1251_pdata;
 	int ret;
 
 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
@@ -550,7 +550,7 @@ static void __init pandora_wl1251_init(void)
 		goto fail_irq;
 
 	pandora_wl1251_pdata.use_eeprom = true;
-	ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
 	if (ret < 0)
 		goto fail_irq;
 
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 8760bbe..e05e740 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -84,7 +84,7 @@ enum {
 	RX51_SPI_MIPID,		/* LCD panel */
 };
 
-static struct wl12xx_platform_data wl1251_pdata;
+static struct wl1251_platform_data wl1251_pdata;
 static struct tsc2005_platform_data tsc2005_pdata;
 
 #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e958..a92bd3e 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
 #include <linux/err.h>
 #include <linux/wl12xx.h>
 
-static struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *wl12xx_platform_data;
 
 int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 {
-	if (platform_data)
+	if (wl12xx_platform_data)
 		return -EBUSY;
 	if (!data)
 		return -EINVAL;
 
-	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
-	if (!platform_data)
+	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl12xx_platform_data)
 		return -ENOMEM;
 
 	return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 {
-	if (!platform_data)
+	if (!wl12xx_platform_data)
 		return ERR_PTR(-ENODEV);
 
-	return platform_data;
+	return wl12xx_platform_data;
 }
 EXPORT_SYMBOL(wl12xx_get_platform_data);
+
+static struct wl1251_platform_data *wl1251_platform_data;
+
+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	if (wl1251_platform_data)
+		return -EBUSY;
+	if (!data)
+		return -EINVAL;
+
+	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+	if (!wl1251_platform_data)
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	if (!wl1251_platform_data)
+		return ERR_PTR(-ENODEV);
+
+	return wl1251_platform_data;
+}
+EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c..b75a37a 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	struct wl1251 *wl;
 	struct ieee80211_hw *hw;
 	struct wl1251_sdio *wl_sdio;
-	const struct wl12xx_platform_data *wl12xx_board_data;
+	const struct wl1251_platform_data *wl1251_board_data;
 
 	hw = wl1251_alloc_hw();
 	if (IS_ERR(hw))
@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 	wl->if_priv = wl_sdio;
 	wl->if_ops = &wl1251_sdio_ops;
 
-	wl12xx_board_data = wl12xx_get_platform_data();
-	if (!IS_ERR(wl12xx_board_data)) {
-		wl->set_power = wl12xx_board_data->set_power;
-		wl->irq = wl12xx_board_data->irq;
-		wl->use_eeprom = wl12xx_board_data->use_eeprom;
+	wl1251_board_data = wl1251_get_platform_data();
+	if (!IS_ERR(wl1251_board_data)) {
+		wl->set_power = wl1251_board_data->set_power;
+		wl->irq = wl1251_board_data->irq;
+		wl->use_eeprom = wl1251_board_data->use_eeprom;
 	}
 
 	if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 1342f81..62403a1 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
 
 static int wl1251_spi_probe(struct spi_device *spi)
 {
-	struct wl12xx_platform_data *pdata;
+	struct wl1251_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
 	int ret;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82..b516b4f 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
 	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
 };
 
-struct wl12xx_platform_data {
+struct wl1251_platform_data {
 	void (*set_power)(bool enable);
 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
 	int irq;
 	bool use_eeprom;
+};
+
+struct wl12xx_platform_data {
+	int irq;
 	int board_ref_clock;
 	int board_tcxo_clock;
 	unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
 
 struct wl12xx_platform_data *wl12xx_get_platform_data(void);
 
+int wl1251_set_platform_data(const struct wl1251_platform_data *data);
+
+struct wl1251_platform_data *wl1251_get_platform_data(void);
+
 #else
 
 static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
 	return ERR_PTR(-ENODATA);
 }
 
+static inline
+int wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+	return -ENOSYS;
+}
+
+static inline
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+	return ERR_PTR(-ENODATA);
+}
+
 #endif
 
 #endif
-- 
1.8.5.3

^ permalink raw reply related

* [PATCHv2 2/5] wl1251: move power GPIO handling into the driver
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>

Move the power GPIO handling from the board code into
the driver. This is a dependency for device tree support.

Signed-off-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/board-omap3pandora.c     |  2 ++
 arch/arm/mach-omap2/board-rx51-peripherals.c | 11 ++--------
 drivers/net/wireless/ti/wl1251/sdio.c        | 21 +++++++++++++-----
 drivers/net/wireless/ti/wl1251/spi.c         | 33 ++++++++++++++++++----------
 drivers/net/wireless/ti/wl1251/wl1251.h      |  2 +-
 include/linux/wl12xx.h                       |  2 +-
 6 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 24f3c1b..cf18340 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -541,6 +541,8 @@ static void __init pandora_wl1251_init(void)
 
 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
 
+	pandora_wl1251_pdata.power_gpio = -1;
+
 	ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
 	if (ret < 0)
 		goto fail;
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e05e740..ddfc8df 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -1173,13 +1173,7 @@ static inline void board_smc91x_init(void)
 
 #endif
 
-static void rx51_wl1251_set_power(bool enable)
-{
-	gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
-}
-
 static struct gpio rx51_wl1251_gpios[] __initdata = {
-	{ RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW,	"wl1251 power"	},
 	{ RX51_WL1251_IRQ_GPIO,	  GPIOF_IN,		"wl1251 irq"	},
 };
 
@@ -1196,17 +1190,16 @@ static void __init rx51_init_wl1251(void)
 	if (irq < 0)
 		goto err_irq;
 
-	wl1251_pdata.set_power = rx51_wl1251_set_power;
+	wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO;
 	rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
 
 	return;
 
 err_irq:
 	gpio_free(RX51_WL1251_IRQ_GPIO);
-	gpio_free(RX51_WL1251_POWER_GPIO);
 error:
 	printk(KERN_ERR "wl1251 board initialisation failed\n");
-	wl1251_pdata.set_power = NULL;
+	wl1251_pdata.power_gpio = -1;
 
 	/*
 	 * Now rx51_peripherals_spi_board_info[1].irq is zero and
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index b75a37a..b661f89 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -28,6 +28,7 @@
 #include <linux/wl12xx.h>
 #include <linux/irq.h>
 #include <linux/pm_runtime.h>
+#include <linux/gpio.h>
 
 #include "wl1251.h"
 
@@ -182,8 +183,9 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
 		 * callback in case it wants to do any additional setup,
 		 * for example enabling clock buffer for the module.
 		 */
-		if (wl->set_power)
-			wl->set_power(true);
+		if (gpio_is_valid(wl->power_gpio))
+			gpio_set_value(wl->power_gpio, true);
+
 
 		ret = pm_runtime_get_sync(&func->dev);
 		if (ret < 0) {
@@ -203,8 +205,8 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
 		if (ret < 0)
 			goto out;
 
-		if (wl->set_power)
-			wl->set_power(false);
+		if (gpio_is_valid(wl->power_gpio))
+			gpio_set_value(wl->power_gpio, false);
 	}
 
 out:
@@ -256,11 +258,20 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 
 	wl1251_board_data = wl1251_get_platform_data();
 	if (!IS_ERR(wl1251_board_data)) {
-		wl->set_power = wl1251_board_data->set_power;
+		wl->power_gpio = wl1251_board_data->power_gpio;
 		wl->irq = wl1251_board_data->irq;
 		wl->use_eeprom = wl1251_board_data->use_eeprom;
 	}
 
+	if (gpio_is_valid(wl->power_gpio)) {
+		ret = devm_gpio_request(&func->dev, wl->power_gpio,
+								"wl1251 power");
+		if (ret) {
+			wl1251_error("Failed to request gpio: %d\n", ret);
+			goto disable;
+		}
+	}
+
 	if (wl->irq) {
 		irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
 		ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 62403a1..6abcbc3 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -26,6 +26,7 @@
 #include <linux/crc7.h>
 #include <linux/spi/spi.h>
 #include <linux/wl12xx.h>
+#include <linux/gpio.h>
 
 #include "wl1251.h"
 #include "reg.h"
@@ -221,8 +222,8 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
 
 static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
 {
-	if (wl->set_power)
-		wl->set_power(enable);
+	if (gpio_is_valid(wl->power_gpio))
+		gpio_set_value(wl->power_gpio, enable);
 
 	return 0;
 }
@@ -271,22 +272,33 @@ static int wl1251_spi_probe(struct spi_device *spi)
 		goto out_free;
 	}
 
-	wl->set_power = pdata->set_power;
-	if (!wl->set_power) {
-		wl1251_error("set power function missing in platform data");
-		return -ENODEV;
+	wl->power_gpio = pdata->power_gpio;
+
+	if (gpio_is_valid(wl->power_gpio)) {
+		ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
+					GPIOF_OUT_INIT_LOW, "wl1251 power");
+		if (ret) {
+			wl1251_error("Failed to request gpio: %d\n", ret);
+			goto out_free;
+		}
+	} else {
+		wl1251_error("set power gpio missing in platform data");
+		ret = -ENODEV;
+		goto out_free;
 	}
 
 	wl->irq = spi->irq;
 	if (wl->irq < 0) {
 		wl1251_error("irq missing in platform data");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out_free;
 	}
 
 	wl->use_eeprom = pdata->use_eeprom;
 
 	irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
-	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+	ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
+							DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1251_error("request_irq() failed: %d", ret);
 		goto out_free;
@@ -296,13 +308,10 @@ static int wl1251_spi_probe(struct spi_device *spi)
 
 	ret = wl1251_init_ieee80211(wl);
 	if (ret)
-		goto out_irq;
+		goto out_free;
 
 	return 0;
 
- out_irq:
-	free_irq(wl->irq, wl);
-
  out_free:
 	ieee80211_free_hw(hw);
 
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 235617a..389fe25 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -276,7 +276,7 @@ struct wl1251 {
 	void *if_priv;
 	const struct wl1251_if_operations *if_ops;
 
-	void (*set_power)(bool enable);
+	int power_gpio;
 	int irq;
 	bool use_eeprom;
 
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..a9c723b 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -49,7 +49,7 @@ enum {
 };
 
 struct wl1251_platform_data {
-	void (*set_power)(bool enable);
+	int power_gpio;
 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
 	int irq;
 	bool use_eeprom;
-- 
1.8.5.3

^ permalink raw reply related

* [PATCHv2 3/5] wl1251: spi: add vio regulator support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>

This patch adds support for requesting the regulator powering
the vio pin.

Signed-off-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
---
 drivers/net/wireless/ti/wl1251/spi.c    | 19 +++++++++++++++++--
 drivers/net/wireless/ti/wl1251/wl1251.h |  2 ++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6abcbc3..0a8aacc 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -27,6 +27,7 @@
 #include <linux/spi/spi.h>
 #include <linux/wl12xx.h>
 #include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 
 #include "wl1251.h"
 #include "reg.h"
@@ -306,13 +307,26 @@ static int wl1251_spi_probe(struct spi_device *spi)
 
 	irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
 
-	ret = wl1251_init_ieee80211(wl);
+	wl->vio = devm_regulator_get(&spi->dev, "vio");
+	if (IS_ERR(wl->vio)) {
+		ret = PTR_ERR(wl->vio);
+		wl1251_error("vio regulator missing: %d", ret);
+		goto out_free;
+	}
+
+	ret = regulator_enable(wl->vio);
 	if (ret)
 		goto out_free;
 
+	ret = wl1251_init_ieee80211(wl);
+	if (ret)
+		goto disable_regulator;
+
 	return 0;
 
- out_free:
+disable_regulator:
+	regulator_disable(wl->vio);
+out_free:
 	ieee80211_free_hw(hw);
 
 	return ret;
@@ -324,6 +338,7 @@ static int wl1251_spi_remove(struct spi_device *spi)
 
 	free_irq(wl->irq, wl);
 	wl1251_free_hw(wl);
+	regulator_disable(wl->vio);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 389fe25..16dae52 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -280,6 +280,8 @@ struct wl1251 {
 	int irq;
 	bool use_eeprom;
 
+	struct regulator *vio;
+
 	spinlock_t wl_lock;
 
 	enum wl1251_state state;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCHv2 4/5] wl1251: spi: add device tree support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>

Add device tree support for the spi variant of wl1251.

Signed-off-by: Sebastian Reichel <sre@debian.org>
---
 drivers/net/wireless/ti/wl1251/spi.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 0a8aacc..b06d36d 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -27,6 +27,8 @@
 #include <linux/spi/spi.h>
 #include <linux/wl12xx.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
 
 #include "wl1251.h"
@@ -240,13 +242,13 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
 
 static int wl1251_spi_probe(struct spi_device *spi)
 {
-	struct wl1251_platform_data *pdata;
+	struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev);
+	struct device_node *np = spi->dev.of_node;
 	struct ieee80211_hw *hw;
 	struct wl1251 *wl;
 	int ret;
 
-	pdata = dev_get_platdata(&spi->dev);
-	if (!pdata) {
+	if (!np && !pdata) {
 		wl1251_error("no platform data");
 		return -ENODEV;
 	}
@@ -273,7 +275,18 @@ static int wl1251_spi_probe(struct spi_device *spi)
 		goto out_free;
 	}
 
-	wl->power_gpio = pdata->power_gpio;
+	if (np) {
+		wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
+		wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0);
+	} else if (pdata) {
+		wl->power_gpio = pdata->power_gpio;
+		wl->use_eeprom = pdata->use_eeprom;
+	}
+
+	if (wl->power_gpio == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto out_free;
+	}
 
 	if (gpio_is_valid(wl->power_gpio)) {
 		ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
@@ -295,8 +308,6 @@ static int wl1251_spi_probe(struct spi_device *spi)
 		goto out_free;
 	}
 
-	wl->use_eeprom = pdata->use_eeprom;
-
 	irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
 	ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
 							DRIVER_NAME, wl);
-- 
1.8.5.3

^ permalink raw reply related

* [PATCHv2 5/5] Documentation: dt: wireless: Add wl1251
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>

Add device tree binding documentation for Texas Instrument's wl1251
wireless lan chip. For now only the SPI binding is documented.

Signed-off-by: Sebastian Reichel <sre@debian.org>
---
 .../devicetree/bindings/net/wireless/ti,wl1251.txt | 39 ++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
new file mode 100644
index 0000000..189ae5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
@@ -0,0 +1,39 @@
+* Texas Instruments wl1251 wireless lan controller
+
+The wl1251 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :        Should be "ti,wl1251"
+- reg :               Chip select address of device
+- spi-max-frequency : Maximum SPI clocking speed of device in Hz
+- interrupts :        Should contain interrupt line
+- interrupt-parent :  Should be the phandle for the interrupt controller
+                      that services interrupts for this device
+- vio-supply :        phandle to regulator providing VIO
+- ti,power-gpio :     GPIO connected to chip's PMEN pin
+
+Optional properties:
+- ti,wl1251-has-eeprom : boolean, the wl1251 has an eeprom connected, which
+                         provides configuration data (calibration, MAC, ...)
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+&spi1 {
+	wl1251@0 {
+		compatible = "ti,wl1251";
+
+		reg = <0>;
+		spi-max-frequency = <48000000>;
+		spi-cpol;
+		spi-cpha;
+
+		interrupt-parent = <&gpio2>;
+		interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
+
+		vio-supply = <&vio>;
+		ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
+	};
+};
-- 
1.8.5.3

^ permalink raw reply related

* [RESEND] [PATCHv2 0/5] wl1251 device tree support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
  To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
	John W. Linville
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
	Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
	netdev, Sebastian Reichel
In-Reply-To: <20140125000929.GD25488@atomide.com>

Hi John,

The following patchset adds device tree support to the spi variant of the
wl1251 driver, which is used in the Nokia N900. Tony requested, that you
take the whole series even if that may introduce merge conflicts:

> Sebastian, please resend the whole series to John and feel free to add my
> acks.  It's best that John picks them all up, otherwise we'll have the same
> issue for v3.15. It seems that we should have just taken the merge conflict
> rather than going back and forth with this.

-- Sebastian

Luciano Coelho (1):
  wl1251: split wl251 platform data to a separate structure

Sebastian Reichel (4):
  wl1251: move power GPIO handling into the driver
  wl1251: spi: add vio regulator support
  wl1251: spi: add device tree support
  Documentation: dt: wireless: Add wl1251

 .../devicetree/bindings/net/wireless/ti,wl1251.txt | 39 ++++++++++++
 arch/arm/mach-omap2/board-omap3pandora.c           |  6 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c       | 13 +---
 drivers/net/wireless/ti/wilink_platform_data.c     | 37 +++++++++--
 drivers/net/wireless/ti/wl1251/sdio.c              | 31 +++++++---
 drivers/net/wireless/ti/wl1251/spi.c               | 71 ++++++++++++++++------
 drivers/net/wireless/ti/wl1251/wl1251.h            |  4 +-
 include/linux/wl12xx.h                             | 24 +++++++-
 8 files changed, 176 insertions(+), 49 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt

-- 
1.8.5.3

^ permalink raw reply

* [Patch net-next] openvswitch: rename ->sync to ->syncp
From: Cong Wang @ 2014-02-14 23:10 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Cong Wang

Openvswitch defines u64_stats_sync as ->sync rather than ->syncp,
so fails to compile with netdev_alloc_pcpu_stats(). So just rename it to ->syncp.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Fixes: 1c213bd24ad04f4430031 (net: introduce netdev_alloc_pcpu_stats() for drivers)
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

---
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 3a95406..36f8872c 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -256,10 +256,10 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
 
 out:
 	/* Update datapath statistics. */
-	u64_stats_update_begin(&stats->sync);
+	u64_stats_update_begin(&stats->syncp);
 	(*stats_counter)++;
 	stats->n_mask_hit += n_mask_hit;
-	u64_stats_update_end(&stats->sync);
+	u64_stats_update_end(&stats->syncp);
 }
 
 static struct genl_family dp_packet_genl_family = {
@@ -295,9 +295,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
 err:
 	stats = this_cpu_ptr(dp->stats_percpu);
 
-	u64_stats_update_begin(&stats->sync);
+	u64_stats_update_begin(&stats->syncp);
 	stats->n_lost++;
-	u64_stats_update_end(&stats->sync);
+	u64_stats_update_end(&stats->syncp);
 
 	return err;
 }
@@ -606,9 +606,9 @@ static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats,
 		percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
 
 		do {
-			start = u64_stats_fetch_begin_bh(&percpu_stats->sync);
+			start = u64_stats_fetch_begin_bh(&percpu_stats->syncp);
 			local_stats = *percpu_stats;
-		} while (u64_stats_fetch_retry_bh(&percpu_stats->sync, start));
+		} while (u64_stats_fetch_retry_bh(&percpu_stats->syncp, start));
 
 		stats->n_hit += local_stats.n_hit;
 		stats->n_missed += local_stats.n_missed;
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 6be9fbb..0531738 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -55,7 +55,7 @@ struct dp_stats_percpu {
 	u64 n_missed;
 	u64 n_lost;
 	u64 n_mask_hit;
-	struct u64_stats_sync sync;
+	struct u64_stats_sync syncp;
 };
 
 /**

^ permalink raw reply related

* [PATCH net-next] Documentation: broadcom-bcmgenet: add better clocks documentation
From: Florian Fainelli @ 2014-02-14 23:21 UTC (permalink / raw)
  To: netdev; +Cc: davem, Florian Fainelli, Mark Rutland

Document the required "clocks" phandles and their corresponding
"clock-names" properties for the two clocks used by the GENET hardware
block ("enet" and "enet-wol").

CC: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt b/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
index afd31f9..88c3d04 100644
--- a/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
+++ b/Documentation/devicetree/bindings/net/broadcom-bcmgenet.txt
@@ -14,8 +14,11 @@ Required properties:
 - size-cells: should be 1
 
 Optional properties:
-- clocks: When provided, must be two cells, first one is the main GENET clock
-  and the second cell is the Genet Wake-on-LAN clock.
+- clocks: When provided, must be two phandles to the functional clocks nodes
+  of the GENET block. The first phandle is the main GENET clock used during
+  normal operation, while the second phandle is the Wake-on-LAN clock.
+- clock-names: When provided, names of the functional clock phandles, first
+  name should be "enet" and second should be "enet-wol".
 
 - phy-handle: A phandle to a phy node defining the PHY address (as the reg
   property, a single integer), used to describe configurations where a PHY
-- 
1.8.3.2

^ permalink raw reply related

* Re: [net-next 05/14] i40evf: fix up strings in init task
From: Joe Perches @ 2014-02-14 23:43 UTC (permalink / raw)
  To: Aaron Brown
  Cc: davem, Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg
In-Reply-To: <1392418688-23895-6-git-send-email-aaron.f.brown@intel.com>

On Fri, 2014-02-14 at 14:57 -0800, Aaron Brown wrote:
> From: Mitch Williams <mitch.a.williams@intel.com>

Hello.

> Make sure errors are reported at the correct log level, quit printing
> the function name every time, and make the messages more consistent in
> format.

> diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
[]
> @@ -1939,14 +1939,14 @@ static void i40evf_init_task(struct work_struct *work)
>  		adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
>  		err = i40e_set_mac_type(hw);
>  		if (err) {
> -			dev_info(&pdev->dev, "%s: set_mac_type failed: %d\n",
> -				__func__, err);
> +			dev_err(&pdev->dev, "Failed to set MAC type (%d)\n",
> +				err);
>  		goto err;
>  		}
>  		err = i40evf_check_reset_complete(hw);
>  		if (err) {
> -			dev_info(&pdev->dev, "%s: device is still in reset (%d).\n",
> -				__func__, err);
> +			dev_err(&pdev->dev, "Device is still in reset (%d).\n",
> +				err);


Look at the lines above and below here.

If you're going to be consistent, can you please
remove the unnecessary period before the newline.

>  			goto err;
>  		}
>  		hw->aq.num_arq_entries = I40EVF_AQ_LEN;
> @@ -1956,14 +1956,14 @@ static void i40evf_init_task(struct work_struct *work)
>  
>  		err = i40evf_init_adminq(hw);
>  		if (err) {
> -			dev_info(&pdev->dev, "%s: init_adminq failed: %d\n",
> -				__func__, err);
> +			dev_err(&pdev->dev, "Failed to init Admin Queue (%d)\n",
> +				err);
>  			goto err;
>  		}
>  		err = i40evf_send_api_ver(adapter);
>  		if (err) {
> -			dev_info(&pdev->dev, "%s: unable to send to PF (%d)\n",
> -				__func__, err);
> +			dev_err(&pdev->dev, "Unable to send to PF (%d)\n",
> +				err);
>  			i40evf_shutdown_adminq(hw);
>  			goto err;
>  		}

[]

> @@ -1998,8 +1998,7 @@ static void i40evf_init_task(struct work_struct *work)
>  				 sizeof(struct i40e_virtchnl_vsi_resource));
>  			adapter->vf_res = kzalloc(bufsz, GFP_KERNEL);
>  			if (!adapter->vf_res) {
> -				dev_err(&pdev->dev, "%s: unable to allocate memory\n",
> -					__func__);
> +				dev_err(&pdev->dev, "Unable to allocate memory for vf resources.\n");

Unnecessary OOM.
Allocs failures already have one and a dump_stack().

> @@ -2022,7 +2021,7 @@ static void i40evf_init_task(struct work_struct *work)
>  			adapter->vsi_res = &adapter->vf_res->vsi_res[i];
>  	}
>  	if (!adapter->vsi_res) {
> -		dev_info(&pdev->dev, "%s: no LAN VSI found\n", __func__);
> +		dev_err(&pdev->dev, "No LAN VSI found.\n");

Adding unnecessary periods.

> @@ -2053,9 +2052,8 @@ static void i40evf_init_task(struct work_struct *work)
>  
>  	/* The HW MAC address was set and/or determined in sw_init */
>  	if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
> -		dev_info(&pdev->dev,
> -			"Invalid MAC address %pMAC, using random\n",
> -			adapter->hw.mac.addr);
> +		dev_info(&pdev->dev, "Invalid MAC address %pMAC, using random.\n",

And here too.

^ permalink raw reply

* Re: [Patch net-next] openvswitch: rename ->sync to ->syncp
From: Flavio Leitner @ 2014-02-14 23:46 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, David S. Miller
In-Reply-To: <1392419446-4559-1-git-send-email-xiyou.wangcong@gmail.com>

On Fri, Feb 14, 2014 at 03:10:46PM -0800, Cong Wang wrote:
> Openvswitch defines u64_stats_sync as ->sync rather than ->syncp,
> so fails to compile with netdev_alloc_pcpu_stats(). So just rename it to ->syncp.
> 
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Fixes: 1c213bd24ad04f4430031 (net: introduce netdev_alloc_pcpu_stats() for drivers)
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
> 
> ---

Reviewed-by: Flavio Leitner <fbl@redhat.com>

^ permalink raw reply

* RE: [net-next 05/14] i40evf: fix up strings in init task
From: Williams, Mitch A @ 2014-02-14 23:53 UTC (permalink / raw)
  To: Joe Perches, Brown, Aaron F
  Cc: davem@davemloft.net, netdev@vger.kernel.org, gospo@redhat.com,
	sassmann@redhat.com, Brandeburg, Jesse
In-Reply-To: <1392421409.12157.3.camel@joe-AO722>



> -----Original Message-----
> From: Joe Perches [mailto:joe@perches.com]
> Sent: Friday, February 14, 2014 3:43 PM
> To: Brown, Aaron F
> Cc: davem@davemloft.net; Williams, Mitch A; netdev@vger.kernel.org;
> gospo@redhat.com; sassmann@redhat.com; Brandeburg, Jesse
> Subject: Re: [net-next 05/14] i40evf: fix up strings in init task
> 
> On Fri, 2014-02-14 at 14:57 -0800, Aaron Brown wrote:
> > From: Mitch Williams <mitch.a.williams@intel.com>
> 
> Hello.
> 
> > Make sure errors are reported at the correct log level, quit printing
> > the function name every time, and make the messages more consistent in
> > format.
> 
> > diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
> b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
> []
> > @@ -1939,14 +1939,14 @@ static void i40evf_init_task(struct work_struct
> *work)
> >  		adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
> >  		err = i40e_set_mac_type(hw);
> >  		if (err) {
> > -			dev_info(&pdev->dev, "%s: set_mac_type failed: %d\n",
> > -				__func__, err);
> > +			dev_err(&pdev->dev, "Failed to set MAC type (%d)\n",
> > +				err);
> >  		goto err;
> >  		}
> >  		err = i40evf_check_reset_complete(hw);
> >  		if (err) {
> > -			dev_info(&pdev->dev, "%s: device is still in reset (%d).\n",
> > -				__func__, err);
> > +			dev_err(&pdev->dev, "Device is still in reset (%d).\n",
> > +				err);
> 
> 
> Look at the lines above and below here.
> 
> If you're going to be consistent, can you please
> remove the unnecessary period before the newline.
> 
> >  			goto err;
> >  		}
> >  		hw->aq.num_arq_entries = I40EVF_AQ_LEN;
> > @@ -1956,14 +1956,14 @@ static void i40evf_init_task(struct work_struct
> *work)
> >
> >  		err = i40evf_init_adminq(hw);
> >  		if (err) {
> > -			dev_info(&pdev->dev, "%s: init_adminq failed: %d\n",
> > -				__func__, err);
> > +			dev_err(&pdev->dev, "Failed to init Admin Queue (%d)\n",
> > +				err);
> >  			goto err;
> >  		}
> >  		err = i40evf_send_api_ver(adapter);
> >  		if (err) {
> > -			dev_info(&pdev->dev, "%s: unable to send to PF (%d)\n",
> > -				__func__, err);
> > +			dev_err(&pdev->dev, "Unable to send to PF (%d)\n",
> > +				err);
> >  			i40evf_shutdown_adminq(hw);
> >  			goto err;
> >  		}
> 
> []
> 
> > @@ -1998,8 +1998,7 @@ static void i40evf_init_task(struct work_struct
> *work)
> >  				 sizeof(struct i40e_virtchnl_vsi_resource));
> >  			adapter->vf_res = kzalloc(bufsz, GFP_KERNEL);
> >  			if (!adapter->vf_res) {
> > -				dev_err(&pdev->dev, "%s: unable to allocate memory\n",
> > -					__func__);
> > +				dev_err(&pdev->dev, "Unable to allocate memory for vf
> resources.\n");
> 
> Unnecessary OOM.
> Allocs failures already have one and a dump_stack().
> 
> > @@ -2022,7 +2021,7 @@ static void i40evf_init_task(struct work_struct
> *work)
> >  			adapter->vsi_res = &adapter->vf_res->vsi_res[i];
> >  	}
> >  	if (!adapter->vsi_res) {
> > -		dev_info(&pdev->dev, "%s: no LAN VSI found\n", __func__);
> > +		dev_err(&pdev->dev, "No LAN VSI found.\n");
> 
> Adding unnecessary periods.
> 
> > @@ -2053,9 +2052,8 @@ static void i40evf_init_task(struct work_struct
> *work)
> >
> >  	/* The HW MAC address was set and/or determined in sw_init */
> >  	if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
> > -		dev_info(&pdev->dev,
> > -			"Invalid MAC address %pMAC, using random\n",
> > -			adapter->hw.mac.addr);
> > +		dev_info(&pdev->dev, "Invalid MAC address %pMAC, using
> random.\n",
> 
> And here too.
> 
Joe, thanks for your review. We'll ditch the OOM message and I'll add a reminder to myself to scrub the rest of the driver for more of these.

With regard to periods on the end of log messages, is this a hard rule? The grammar pedant in me likes to see periods on the end of sentences, so I tend to add them. However, I see that CodingStyle says, "Kernel messages do not have to be terminated with a period." Perhaps we should change that to say "should not" if it is considered a rule.

Either way, we'll respin the patch.

-Mitch

^ permalink raw reply

* Re: [PATCH 2/3] net: UDP gro_receive accept csum=0
From: Tom Herbert @ 2014-02-14 23:54 UTC (permalink / raw)
  To: Joseph Gasparakis
  Cc: Or Gerlitz, Or Gerlitz, David Miller, Linux Netdev List,
	Jerry Chu, Eric Dumazet
In-Reply-To: <alpine.LFD.2.03.1402141034180.25492@intel.com>

>> In any case, we need to consider the orignal ip_summed value from the
>> driver, not the one that udp4_csum_init (udp_gro or anywhere else in
>> the path) would set.
>>
>> Also, udp_gro_receive should be able to handle the case where
>> ip_summed == CHECKSUM_UNNECESSARY and !skb->encapsulation, that will
>> be very common scenario. Probably CHECKSUM_NONE also.
>>
>
> Yes, I now see your point and totaly agree. Thanks.

Okay, I'll look at fixing this. I suspect we want to maintain
CHECKSUM_COMPLETE as long as possible in UDP receive path (or any
other encap path) and not be converting to CHECKSUM_UNNECESSARY.  When
crossing  the encapsulation layer we'll need to deal with
skb->encapsulation and CHECKSUM_UNNECESSARY.

Note to HW vendors: can you please start providing the full packet
checksum (CHECKSUM_COMPLETE) and stop perpetuating the extremely
protocol specific, restrictive checksum validation!

^ permalink raw reply

* Re: [net-next 05/14] i40evf: fix up strings in init task
From: Joe Perches @ 2014-02-15  0:05 UTC (permalink / raw)
  To: Williams, Mitch A
  Cc: Brown, Aaron F, davem@davemloft.net, netdev@vger.kernel.org,
	gospo@redhat.com, sassmann@redhat.com, Brandeburg, Jesse
In-Reply-To: <AAEA33E297BCAC4B9BB20A7C2DF0AB8D65517F5F@FMSMSX113.amr.corp.intel.com>

On Fri, 2014-02-14 at 23:53 +0000, Williams, Mitch A wrote:
> With regard to periods on the end of log messages,
> is this a hard rule?

No.

>  The grammar pedant in me likes to see periods on the end of sentences,

Opinions vary.

I think kernel logging output lines aren't sentences
and are just notifications that don't need periods.

If you look at a normal log, there are relatively few
entries with periods.

For instance, my current dmesg:

$ dmesg | wc -l
1568
$ dmesg | grep "[^\.]\.$" | wc -l
84

^ permalink raw reply

* Re: [PATCH net-next 3/4] appletalk: convert printks to pr_<level>
From: Wang Weidong @ 2014-02-15  1:19 UTC (permalink / raw)
  To: Sergei Shtylyov, acme, davem; +Cc: netdev
In-Reply-To: <52FE8E91.2040105@cogentembedded.com>

On 2014/2/15 5:45, Sergei Shtylyov wrote:
> Hello.
> 
> On 02/14/2014 10:43 AM, Wang Weidong wrote:
> 
>> Prefer pr_<level> then printk(LEVEL).
> 
>> Signed-off-by: Wang Weidong <wangweidong1@huawei.com>
> 
> [...]
>> diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
>> index 06e0d19..9189d3c 100644
>> --- a/net/appletalk/ddp.c
>> +++ b/net/appletalk/ddp.c
>> @@ -704,9 +704,9 @@ static int atif_ioctl(int cmd, void __user *arg)
>>           if ((dev->flags & IFF_POINTOPOINT) &&
>>               atalk_find_interface(sa->sat_addr.s_net,
>>                        sa->sat_addr.s_node)) {
>> -            printk(KERN_DEBUG "AppleTalk: point-to-point "
>> -                   "interface added with "
>> -                   "existing address\n");
>> +            pr_debug("AppleTalk: point-to-point "
>> +                 "interface added with "
>> +                 "existing address\n");
>>               add_route = 0;
>>           }
>>
> [...]
>> @@ -1329,8 +1328,8 @@ static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
>>            * needs to be broadcast onto the default network?
>>            */
>>           if (dev->type == ARPHRD_PPP)
>> -            printk(KERN_DEBUG "AppleTalk: didn't forward broadcast "
>> -                      "packet received from PPP iface\n");
>> +            pr_debug("AppleTalk: didn't forward broadcast "
>> +                 "packet received from PPP iface\n");
> 
>    pr_debug() is not equivalent to printk(KERN_DEBUG). It will only print a message if DEBUG is defined or if dynamic debugging is enabled.
> 
Got it.

WBR, Wang

> WBR, Sergei
> 
> 
> 

^ permalink raw reply

* Re: [PATCH net-next 0/7] clear old options when old qdisc's replaced
From: Yang Yingliang @ 2014-02-15  2:20 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, davem, stephen
In-Reply-To: <1392381841.24974.5.camel@edumazet-glaptop2.roam.corp.google.com>

On 2014/2/14 20:44, Eric Dumazet wrote:
> On Fri, 2014-02-14 at 16:36 +0800, Yang Yingliang wrote:
>> I've added a netem qdisc with rate option, then I replace this qdisc
>> without rate option but with latency option. The rate option is still
>> there.
>>
>> E.g.
>>   # tc qdisc add dev eth4 handle 1: root netem rate 10mbit
>>   # tc qdisc show
>>     qdisc netem 1: dev eth4 root refcnt 2 limit 1000 rate 10Mbit
>>
>>   # tc qdisc replace dev eth4 handle 1: root netem latency 10ms
>>   # tc qdisc show
>>     qdisc netem 1: dev eth4 root refcnt 2 limit 1000 delay 10.0ms rate 10Mbit
>>
>> The old options need be cleared after the qdisc is replaced.
> 
> Not at all. Test your changes with "tc qdisc change ... "
> 
> 
With "tc qdisc change ... ", it will only change the options that specified in command.
It's proper, I think.

   # tc qdisc add dev eth4 handle 1: root netem rate 10mbit
   # tc qdisc show
     qdisc netem 1: dev eth4 root refcnt 2 limit 1000 rate 10Mbit

   # tc qdisc replace dev eth4 handle 1: root netem latency 10ms
   # tc qdisc show
     qdisc netem 1: dev eth4 root refcnt 2 limit 1000 delay 10.0ms rate 10Mbit

"rate" is not cleared.

But with other qdiscs, such as tbf and htb etc, their usage not complete same as netem's,
when we use "tc qdisc change ... ", the old options will be cleared. Maybe we should make
their useages of "change" same as netem's?

E.g.
  # tc qdisc replace dev eth4 handle 1: root tbf rate 10mbit burst 10kb latency 50ms mtu 64kb peakrate 20mbit
  # tc qdisc show
    qdisc tbf 1: dev eth4 root refcnt 2 rate 10Mbit burst 10Kb peakrate 20Mbit minburst 64Kb lat 50.0ms
  # tc qdisc change dev eth4 handle 1: root tbf rate 20mbit burst 10kb latency 50ms
  # tc qdisc show
    qdisc tbf 1: dev eth4 root refcnt 2 rate 20Mbit burst 10Kb lat 50.0ms

"peakrate" and "minburst" are cleared.

  # tc class add dev eth4 parent 1:0 classid 1:1 htb rate 10mbit ceil 10mbit burst 10kb cburst 10kb
  # tc class show dev eth4
    class htb 1:1 root prio 0 rate 10Mbit ceil 10Mbit burst 10Kb cburst 10Kb
  # tc class change dev eth4 parent 1:0 classid 1:1 htb rate 20mbit
  # tc class show dev eth4
    class htb 1:1 root prio 0 rate 20Mbit ceil 20Mbit burst 1600b cburst 1600b

"cburst" and "burst" are cleared.


Regards,
Yang

^ permalink raw reply

* [PATCH V3 0/4] mailbox: xgene: Add support for APM X-Gene SoC Queue Manager/Traffic Manager
From: Ravi Patel @ 2014-02-15  2:21 UTC (permalink / raw)
  To: arnd-r2nGTMty4D4, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, patches-qTEPVZfXA3Y, Ravi Patel,
	Keyur Chudgar

This patch adds support for APM X-Gene SoC Queue Manager/Traffic Manager.
 QMTM is required by APM X-Gene SoC Ethernet, PktDMA (XOR Engine) and
 Security Engine subsystems. All subsystems communicate with QMTM using
 messages which include information about the work to be performed and
 the location of associated data buffers.

V3:
 * Switch to mailbox framework
 * Add support for little and big endian kernel
 * Change virt_to_phys function call to dma_zalloc_coherent

V2:
 * Adding COMPILE_TEST dependency for QMTM in Kconfig
 * Updated license banner as per review comments
 * Fixed alignment for macros
 * Changed EXPORT_SYMBOL to EXPORT_SYMBOL_GPL

V1:
 * inital version

Signed-off-by: Ravi Patel <rapatel-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
---
Ravi Patel (4):
  Documentation: mailbox: APM X-Gene SoC QMTM
  Documentation: devicetree: bindings for APM X-Gene SoC QMTM
  mailbox: xgene: base driver for APM X-Gene SoC QMTM
  arm64: boot: dts: entries for APM X-Gene SoC QMTM

 .../devicetree/bindings/mailbox/apm-xgene-qmtm.txt |   53 ++
 Documentation/mailbox/apm-xgene-qmtm.txt           |  149 ++++++
 MAINTAINERS                                        |    9 +
 arch/arm64/boot/dts/apm-storm.dtsi                 |   18 +-
 drivers/mailbox/Kconfig                            |    2 +
 drivers/mailbox/Makefile                           |    1 +
 drivers/mailbox/xgene/Kconfig                      |    9 +
 drivers/mailbox/xgene/Makefile                     |    7 +
 drivers/mailbox/xgene/xgene_qmtm_main.c            |  516 ++++++++++++++++++++
 drivers/mailbox/xgene/xgene_qmtm_main.h            |  112 +++++
 drivers/mailbox/xgene/xgene_qmtm_storm.c           |  358 ++++++++++++++
 include/linux/platform_data/xgene_qmtm.h           |  300 ++++++++++++
 12 files changed, 1533 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
 create mode 100644 Documentation/mailbox/apm-xgene-qmtm.txt
 create mode 100644 drivers/mailbox/xgene/Kconfig
 create mode 100644 drivers/mailbox/xgene/Makefile
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.c
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.h
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_storm.c
 create mode 100644 include/linux/platform_data/xgene_qmtm.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH V3 1/4] Documentation: mailbox: APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15  2:21 UTC (permalink / raw)
  To: arnd, gregkh, davem
  Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
	Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>

This patch adds documentation for APM X-Gene SoC Queue Manager/Traffic Manager.

Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
 Documentation/mailbox/apm-xgene-qmtm.txt |  149 ++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 Documentation/mailbox/apm-xgene-qmtm.txt

diff --git a/Documentation/mailbox/apm-xgene-qmtm.txt b/Documentation/mailbox/apm-xgene-qmtm.txt
new file mode 100644
index 0000000..2b4ff09
--- /dev/null
+++ b/Documentation/mailbox/apm-xgene-qmtm.txt
@@ -0,0 +1,149 @@
+AppliedMicro X-Gene SOC Queue Manager/Traffic Manager Document
+
+Copyright (c) 2013 Applied Micro Circuits Corporation.
+Author: Ravi Patel <rapatel@apm.com>
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+
+Overview:
+QMTM is a device which interacts with CPU, Ethernet, PktDMA and Security
+subsystems through AXI BUS. Its centralized resource manager/driver exports
+APIs for CPU, Ethernet, PktDMA and Security subsystems to
+1. Initialize & allocate queue & pbn.
+2. Read queue state so that subsystems driver knows how much more work it can
+   offload to its subsystem.
+3. Apply QoS for subsystems on their queues.
+
+Layout:
+The layout represents run-time flow of messages between Ethernet subsystem, CPU
+and QMTM in APM X-Gene SOC. PktDMA and Security subsystems interfaces with QMTM
+in the same way as Ethernet.
+
+
+                          CPU
+              o-------------------------o
+              |                         |
+         +----|[2]                   {5}|----+
+         |    |     [1]         {4}     |    |
+Register |    o------+-----------+------o    | Register
+Write    |    CPU WR |           | CPU RD    | Write
+to start v      MSG  v           ^  MSG      v to notify
+packet   |           |    DDR    |           | packet
+transmit |  o--------+-----o-----+--------o  | received
+         |  | Q0   M . M M | M M . M   Q1 |  |
+         |  | for  S . S S | S S . S  for |  |
+         |  | ETH  G . G G | G G . G  ETH |  |
+         |  | TX   n . 2 1 | 1 2 . n   RX |  |
+         |  o----------+---o---+----------o  |
+         |             |       |             |
+         v             v       ^             v
+         |             |       |             |
+o--------|-------------|-------|-------------|--------o
+|        |             |       |             |        | Coherent
+|        v             v       ^             v        | I/O
+|        |             |       |             |        | BUS
+o--------|-------------|-------|-------------|--------o
+         |         [3] |       | {3}         |
+         v     QMTM RD v       ^ QMTM WR     v
+         |       MSG   |       |   MSG       |
+    o----+----o--------+---o---+--------o----+----o
+    | Queue 0 |            |            | Queue 1 |
+    | Command o ETH PBN 0  o  CPU PBN 0 o Command | Queue Manager/
+    | Register|            |            |Register | Traffic Manager
+    o---------o---+--------o--------+---o---------o
+                  |                 |
+                  v                 ^
+Ethernet RD MSG   | [4]   ETH   {2} |  Ethernet WR MSG
+from its PBN  o---+-----------------+---o to CPU PBN
+              |                         |
+              | Egress MAC  Ingress MAC |
+              |     [5]         {1}     |
+              o------|-----------|------o
+                     v           ^
+                     |           |
+                  TX Data     RX Data
+
+Transmit Flow
+[1] CPU (Ethernet driver) prepares 32 byte Ethernet egress work message and
+    enqueues the message to the queue in DDR.
+[2] CPU (Ethernet driver) notifies QMTM that there is a message enqueued in
+    Ethernet transmit queue (e.g. Q0).
+[3] QMTM prefetches the Ethernet egress work messages into Ethernet PBN
+    (e.g. ETH PBN 0).
+[4] Ethernet reads work messages from its PBN.
+[5] Ethernet DMAs payload from DDR to its egress FIFO and transmits data out.
+
+Receive Flow
+{1} Ethernet receives data and DMAs payload from its ingress FIFO to DDR and
+    prepares a Ethernet ingress work message.
+{2} Ethernet pushes work message to QMTM.
+{3} QMTM prefetches the Ethernet ingress work messages into CPU PBN
+    (e.g. CPU PBN 0) and then interrupts CPU.
+{4} CPU (Ethernet driver) dequeues the 32 bytes Ethernet ingress work message
+    from the queue in DDR.
+{5} CPU (Ethernet driver) notifies QMTM that it dequeued a message from
+    Ethernet receive queue (e.g. Q1).
+
+
+Definition:
+1. QMTM (Queue/Traffic Manager)
+   QMTM manages queues and pbns for CPU, Ethernet, PktDMA and Security
+   Subsystems. It also performs flow control and QoS on queues.
+
+2. Slave/Client/Agent
+   Ethernet, PktDMA (XOR Engine) and Security Engine Subsystems & CPU whose
+   queues and pbn are managed by QMTM are called slave/client/agent.
+
+3. Queue
+   Queue is circular FIFO memory for QMTM hardware in which a 16 bytes,
+   32 bytes or 64 bytes message is dequeued OR enqueued between CPU and
+   Ethernet, PktDMA and Security Engine Subsystems.
+
+4. PB
+   Each subsystem in the APM X-Gene SoC device has a prefetch buffer for
+   storing messages in order to pipeline the QMTM processing latency with the
+   subsystem processing latency. The number of buffers prefetched depends on
+   the QM/TM processing latency and the subsystem data rate.
+
+   There are multiple PB for a subsystem, each PB is assigned a number which is
+   called PBN. Each subsystem and CPU can have max 32 pbns, however QMTM limits
+   how many pbns it supports for each subsystem.
+
+5. Message
+   The subsystems in the APM X-Gene SoC communicate with a central Queue Manager
+   (QM) that manages all the messages queued to the subsystems. The subsystems
+   communicate with the QM using messages that include information about the
+   work to be performed and the location of the buffers or data on which the
+   work is to be performed.
+
+   A message consists of 16, 32 or 64 bytes which resides in a queue. A message
+   which is
+   a. 16 bytes contains information of data buffer, length, etc. allocated by
+      subsystem driver.
+   b. 32 or 64 bytes contains information about the work to be done for a
+      subsystem. Each subsystem defines its own format of work message.
+
+   Each subsystem defines their own format of work message. A message (or queue
+   descriptor) has attribute fields (QMTM specific) which are common for all
+   subsystem work messages. The remaining fields of a message are specific to
+   subsystem. QMTM device doesn't have any knowledge of these subsystems
+   specific fields and the data operation which subsystem is going to perform
+   using these fields.
+
+   e.g.
+   1. Ethernet work message includes data address & length which is used by
+      Ethernet DMA engine for copying the data to/from its internal FIFO.
+   2. PktDMA work message includes multiple data addresses & lengths for
+      doing scatter/gather, XOR operations and result data address/es to give
+      back result to the CPU (driver).
+   3. Security work message includes data address & length for doing encryption
+      or decryption, the type of encryption or decryption and result data
+      address to give back result to the CPU (driver).
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V3 2/4] Documentation: devicetree: bindings for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15  2:22 UTC (permalink / raw)
  To: arnd, gregkh, davem
  Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
	Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>

This patch adds devicetree bindings documentation for APM X-Gene SoC Queue
Manager/Traffic Manager.

Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
 .../devicetree/bindings/mailbox/apm-xgene-qmtm.txt |   53 ++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt

diff --git a/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt b/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
new file mode 100644
index 0000000..cb17d5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
@@ -0,0 +1,53 @@
+* APM X-Gene SoC Queue Manager/Traffic Manager mailbox nodes
+
+Mailbox nodes are defined to describe on-chip Queue Managers in APM X-Gene SoC.
+APM X-Gene SoC Ethernet, PktDMA (XOR Engine), and Security Engine subsystems
+communicate with a central Queue Manager using messages which include
+information about the work to be performed and the location of the associated
+data buffers. There are multiple instances of QMTM. Each QMTM instance has its
+own node. Its corresponding clock nodes are shown below.
+
+Required properties:
+- compatible		: Shall be "apm,xgene-qmtm"
+- reg			: First memory resource shall be the QMTM register
+			  memory resource.
+			  Second memory resource shall be the QMTM IO-Fabric
+			  memory resource.
+- #mailbox-cells	: Shall be 4 as it expects following arguments
+			  First cell for 64-bit mailbox bus address MSB.
+			  Second cell for 64-bit mailbox bus address LSB.
+			  Third cell for 32-bit mailbox size.
+			  Fourth cell for 32-bit mailbox signal/id value.
+- interrupts		: First interrupt resource shall be the QMTM Error
+			  interrupt.
+			  Remaining interrupt resources shall be the Ingress
+			  work message interrupt mapping for receiver,
+			  receiving work messages for the QMTM.
+- clocks		: Reference to the clock entry.
+
+Optional properties:
+- status		: Shall be "ok" if enabled or "disabled" if disabled.
+			  Default is "ok".
+
+Example:
+		qmlclk: qmlclk {
+			compatible = "apm,xgene-device-clock";
+			#clock-cells = <1>;
+			clock-names = "socplldiv2";
+			status = "ok";
+			csr-offset = <0x0>;
+			csr-mask = <0x3>;
+			enable-offset = <0x8>;
+			enable-mask = <0x3>;
+		};
+
+		qmlite: mailbox@17030000 {
+			compatible = "apm,xgene-qmtm";
+			#mailbox-cells = <4>;
+			status = "ok";
+			reg = <0x0 0x17030000 0x0 0x10000>,
+			      <0x0 0x10000000 0x0 0x400000>;
+			interrupts = <0x0 0x40 0x4>,
+				     <0x0 0x3c 0x4>;
+			clocks = <&qmlclk 0>;
+		};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V3 3/4] mailbox: xgene: base driver for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15  2:22 UTC (permalink / raw)
  To: arnd, gregkh, davem
  Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
	Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>

This patch adds APM X-Gene SoC Queue Manager/Traffic Manager base driver.
QMTM is requried by Ethernet, PktDMA (XOR Engine) and Security subsystems.

Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
 MAINTAINERS                              |    9 +
 drivers/mailbox/Kconfig                  |    2 +
 drivers/mailbox/Makefile                 |    1 +
 drivers/mailbox/xgene/Kconfig            |    9 +
 drivers/mailbox/xgene/Makefile           |    7 +
 drivers/mailbox/xgene/xgene_qmtm_main.c  |  516 ++++++++++++++++++++++++++++++
 drivers/mailbox/xgene/xgene_qmtm_main.h  |  112 +++++++
 drivers/mailbox/xgene/xgene_qmtm_storm.c |  358 +++++++++++++++++++++
 include/linux/platform_data/xgene_qmtm.h |  300 +++++++++++++++++
 9 files changed, 1314 insertions(+)
 create mode 100644 drivers/mailbox/xgene/Kconfig
 create mode 100644 drivers/mailbox/xgene/Makefile
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.c
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.h
 create mode 100644 drivers/mailbox/xgene/xgene_qmtm_storm.c
 create mode 100644 include/linux/platform_data/xgene_qmtm.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2507f38..3e09f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -678,6 +678,15 @@ S:	Maintained
 F:	drivers/net/appletalk/
 F:	net/appletalk/
 
+APPLIEDMICRO (APM) X-GENE SOC QUEUE MANAGER/TRAFFIC MANAGER (QMTM) DRIVER
+M:	Ravi Patel <rapatel@apm.com>
+M:	Keyur Chudgar <kchudgar@apm.com>
+S:	Maintained
+F:	drivers/mailbox/xgene/
+F:	include/linux/platform_data/xgene_qmtm.h
+F:	Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
+F:	Documentation/mailbox/apm-xgene-qmtm
+
 APTINA CAMERA SENSOR PLL
 M:	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
 L:	linux-media@vger.kernel.org
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c8b5c13..52653d4 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -50,4 +50,6 @@ config OMAP_MBOX_KFIFO_SIZE
 	  Specify the default size of mailbox's kfifo buffers (bytes).
 	  This can also be changed at runtime (via the mbox_kfifo_size
 	  module parameter).
+
+source "drivers/mailbox/xgene/Kconfig"
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index e0facb3..6faee7e 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_OMAP1_MBOX)	+= mailbox_omap1.o
 mailbox_omap1-objs		:= mailbox-omap1.o
 obj-$(CONFIG_OMAP2PLUS_MBOX)	+= mailbox_omap2.o
 mailbox_omap2-objs		:= mailbox-omap2.o
+obj-$(CONFIG_XGENE_MBOX)	+= xgene/
diff --git a/drivers/mailbox/xgene/Kconfig b/drivers/mailbox/xgene/Kconfig
new file mode 100644
index 0000000..0843303
--- /dev/null
+++ b/drivers/mailbox/xgene/Kconfig
@@ -0,0 +1,9 @@
+config XGENE_MBOX
+	tristate "APM X-Gene Queue Manager/Traffic Manager Mailbox"
+	depends on ARM64 || COMPILE_TEST
+	default y
+	help
+	  This option enables APM X-Gene Queue Manager Traffic Manager (QMTM)
+	  mailbox support.
+	  QMTM is required for Ethernet, PktDMA (XOR Engine) and Security
+	  Engine.
diff --git a/drivers/mailbox/xgene/Makefile b/drivers/mailbox/xgene/Makefile
new file mode 100644
index 0000000..574e1b8
--- /dev/null
+++ b/drivers/mailbox/xgene/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for APM X-GENE Queue Manager Traffic Manager mailbox
+#
+
+obj-$(CONFIG_XGENE_MBOX) += xgene-qmtm.o
+
+xgene-qmtm-objs := xgene_qmtm_main.o xgene_qmtm_storm.o
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.c b/drivers/mailbox/xgene/xgene_qmtm_main.c
new file mode 100644
index 0000000..bc50cd9
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.c
@@ -0,0 +1,516 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ *         Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include "xgene_qmtm_main.h"
+
+#define XGENE_QMTM_DRIVER_VER	"1.0"
+#define XGENE_QMTM_DRIVER_NAME	"xgene-qmtm"
+#define XGENE_QMTM_DRIVER_DESC	"APM X-Gene QMTM driver"
+
+/* CSR Address Macros */
+#define CSR_QM_CONFIG_ADDR	0x00000004
+#define  QM_ENABLE_WR(src)	(((u32)(src)<<31) & 0x80000000)
+
+#define CSR_PBM_ADDR		0x00000008
+#define  OVERWRITE_WR(src)	(((u32)(src)<<31) & 0x80000000)
+#define  SLVID_PBN_WR(src)	(((u32)(src)) & 0x000003ff)
+
+#define CSR_PBM_BUF_WR_ADDR	0x0000000c
+#define CSR_PBM_BUF_RD_ADDR	0x00000010
+#define  PB_SIZE_WR(src)	(((u32)(src)<<31) & 0x80000000)
+#define  PREFETCH_BUF_EN_SET(dst, src) \
+	(((dst) & ~0x00200000) | (((u32)(src)<<21) & 0x00200000))
+#define  IS_FREE_POOL_SET(dst, src) \
+	(((dst) & ~0x00100000) | (((u32)(src)<<20) & 0x00100000))
+#define  TLVQ_SET(dst, src) \
+	(((dst) & ~0x00080000) | (((u32)(src)<<19) & 0x00080000))
+#define  CORRESPONDING_QNUM_SET(dst, src) \
+	(((dst) & ~0x0007fe00) | (((u32)(src)<<9) & 0x0007fe00))
+
+#define CSR_THRESHOLD0_SET1_ADDR	0x00000030
+#define CSR_THRESHOLD1_SET1_ADDR	0x00000034
+#define CSR_HYSTERESIS_ADDR		0x00000068
+#define CSR_QM_MBOX_NE_INT_MODE_ADDR	0x0000017c
+#define CSR_QMLITE_PBN_MAP_0_ADDR	0x00000228
+
+#define CSR_RECOMB_CTRL_0_ADDR		0x00000230
+#define  RECOMB_EN0_SET(dst, src) \
+	(((dst) & ~0x00000001) | (((u32)(src)) & 0x00000001))
+
+/* QMTM Diag CSR */
+#define QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET	0xd000
+#define QM_CFG_MEM_RAM_SHUTDOWN_ADDR		0x00000070
+#define QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT		0xffffffff
+
+static struct of_device_id xgene_qmtm_match[] = {
+	{
+		.compatible = "apm,xgene-qmtm",
+		.data = &storm_qmtm_ops,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, xgene_qmtm_match);
+
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data)
+{
+	writel(data, qmtm->csr_vaddr + offset);
+}
+
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data)
+{
+	*data = readl(qmtm->csr_vaddr + offset);
+}
+
+static void xgene_qmtm_pbm_get(struct xgene_mbox *mbox)
+{
+	u16 is_fp = QMTM_QTYPE_FP(mbox);
+	u16 is_vq = QMTM_QTYPE_VQ(mbox);
+	u32 val = 0;
+	u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+
+	if (mbox->qmtm->qmtm_ip == QMTM0 || mbox->qmtm->qmtm_ip == QMTM2)
+		val |= PB_SIZE_WR(1);
+
+	val = CORRESPONDING_QNUM_SET(val, mbox->qid);
+	val = IS_FREE_POOL_SET(val, is_fp);
+	val = TLVQ_SET(val, is_vq);
+	val = PREFETCH_BUF_EN_SET(val, 1);
+	xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+	xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, val);
+}
+
+static void xgene_qmtm_pbm_put(struct xgene_mbox *mbox)
+{
+	u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+	xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+	xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, 0);
+}
+
+/**
+ * xgene_mbox_get - Create and configure a queue
+ * @dev: device that requests this queue
+ * @s: the queue name string as given in the dt data
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to create and configure a queue.
+ *
+ * Returns the mbox associated with the given phandle value,
+ * after getting a refcount to it, -ENODEV if there is no such queue,
+ * -ENOMEM if out of memory or -EINVAL for other error conditions.
+ * The caller is responsible for calling xgene_mbox_put() to release
+ * that count.
+ */
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s)
+{
+	struct module *module = THIS_MODULE;
+	struct xgene_mbox *mbox = ERR_PTR(-EINVAL);
+	struct xgene_qmtm *qmtm;
+	int ret;
+	struct of_phandle_args args;
+	u64 qfabric_paddr;
+	u32 qsize = 0;
+	u16 qid = 0;
+	u8 cfgqsize;
+
+	if (!dev->of_node) {
+		dev_err(dev, "Invalid device tree\n");
+		goto _err_mbox_get;
+	}
+
+	ret = of_property_match_string(dev->of_node, "mailbox-names", s);
+	if (ret < 0) {
+		mbox = ERR_PTR(-ENODEV);
+		goto _err_mbox_get;
+	}
+
+	memset(&args, 0, sizeof(args));
+	ret = of_parse_phandle_with_args(dev->of_node, "mailboxes",
+			"#mailbox-cells", ret, &args);
+	if (ret || !args.np) {
+		dev_err(dev, "failed to get mailbox in %s node\n",
+				dev->of_node->full_name);
+		goto _err_mbox_get;
+	}
+
+	if (!try_module_get(module))
+		goto _err_mbox_get;
+
+	qmtm = platform_get_drvdata(of_find_device_by_node(args.np));
+	if (qmtm == NULL) {
+		dev_err(dev, "failed to get QMTM for %s node\n",
+				dev->of_node->full_name);
+		goto _module_put;
+	}
+
+	qfabric_paddr = ((u64)args.args[0] << 32) | args.args[1];
+	if (qfabric_paddr > (qmtm->fabric_paddr |
+				((u64)(QMTM_MAX_QUEUES - 1) << 6)) ||
+			qfabric_paddr < qmtm->fabric_paddr) {
+		dev_err(dev, "Invalid qfabric address for %s node\n",
+				dev->of_node->full_name);
+		goto _module_put;
+	}
+	qid = (qfabric_paddr - qmtm->fabric_paddr) >> 6;
+
+	qsize = args.args[2];
+	switch (qsize) {
+	case 0x00200:
+		cfgqsize = QSIZE_512B;
+		break;
+	case 0x00800:
+		cfgqsize = QSIZE_2KB;
+		break;
+	case 0x04000:
+		cfgqsize = QSIZE_16KB;
+		break;
+	case 0x10000:
+		cfgqsize = QSIZE_64KB;
+		break;
+	case 0x80000:
+		cfgqsize = QSIZE_512KB;
+		break;
+	default:
+		dev_err(dev, "Unsupported queue size %d\n", qsize);
+		goto _module_put;
+	}
+
+	mbox = kzalloc(sizeof(struct xgene_mbox), GFP_KERNEL);
+	if (mbox == NULL) {
+		dev_err(dev, "Unable to allocate mbox\n");
+		goto _module_put;
+	}
+
+	mbox->qaddr = dma_zalloc_coherent(&qmtm->pdev->dev, qsize,
+		&mbox->dma, GFP_KERNEL);
+	if (mbox->qaddr == NULL) {
+		dev_err(dev, "Unable to allocate qaddr\n");
+		kfree(mbox);
+		mbox = NULL;
+		goto _module_put;
+	}
+	mbox->qsize = qsize;
+	mbox->pbm = args.args[3];
+	mbox->qid = qid;
+	mbox->slots = cfgqsize;
+	mbox->qfabric = qmtm->fabric_vaddr + (qid << 6);
+	mbox->level = mbox->qfabric + 0x2C;
+	mbox->qmtm = qmtm;
+	qmtm->ops.set_qstate(mbox);
+	xgene_qmtm_pbm_get(mbox);
+	mbox->slots = QMTM_QTYPE_FP(mbox) ? qsize / 16 : qsize / 32;
+	mbox->qstate[6] = qmtm->qmtm_ip;
+
+	if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+			!QMTM_QTYPE_FP(mbox) &&
+			!QMTM_QTYPE_VQ(mbox)) {
+		u32 s, data;
+		for (s = 0; s < mbox->slots; s++) {
+			u32 *slot = (u32 *)&mbox->msg32[s];
+			slot[EMPTY_SLOT_INDEX] = EMPTY_SLOT;
+		}
+		xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+		data |= (u32) (1 << (31 - QMTM_PBN(mbox)));
+		xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+		mbox->irq = qmtm->dequeue_irq[QMTM_PBN(mbox)];
+	}
+
+	qmtm->mbox[qid] = mbox;
+	return mbox;
+
+_module_put:
+	module_put(module);
+
+_err_mbox_get:
+	return mbox;
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_get);
+
+/**
+ * xgene_mbox_put - Unconfigure and delete a queue
+ * @mbox: the mbox returned by xgene_mbox_get()
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to unconfigure and delete a queue.
+ *
+ * Releases a refcount the caller received from xgene_mbox_get().
+ */
+void xgene_mbox_put(struct xgene_mbox *mbox)
+{
+	struct xgene_qmtm *qmtm = mbox->qmtm;
+	struct module *module = THIS_MODULE;
+
+	if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+			!QMTM_QTYPE_FP(mbox) &&
+			!QMTM_QTYPE_VQ(mbox)) {
+		u32 data;
+		xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+		data &= ~(u32) (1 << (31 - QMTM_PBN(mbox)));
+		xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+	}
+
+	xgene_qmtm_pbm_put(mbox);
+	qmtm->ops.clr_qstate(mbox);
+	dma_free_coherent(&qmtm->pdev->dev, mbox->qsize,
+		mbox->qaddr, mbox->dma);
+	qmtm->mbox[mbox->qid] = NULL;
+	kfree(mbox);
+	module_put(module);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_put);
+
+/**
+ * xgene_mbox_level - Read number of message in queue
+ * @mbox: read number of message for mbox
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to read number of message for mbox.
+ *
+ * Returns number of messages in mbox
+ */
+u32 xgene_mbox_level(struct xgene_mbox *mbox)
+{
+	return mbox->qmtm->ops.read_level(mbox->qfabric);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_level);
+
+static int xgene_qmtm_enable(struct xgene_qmtm *qmtm)
+{
+	struct xgene_mbox mbox;
+	struct device *dev = &qmtm->pdev->dev;
+	int rc, mwait = 0, inum = 1;
+	u32 val;
+	u32 qid;
+
+	qmtm->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(qmtm->clk)) {
+		dev_err(dev, "can't get clock\n");
+		return PTR_ERR(qmtm->clk);
+	}
+
+	rc = clk_prepare_enable(qmtm->clk);
+	if (rc < 0) {
+		dev_err(dev, "clock prepare enable failed\n");
+		return rc;
+	}
+
+	xgene_qmtm_wr32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+			QM_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
+	do {
+		/* Wait for Memory to come out of shutdown */
+		usleep_range(1000, 2000);
+		xgene_qmtm_rd32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+				QM_CFG_MEM_RAM_SHUTDOWN_ADDR, &val);
+
+		if (mwait++ >= 1000) {
+			rc = -EIO;
+			dev_err(dev, "RAM not out of shutdown %d\n", rc);
+			clk_disable_unprepare(qmtm->clk);
+			return rc;
+		}
+	} while (val == QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT);
+
+	rc = qmtm->ops.init(qmtm);
+	if (rc < 0) {
+		dev_err(dev, "not supported on your system\n");
+		return rc;
+	}
+
+	for (inum = qmtm->irq_start; inum < (qmtm->irq_start +
+				qmtm->irq_count); inum++) {
+		int irq = platform_get_irq(qmtm->pdev,
+			inum - qmtm->irq_start + 1);
+		if (irq < 0) {
+			dev_err(dev, "Failed to map QMTM%d PBN %d IRQ\n",
+				qmtm->qmtm_ip, inum);
+			continue;
+		}
+		qmtm->dequeue_irq[inum] = irq;
+	}
+
+	switch (qmtm->qmtm_ip) {
+	case QMTM0:
+	case QMTM2:
+		xgene_qmtm_rd32(qmtm, CSR_RECOMB_CTRL_0_ADDR, &val);
+		val = RECOMB_EN0_SET(val, 1);
+		xgene_qmtm_wr32(qmtm, CSR_RECOMB_CTRL_0_ADDR, val);
+		break;
+	case QMTM3:
+		xgene_qmtm_wr32(qmtm, CSR_QMLITE_PBN_MAP_0_ADDR, 0x00000000);
+	}
+
+	/* program threshold set 1 and all hysteresis */
+	xgene_qmtm_wr32(qmtm, CSR_THRESHOLD0_SET1_ADDR, 100);
+	xgene_qmtm_wr32(qmtm, CSR_THRESHOLD1_SET1_ADDR, 200);
+	xgene_qmtm_wr32(qmtm, CSR_HYSTERESIS_ADDR, 0xFFFFFFFF);
+
+	/* Enable QPcore */
+	xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(1));
+
+	/* Clear all HW queue state in case they were not de-activated */
+	memset(&mbox, 0, sizeof(mbox));
+	mbox.qmtm = qmtm;
+
+	for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+		mbox.qid = qid;
+		qmtm->ops.clr_qstate(&mbox);
+	}
+
+	return rc;
+}
+
+static int xgene_qmtm_disable(struct xgene_qmtm *qmtm)
+{
+	u32 qid;
+
+	for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+		if (qmtm->mbox[qid]) {
+			dev_err(&qmtm->pdev->dev,
+				"QMTM %d Queue ID %d Resource in use\n",
+				qmtm->qmtm_ip, qid);
+			return -EAGAIN;
+		}
+	}
+
+	/* Disable QPcore */
+	xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(0));
+	clk_disable_unprepare(qmtm->clk);
+
+	return 0;
+}
+
+static struct xgene_qmtm *xgene_alloc_qmtm(struct platform_device *pdev)
+{
+	struct xgene_qmtm *qmtm;
+
+	qmtm = devm_kzalloc(&pdev->dev, sizeof(struct xgene_qmtm), GFP_KERNEL);
+	if (qmtm == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate QMTM context\n");
+		return NULL;
+	}
+
+	qmtm->pdev = pdev;
+	platform_set_drvdata(pdev, qmtm);
+	qmtm->mbox = devm_kzalloc(&pdev->dev,
+		QMTM_MAX_QUEUES * (sizeof(struct xgene_qmtm_info *)),
+		GFP_KERNEL);
+	if (qmtm->mbox == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate QMTM Queue context\n");
+		return NULL;
+	}
+
+	return qmtm;
+}
+
+static int xgene_get_qmtm(struct xgene_qmtm *qmtm)
+{
+	struct platform_device *pdev = qmtm->pdev;
+	const struct of_device_id *match;
+	struct resource *res;
+
+	/* Get Match Table */
+	match = of_match_device(xgene_qmtm_match, &pdev->dev);
+	if (!match)
+		return -EINVAL;
+	memcpy(&qmtm->ops, match->data, sizeof(struct xgene_qmtm_ops));
+
+	/* Retrieve QM CSR register address and size */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get QMTM CSR region\n");
+		return -ENODEV;
+	}
+
+	qmtm->csr_vaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(qmtm->csr_vaddr)) {
+		dev_err(&pdev->dev, "Invalid QMTM CSR region\n");
+		return PTR_ERR(qmtm->csr_vaddr);
+	}
+
+	/* Retrieve Primary Fabric address and size */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get QMTM Fabric region\n");
+		return -ENODEV;
+	}
+
+	qmtm->fabric_vaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(qmtm->fabric_vaddr)) {
+		dev_err(&pdev->dev, "Invalid QMTM Fabric region\n");
+		return PTR_ERR(qmtm->fabric_vaddr);
+	}
+	qmtm->fabric_paddr = res->start;
+
+	if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
+		return dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+	return 0;
+}
+
+static int xgene_qmtm_probe(struct platform_device *pdev)
+{
+	struct xgene_qmtm *qmtm;
+	int rc;
+
+	qmtm = xgene_alloc_qmtm(pdev);
+	if (qmtm == NULL)
+		return -ENOMEM;
+
+	rc = xgene_get_qmtm(qmtm);
+	if (rc)
+		return rc;
+
+	return xgene_qmtm_enable(qmtm);
+}
+
+static int xgene_qmtm_remove(struct platform_device *pdev)
+{
+	struct xgene_qmtm *qmtm = platform_get_drvdata(pdev);
+	return xgene_qmtm_disable(qmtm);
+}
+
+static struct platform_driver xgene_qmtm_driver = {
+	.driver = {
+		   .name = XGENE_QMTM_DRIVER_NAME,
+		   .owner = THIS_MODULE,
+		   .of_match_table = xgene_qmtm_match,
+		   },
+	.probe = xgene_qmtm_probe,
+	.remove = xgene_qmtm_remove,
+};
+
+static int __init xgene_qmtm_init(void)
+{
+	return platform_driver_register(&xgene_qmtm_driver);
+}
+subsys_initcall(xgene_qmtm_init);
+
+static void __exit xgene_qmtm_exit(void)
+{
+	platform_driver_unregister(&xgene_qmtm_driver);
+}
+module_exit(xgene_qmtm_exit);
+
+MODULE_VERSION(XGENE_QMTM_DRIVER_VER);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ravi Patel <rapatel@apm.com>");
+MODULE_DESCRIPTION(XGENE_QMTM_DRIVER_DESC);
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.h b/drivers/mailbox/xgene/xgene_qmtm_main.h
new file mode 100644
index 0000000..1a9de03
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.h
@@ -0,0 +1,112 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ *         Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XGENE_QMTM_MAIN_H__
+#define __XGENE_QMTM_MAIN_H__
+
+#include <linux/of_platform.h>
+#include <linux/platform_data/xgene_qmtm.h>
+
+/* QMTM IP Blocks */
+enum xgene_qmtm_ip {
+	QMTM0,
+	QMTM1,
+	QMTM2,
+	QMTM3,
+};
+
+#define QMTM_MAX_QUEUES	1024
+#define QMTM_MAX_PBN	32
+
+/* QMTM Queue types */
+enum xgene_qmtm_qtype {
+	QTYPE_DISABLED,		/* Queue Type is un-configured or disabled */
+	QTYPE_PQ,		/* Queue Type is Physical Work Queue */
+	QTYPE_FP,		/* Queue Type is Free Pool Queue */
+	QTYPE_VQ,		/* Queue Type is Virtual Queue */
+};
+
+/* QMTM Queue possible sizes */
+enum xgene_qmtm_qsize {
+	QSIZE_512B,
+	QSIZE_2KB,
+	QSIZE_16KB,
+	QSIZE_64KB,
+	QSIZE_512KB,
+	QSIZE_MAX,
+};
+
+struct xgene_qmtm_ops {
+	int (*init)(struct xgene_qmtm *qmtm);
+	void (*set_qstate)(struct xgene_mbox *mbox);
+	void (*clr_qstate)(struct xgene_mbox *mbox);
+	u32 (*read_level)(void *qfabric);
+};
+
+struct xgene_qmtm {
+	struct xgene_qmtm_ops ops;
+	void *csr_vaddr;
+	void *fabric_vaddr;
+	u64 fabric_paddr;
+	u16 qmtm_ip;		/* qmtm_ip, see xgene_qmtm_ip */
+	u16 irq_start;
+	u16 irq_count;
+	u16 error_irq;
+	u16 dequeue_irq[QMTM_MAX_PBN];
+	char error_irq_s[16];
+	char error_queue_irq_s[16];
+	struct xgene_mbox *(*mbox);
+	struct xgene_mbox *error_mbox;
+	struct clk *clk;
+	struct platform_device *pdev;
+};
+
+/* QMTM Slave IDs */
+enum xgene_qmtm_slave_id {
+	QMTM_SLAVE_ID_ETH0,
+	QMTM_SLAVE_ID_ETH1,
+	QMTM_SLAVE_ID_RES2,
+	QMTM_SLAVE_ID_PKTDMA,
+	QMTM_SLAVE_ID_CTX,
+	QMTM_SLAVE_ID_SEC,
+	QMTM_SLAVE_ID_CLASS,
+	QMTM_SLAVE_ID_MSLIM,
+	QMTM_SLAVE_ID_RES8,
+	QMTM_SLAVE_ID_RES9,
+	QMTM_SLAVE_ID_RESA,
+	QMTM_SLAVE_ID_RESB,
+	QMTM_SLAVE_ID_RESC,
+	QMTM_SLAVE_ID_PMPRO,
+	QMTM_SLAVE_ID_SMPRO,
+	QMTM_SLAVE_ID_CPU,
+	QMTM_SLAVE_ID_MAX,
+};
+
+/* QMTM Free Pool Queue modes */
+enum xgene_qmtm_fp_mode {
+	MSG_NO_CHANGE,
+	ROUND_ADDR,
+	REDUCE_LEN,
+	CHANGE_LEN,
+};
+
+extern struct xgene_qmtm_ops storm_qmtm_ops;
+/* QMTM CSR read/write routine */
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data);
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data);
+
+#endif /* __XGENE_QMTM_MAIN_H__ */
diff --git a/drivers/mailbox/xgene/xgene_qmtm_storm.c b/drivers/mailbox/xgene/xgene_qmtm_storm.c
new file mode 100644
index 0000000..e214d28
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_storm.c
@@ -0,0 +1,358 @@
+/**
+ * AppliedMicro X-Gene SOC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ *         Keyur Chudgar <kchudgar@apm.com>
+ *         Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include "xgene_qmtm_main.h"
+
+#define CSR_IPBRR_ADDR		0x00000000
+#define CSR_IPBRR_QMTM0_DEFAULT	0x00000520
+#define CSR_IPBRR_QMTM1_DEFAULT	0x00000521
+#define CSR_IPBRR_QMTM2_DEFAULT	0x00000522
+#define CSR_IPBRR_QMTM3_DEFAULT	0x000005E0
+
+#define CSR_QSTATE_ADDR		0x0000006c
+#define QNUMBER_WR(src)		(((u32)(src)) & 0x000003ff)
+
+#define CSR_QSTATE_WR_0_ADDR	0x00000070
+#define CSR_QSTATE_WR_1_ADDR	0x00000074
+#define CSR_QSTATE_WR_2_ADDR	0x00000078
+#define CSR_QSTATE_WR_3_ADDR	0x0000007c
+#define CSR_QSTATE_WR_4_ADDR	0x00000080
+
+/* QMTM Queue State */
+struct storm_qmtm_csr_qstate {
+	u32 w0;
+	u32 w1;
+	u32 w2;
+	u32 w3;
+	u32 w4;
+} __packed;
+
+/*
+ * Physical or free pool queue state (pq or fp)
+ */
+struct storm_qmtm_pq_fp_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	/* register word 0 (bit 31:0) */
+	u32 cpu_notify:8;           /* 31:24 */
+	u32 cfgsaben:1;             /* 23 enable SAB broadcasting */
+	u32 cfgtmvq:10;             /* 22:13 parent vq */
+	u32 cfgtmvqen:1;            /* 12 enable pq to belong to vq */
+	u32 resize_done:1;          /* 11 */
+	u32 resize_start:1;         /* 10 */
+	u32 resize_qid:10;          /* 9:0 */
+
+	/* register word 1 (bit 63:32) */
+	u32 headptr:15;             /* 63:49 */
+	u32 nummsg:16;              /* 48:33 */
+	u32 cfgnotifyqne:1;         /* 32 enable Q not empty intr */
+
+	/* register word 2 (bit 95:64) */
+	u32 cfgstartaddrL:27;       /* 95:69 split 7/27 */
+	u32 qcoherent:1;            /* 68 */
+	u32 rid:3;                  /* 67:65 */
+	u32 cfgcrid:1;              /* 64 */
+
+	/* register word 3 (bit 127:96) */
+	u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+	u32 cfgRecombBuf:1;         /* 123 */
+	u32 qstatelock:1;           /* 122 */
+	u32 cfgqsize:3;             /* 121:119 queue size */
+	u32 fp_mode:3;              /* 118:116 free pool mode */
+	u32 cfgacceptlerr:1;        /* 115 */
+	u32 reserved_0:1;           /* 114 */
+	u32 stashing:1;             /* 113 */
+	u32 slot_pending:8;         /* 112:105 */
+	u32 vc_chanid:2;            /* 104:103 */
+	u32 cfgstartaddrH:7;        /* 102:96 split 7/27 */
+
+	/* register word 4 (bit 159:128) */
+	u32 resv1:11;               /* 159:149 */
+	u32 cfgqtype:2;             /* 148:147 queue type */
+	u32 resv2:5;                /* 146:142 */
+	u32 half_64B_override:3;    /* 141:139 */
+	u32 resv3:4;                /* 138:135 */
+	u32 CfgSupressCmpl:1;       /* 134 */
+	u32 cfgselthrsh:3;          /* 133:131 associated threshold set */
+	u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+#else
+	/* register word 0 (bit 31:0) */
+	u32 resize_qid:10;          /* 9:0 */
+	u32 resize_start:1;         /* 10 */
+	u32 resize_done:1;          /* 11 */
+	u32 cfgtmvqen:1;            /* 12 enable pq to belong to vq */
+	u32 cfgtmvq:10;             /* 22:13 parent vq */
+	u32 cfgsaben:1;             /* 23 enable SAB broadcasting */
+	u32 cpu_notify:8;           /* 31:24 */
+
+	/* register word 1 (bit 63:32) */
+	u32 cfgnotifyqne:1;         /* 32 enable Q not empty intr */
+	u32 nummsg:16;              /* 48:33 */
+	u32 headptr:15;             /* 63:49 */
+
+	/* register word 2 (bit 95:64) */
+	u32 cfgcrid:1;              /* 64 */
+	u32 rid:3;                  /* 67:65 */
+	u32 qcoherent:1;            /* 68 */
+	u32 cfgstartaddrL:27;       /* 95:69 split 7/27 */
+
+	/* register word 3 (bit 127:96) */
+	u32 cfgstartaddrH:7;        /* 102:96 split 7/27 */
+	u32 vc_chanid:2;            /* 104:103 */
+	u32 slot_pending:8;         /* 112:105 */
+	u32 stashing:1;             /* 113 */
+	u32 reserved_0:1;           /* 114 */
+	u32 cfgacceptlerr:1;        /* 115 */
+	u32 fp_mode:3;              /* 118:116 free pool mode */
+	u32 cfgqsize:3;             /* 121:119 queue size */
+	u32 qstatelock:1;           /* 122 */
+	u32 cfgRecombBuf:1;         /* 123 */
+	u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+
+	/* register word 4 (bit 159:128) */
+	u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+	u32 cfgselthrsh:3;          /* 133:131 associated threshold set */
+	u32 CfgSupressCmpl:1;       /* 134 */
+	u32 resv3:4;                /* 138:135 */
+	u32 half_64B_override:3;    /* 141:139 */
+	u32 resv2:5;                /* 146:142 */
+	u32 cfgqtype:2;             /* 148:147 queue type */
+	u32 resv1:11;               /* 159:149 */
+#endif
+} __packed;
+
+/*
+ * Virtual queue state (vq)
+ */
+struct storm_qmtm_vq_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	/* register word 0 (bit 31:0) */
+	u32 rid:3;          /* 31:29 */
+	u32 cpu_notify:8;   /* 28:21 */
+	u32 cfgcrid:1;      /* 20 critical rid config */
+	u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+	u32 cfgsaben:1;     /* 18 enable SAB broadcasting */
+	u32 nummsg:18;      /* 17:0 */
+
+	/* register word 1 (bit 63:32) */
+	u32 q5reqvld:1;     /* 63 */
+	u32 q5txallowed:1;  /* 62 */
+	u32 q5selarb:2;     /* 61:60 */
+	u32 q6_sel:10;      /* 59:50 */
+	u32 q6reqvld:1;     /* 49 */
+	u32 q6txallowed:1;  /* 48 */
+	u32 q6selarb:2;     /* 47:46 */
+	u32 q7_sel:10;      /* 45:36 */
+	u32 q7reqvld:1;     /* 35 */
+	u32 q7txallowed:1;  /* 34 */
+	u32 q7selarb:2;     /* 33:32 */
+
+	/* register word 2 (bit 95:64) */
+	u32 q3_selL:4;      /* 95:92 split 4/6 */
+	u32 q3reqvld:1;     /* 91 */
+	u32 q3txallowed:1;  /* 90 */
+	u32 q3selarb:2;     /* 89:88 */
+	u32 q4_sel:10;      /* 87:78 */
+	u32 q4reqvld:1;     /* 77 */
+	u32 q4txallowed:1;  /* 76 */
+	u32 q4selarb:2;     /* 75:74 */
+	u32 q5_sel:10;      /* 73:64 */
+
+	/* register word 3 (bit 127:96) */
+	u32 q1_selL:8;      /* 127:120 split 2/8 */
+	u32 q1reqvld:1;     /* 119 */
+	u32 q1txallowed:1;  /* 118 */
+	u32 q1selarb:2;     /* 117:116 */
+	u32 q2_sel:10;      /* 115:106 */
+	u32 q2reqvld:1;     /* 105 */
+	u32 q2txallowed:1;  /* 104 */
+	u32 q2selarb:2;     /* 103:102 */
+	u32 q3_selH:6;      /* 101:96 split 4/6 */
+
+	/* register word 4 (bit 159:128) */
+	u32 resv1:11;       /* 159:149 */
+	u32 cfgqtype:2;     /* 148:147 queue type */
+	u32 cfgselthrsh:3;  /* 146:144 associated threshold set */
+	u32 q0_sel:10;      /* 143:134 */
+	u32 q0reqvld:1;     /* 133 */
+	u32 q0txallowed:1;  /* 132 */
+	u32 q0selarb:2;     /* 131:130 */
+	u32 q1_selH:2;      /* 129:128 split 2/8 */
+#else
+	/* register word 0 (bit 31:0) */
+	u32 nummsg:18;      /* 17:0 */
+	u32 cfgsaben:1;     /* 18 enable SAB broadcasting */
+	u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+	u32 cfgcrid:1;      /* 20 critical rid config */
+	u32 cpu_notify:8;   /* 28:21 */
+	u32 rid:3;          /* 31:29 */
+
+	/* register word 1 (bit 63:32) */
+	u32 q7selarb:2;     /* 33:32 */
+	u32 q7txallowed:1;  /* 34 */
+	u32 q7reqvld:1;     /* 35 */
+	u32 q7_sel:10;      /* 45:36 */
+	u32 q6selarb:2;     /* 47:46 */
+	u32 q6txallowed:1;  /* 48 */
+	u32 q6reqvld:1;     /* 49 */
+	u32 q6_sel:10;      /* 59:50 */
+	u32 q5selarb:2;     /* 61:60 */
+	u32 q5txallowed:1;  /* 62 */
+	u32 q5reqvld:1;     /* 63 */
+
+	/* register word 2 (bit 95:64) */
+	u32 q5_sel:10;      /* 73:64 */
+	u32 q4selarb:2;     /* 75:74 */
+	u32 q4txallowed:1;  /* 76 */
+	u32 q4reqvld:1;     /* 77 */
+	u32 q4_sel:10;      /* 87:78 */
+	u32 q3selarb:2;     /* 89:88 */
+	u32 q3txallowed:1;  /* 90 */
+	u32 q3reqvld:1;     /* 91 */
+	u32 q3_selL:4;      /* 95:92 split 4/6 */
+
+	/* register word 3 (bit 127:96) */
+	u32 q3_selH:6;      /* 101:96 split 4/6 */
+	u32 q2selarb:2;     /* 103:102 */
+	u32 q2txallowed:1;  /* 104 */
+	u32 q2reqvld:1;     /* 105 */
+	u32 q2_sel:10;      /* 115:106 */
+	u32 q1selarb:2;     /* 117:116 */
+	u32 q1txallowed:1;  /* 118 */
+	u32 q1reqvld:1;     /* 119 */
+	u32 q1_selL:8;      /* 127:120 split 2/8 */
+
+	/* register word 4 (bit 159:128) */
+	u32 q1_selH:2;      /* 129:128 split 2/8 */
+	u32 q0selarb:2;     /* 131:130 */
+	u32 q0txallowed:1;  /* 132 */
+	u32 q0reqvld:1;     /* 133 */
+	u32 q0_sel:10;      /* 143:134 */
+	u32 cfgselthrsh:3;  /* 146:144 associated threshold set */
+	u32 cfgqtype:2;     /* 148:147 queue type */
+	u32 resv1:11;       /* 159:149 */
+#endif
+} __packed;
+
+union storm_qmtm_qstate {
+	struct storm_qmtm_csr_qstate csr;
+	struct storm_qmtm_pq_fp_qstate pq;
+	struct storm_qmtm_pq_fp_qstate fp;
+	struct storm_qmtm_vq_qstate vq;
+} __packed;
+
+/* Storm QMTM operations */
+static void storm_qmtm_write_qstate(struct xgene_mbox *mbox)
+{
+	struct xgene_qmtm *qmtm = mbox->qmtm;
+	struct storm_qmtm_csr_qstate *csr_qstate =
+	    &((union storm_qmtm_qstate *)mbox->qstate)->csr;
+
+	/* write queue number */
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_ADDR, QNUMBER_WR(mbox->qid));
+
+	/* write queue state */
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_0_ADDR, csr_qstate->w0);
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_1_ADDR, csr_qstate->w1);
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_2_ADDR, csr_qstate->w2);
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_3_ADDR, csr_qstate->w3);
+	xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_4_ADDR, csr_qstate->w4);
+}
+
+static void storm_qmtm_set_qstate(struct xgene_mbox *mbox)
+{
+	struct storm_qmtm_pq_fp_qstate *pq_fp =
+	    &((union storm_qmtm_qstate *)(mbox->qstate))->pq;
+
+	if (QMTM_QTYPE_VQ(mbox))
+		pq_fp->cfgqtype = QTYPE_VQ;
+	else if (QMTM_QTYPE_FP(mbox))
+		pq_fp->cfgqtype = QTYPE_FP;
+	else
+		pq_fp->cfgqtype = QTYPE_PQ;
+
+	/* if its a free queue, ask QMTM to set len to 0 when dealloc */
+	if (pq_fp->cfgqtype == QTYPE_FP)
+		pq_fp->fp_mode = CHANGE_LEN;
+
+	if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH0 ||
+			QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH1) {
+		pq_fp->cfgRecombBuf = 1;
+		pq_fp->cfgRecombBufTimeoutL = 0xf;
+		pq_fp->cfgRecombBufTimeoutH = 0x7;
+	}
+
+	pq_fp->cfgselthrsh = 1;
+	/*  Allow the queue to accept message with non-zero LErr */
+	pq_fp->cfgacceptlerr = 1;
+	pq_fp->qcoherent = 1;
+	pq_fp->cfgstartaddrL = (u32)((mbox->dma >> 8) & (u32)(BIT(27) - 1));
+	pq_fp->cfgstartaddrH = (u32)(mbox->dma >> 35);
+	pq_fp->cfgqsize = mbox->slots;
+	storm_qmtm_write_qstate(mbox);
+}
+
+static void storm_qmtm_clr_qstate(struct xgene_mbox *mbox)
+{
+	memset(mbox->qstate, 0, sizeof(union storm_qmtm_qstate));
+	storm_qmtm_write_qstate(mbox);
+}
+
+static u32 storm_qmtm_read_level(void *qfabric)
+{
+	return (readl(&(((u32 *)qfabric)[1])) & 0x1fffe) >> 1;
+}
+
+static int storm_qmtm_init(struct xgene_qmtm *qmtm)
+{
+	int ret = 0, val;
+	xgene_qmtm_rd32(qmtm, CSR_IPBRR_ADDR, &val);
+	switch (val) {
+	case CSR_IPBRR_QMTM0_DEFAULT:
+		qmtm->qmtm_ip = QMTM0;
+		qmtm->irq_start = 0;
+		qmtm->irq_count = 16;
+		break;
+	case CSR_IPBRR_QMTM1_DEFAULT:
+		qmtm->qmtm_ip = QMTM1;
+		qmtm->irq_start = 0;
+		qmtm->irq_count = 32;
+		break;
+	case CSR_IPBRR_QMTM2_DEFAULT:
+		qmtm->qmtm_ip = QMTM2;
+		qmtm->irq_start = 16;
+		qmtm->irq_count = 16;
+		break;
+	case CSR_IPBRR_QMTM3_DEFAULT:
+		qmtm->qmtm_ip = QMTM3;
+		qmtm->irq_start = 0;
+		qmtm->irq_count = 1;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+struct xgene_qmtm_ops storm_qmtm_ops = {
+	.init = storm_qmtm_init,
+	.set_qstate = storm_qmtm_set_qstate,
+	.clr_qstate = storm_qmtm_clr_qstate,
+	.read_level = storm_qmtm_read_level,
+};
diff --git a/include/linux/platform_data/xgene_qmtm.h b/include/linux/platform_data/xgene_qmtm.h
new file mode 100644
index 0000000..23e630c
--- /dev/null
+++ b/include/linux/platform_data/xgene_qmtm.h
@@ -0,0 +1,300 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ *         Keyur Chudgar <kchudgar@apm.com>
+ *         Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XGENE_QMTM_H__
+#define __XGENE_QMTM_H__
+
+/* QMTM Data Length encoded as per QM message format */
+enum xgene_mbox_data_len {
+	DATA_LEN_256B = 0x0100,
+	DATA_LEN_1K = 0x0400,
+	DATA_LEN_2K = 0x0800,
+	DATA_LEN_4K = 0x1000,
+	DATA_LEN_16K = 0x4000,
+};
+
+enum xgene_mbox_mask_len {
+	MASK_LEN_256B = (DATA_LEN_256B - 1),
+	MASK_LEN_1K = (DATA_LEN_1K - 1),
+	MASK_LEN_2K = (DATA_LEN_2K - 1),
+	MASK_LEN_4K = (DATA_LEN_4K - 1),
+	MASK_LEN_16K = (DATA_LEN_16K - 1),
+};
+
+/* QMTM Buffer Length encoded as per QM message format */
+enum xgene_mbox_buf_len {
+	BUF_LEN_256B = 0x7000,
+	BUF_LEN_1K = 0x6000,
+	BUF_LEN_2K = 0x5000,
+	BUF_LEN_4K = 0x4000,
+	BUF_LEN_16K = 0x0000,
+};
+
+/* QMTM messaging structures */
+/* 16 byte QMTM message format */
+struct xgene_mbox_msg16 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	/* memory word 0 (bit 31:0) */
+	u32 UserInfo;
+
+	/* memory word 1 (bit 63:32) */
+	u32 HL:1;
+	u32 LErr:3;
+	u32 RType:4;
+	u32 IN:1;
+	u32 Rv:1;
+	u32 HB:1;
+	u32 PB:1;
+	u32 LL:1;
+	u32 NV:1;
+	u32 LEI:2;
+	u32 ELErr:2;
+	u32 Rv2:2;
+	u32 FPQNum:12;
+
+	/* memory word 2 (bit 95:64) */
+	u32 DataAddrL;    /* split 10/32 */
+
+	/* memory word 3 (bit 127:96) */
+	u32 C:1;
+	u32 BufDataLen:15;
+	u32 Rv6:6;
+	u32 DataAddrH:10; /* split 10/32 */
+#else
+	/* memory word 0 (bit 31:0) */
+	u32 UserInfo;
+
+	/* memory word 1 (bit 63:32) */
+	u32 FPQNum:12;
+	u32 Rv2:2;
+	u32 ELErr:2;
+	u32 LEI:2;
+	u32 NV:1;
+	u32 LL:1;
+	u32 PB:1;
+	u32 HB:1;
+	u32 Rv:1;
+	u32 IN:1;
+	u32 RType:4;
+	u32 LErr:3;
+	u32 HL:1;
+
+	/* memory word 2 (bit 95:64) */
+	u32 DataAddrL;    /* split 10/32 */
+
+	/* memory word 3 (bit 127:96) */
+	u32 DataAddrH:10; /* split 10/32 */
+	u32 Rv6:6;
+	u32 BufDataLen:15;
+	u32 C:1;
+#endif
+} __packed;
+
+/* Higher 16 byte portion of 32 byte of QMTM message format */
+struct xgene_mbox_msg16H {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	/* memory word 4 (bit 159:128) */
+	u32 H0Info_msbL;    /* split 16/32 */
+
+	/* memory word 5 (bit 191:160) */
+	u32 HR:1;
+	u32 Rv0:1;
+	u32 DR:1;
+	u32 Rv1:1;
+	u32 TotDataLengthLinkListLSBs:12;
+	u16 H0Info_msbH; /* split 16/32 */
+
+	/* memory word 6 (bit 223:192) */
+	u32 H0Info_lsbL; /* split 16/32 */
+
+	/* memory word 7 (bit 255:224) */
+	u32 H0FPSel:4;
+	u32 H0Enq_Num:12;
+	u16 H0Info_lsbH; /* split 16/32 */
+#else
+	/* memory word 4 (bit 159:128) */
+	u32 H0Info_msbL; /* split 16/32 */
+
+	/* memory word 5 (bit 191:160) */
+	u16 H0Info_msbH; /* split 16/32 */
+	u32 TotDataLengthLinkListLSBs:12;
+	u32 Rv1:1;
+	u32 DR:1;
+	u32 Rv0:1;
+	u32 HR:1;
+
+	/* memory word 6 (bit 223:192) */
+	u32 H0Info_lsbL; /* split 16/32 */
+
+	/* memory word 7 (bit 255:224) */
+	u16 H0Info_lsbH; /* split 16/32 */
+	u32 H0Enq_Num:12;
+	u32 H0FPSel:4;
+#endif
+} __packed;
+
+/* 8 byte portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	u32 NxtDataAddrL;
+	u32 Rv1:1;
+	u32 NxtBufDataLength:15;
+	u32 NxtFPQNum:4;
+	u32 Rv2:2;
+	u32 NxtDataAddrH:10;
+#else
+	u32 NxtDataAddrL;
+	u32 NxtDataAddrH:10;
+	u32 Rv2:2;
+	u32 NxtFPQNum:4;
+	u32 NxtBufDataLength:15;
+	u32 Rv1:1;
+#endif
+} __packed;
+
+/* 8 byte Link list portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8_list {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	u32 NxtDataPtrL;
+	u8  TotDataLengthLinkListMSBs;
+	u8  NxtLinkListength;
+	u32 NxtFPQNum:4;
+	u32 Rv2:2;
+	u32 NxtDataPtrH:10;
+#else
+	u32 NxtDataPtrL;
+	u32 NxtDataPtrH:10;
+	u32 Rv2:2;
+	u32 NxtFPQNum:4;
+	u8  NxtLinkListength;
+	u8  TotDataLengthLinkListMSBs;
+#endif
+} __packed;
+
+/* This structure represents 32 byte QMTM message format */
+struct xgene_mbox_msg32 {
+	struct xgene_mbox_msg16 msg16;
+	struct xgene_mbox_msg16H msg16H;
+} __packed;
+
+ /* Higher 32 byte of QMTM extended (64B) message format */
+struct xgene_mbox_msg32H {
+	struct xgene_mbox_msg8 msg8_2;
+	struct xgene_mbox_msg8 msg8_1;
+	union {
+		struct xgene_mbox_msg8 msg8_4;
+		struct xgene_mbox_msg8_list msg8_list;
+	};
+	struct xgene_mbox_msg8 msg8_3;
+} __packed;
+
+/* 64 byte QMTM message format */
+struct xgene_mbox_msg64 {
+	struct xgene_mbox_msg32 msg32;
+	struct xgene_mbox_msg32H msg32H;
+} __packed;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define xgene_mbox_msg_le32(word, words) \
+	do { \
+		int w; \
+		for (w = 0; w < words; w++) \
+			*(word + w) = cpu_to_le32(*(word + w)); \
+	} while (0)
+#else
+#define xgene_mbox_msg_le32(word, words) \
+	do {} while (0)
+#endif
+
+/* Empty Slot Soft Signature */
+#define EMPTY_SLOT_INDEX	7
+#define EMPTY_SLOT		0x22222222
+
+/* Encoding Destination QMTM (2 MSB) and Queue ID */
+#define QMTM_QUEUE_ID(q)	(((u16)(q->qstate[6]) << 10) | q->qid)
+
+/* Decoding PBM signal */
+#define QMTM_PBN(q)		(q->pbm & 0x003F)
+#define QMTM_SLAVE_ID(q)	((q->pbm & 0x03C0) >> 6)
+#define QMTM_QTYPE_FP(q)	(q->pbm & 0x0020)
+#define QMTM_QTYPE_VQ(q)	(q->pbm & 0x0400)
+
+/* Per queue state database */
+struct xgene_mbox {
+	u16 pbm;
+	u16 qid;
+	u16 qhead;
+	u16 qtail;
+	u16 slots;
+	u16 irq;
+	u32 qsize;
+	u32 pbm_state;
+	u32 qstate[7];
+	void *qfabric;
+	void *level;
+	dma_addr_t dma;
+	union {
+		void *qaddr;
+		struct xgene_mbox_msg16 *msg16;
+		struct xgene_mbox_msg32 *msg32;
+	};
+	struct xgene_qmtm *qmtm;
+};
+
+static inline u16 xgene_mbox_encode_bufdatalen(u32 len)
+{
+	if (len <= DATA_LEN_256B)
+		return BUF_LEN_256B | (len & MASK_LEN_256B);
+	else if (len <= DATA_LEN_1K)
+		return BUF_LEN_1K | (len & MASK_LEN_1K);
+	else if (len <= DATA_LEN_2K)
+		return BUF_LEN_2K | (len & MASK_LEN_2K);
+	else if (len <= DATA_LEN_4K)
+		return BUF_LEN_4K | (len & MASK_LEN_4K);
+	else if (len < DATA_LEN_16K)
+		return BUF_LEN_16K | (len & MASK_LEN_16K);
+	else
+		return BUF_LEN_16K;
+}
+
+static inline u16 xgene_mbox_encode_datalen(u32 len)
+{
+	return len & MASK_LEN_16K;
+}
+
+static inline u32 xgene_mbox_decode_datalen(u16 bufdatalen)
+{
+	switch (bufdatalen & BUF_LEN_256B) {
+	case BUF_LEN_256B:
+		return bufdatalen & MASK_LEN_256B ? : DATA_LEN_256B;
+	case BUF_LEN_1K:
+		return bufdatalen & MASK_LEN_1K ? : DATA_LEN_1K;
+	case BUF_LEN_2K:
+		return bufdatalen & MASK_LEN_2K ? : DATA_LEN_2K;
+	case BUF_LEN_4K:
+		return bufdatalen & MASK_LEN_4K ? : DATA_LEN_4K;
+	default:
+		return bufdatalen & MASK_LEN_16K ? : DATA_LEN_16K;
+	};
+}
+
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s);
+void xgene_mbox_put(struct xgene_mbox *mbox);
+u32 xgene_mbox_level(struct xgene_mbox *mbox);
+
+#endif /* __XGENE_QMTM_H__ */
-- 
1.7.9.5

^ permalink raw reply related


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